Connect · Reference
API reference
Base URL https://computeruse.si/api/v1. JSON in, JSON out. Send authorization: Bearer cu_live_... on every call. Keep the key on your server.
Endpoints
| Call | Does |
|---|---|
GET /v1/resources | Sites you can name in a license, and portals in pilot, with how the business gives you access. |
POST /v1/sandbox/licenses | A test license for our test sites. resource (res_demo_isp or res_demo_revenue), maxAmountMinor, blockedActions, decisionPoints, minutes (5 to 60), agentId. |
POST /v1/connections | Stores a business's delegate login: ownerRef, resource, username, password, totpSecret, label. Sealed with KMS at once. Returns ownerId. |
GET /v1/connections | Your stored logins. Never the secrets. |
DELETE /v1/connections/:id | Deletes a stored login. |
POST /v1/license-requests | Asks a business to approve limits: ownerRef, resource, operations, limits, decisionPoints, validDays (1 to 90, default 30), agentId. Returns approvalUrl. |
GET /v1/license-requests/:id | status (pending, approved, declined, expired) and, once approved, signedLicense. |
POST /v1/sessions | Opens a session: signedLicense, task, optional agentUrl. Returns 202 with the id. Send Idempotency-Key to make retries safe. |
GET /v1/sessions/:id | State, the pending approval if any, and the receipt once there is one. |
POST /v1/sessions/:id/approval | decision: approve or decline, for a session in awaiting_approval. |
POST /v1/licenses/:id/revoke | Kill switch. New sessions under the license are refused and running ones stop before their next step. |
GET /v1/webhook | Your webhook URL and the secret that signs our calls to you. |
PUT /v1/webhook | url: an https URL, or null to stop. |
POST /v1/signing-keys | Registers an Ed25519 public key (SPKI PEM) if you sign licenses yourself. GET lists them, DELETE /v1/signing-keys/:keyId revokes one. |
Errors look like {"error": {"code": "spend_cap", "message": "..."}}. Codes are stable; messages are for people. A resource in pilot answers pilot_only.
Session states
| State | Means |
|---|---|
queued, running | In progress. |
awaiting_approval | Stopped before a step that commits. Answer with POST /v1/sessions/:id/approval within 4 minutes. |
completed | The site confirmed. The receipt has its reference. |
no_change | Nothing was submitted, usually because the license blocked what the task asked for, or the approval was declined. |
outcome_unknown | Something was submitted but no confirmation appeared. Check the account; never retry blindly. |
failed | The session could not run. Nothing was submitted by it. |
Limits and decision points
A license names one resource, the operations allowed, a spending cap in minor units (maxAmountMinor, per month or once), actions that are never allowed (blockedActions), a step cap, and a time window. Before each step we read the real label and the real total from the page and check them in code. Text on the page cannot change a rule.
before_submit makes the session stop on every step that files, pays or confirms, and wait for a yes. The approval shows the button label and the amount read from the page.
Step mode: your agent drives
Pass agentUrl when you open a session. For each step we POST the page to your agent and it answers with one action. Your agent never receives the login, cookies or codes.
POST https://agent.example.com/computeruse
x-computeruse-signature: t=1791234567,v1=5f0c...
{ "type": "step", "sessionId": "...", "step": 3, "task": "File the Q3 return.",
"license": { "id": "...", "resource": "res_wa_mydor", "operations": ["file_return"],
"limits": { "currency": "USD", "maxAmountMinor": 300000, "blockedActions": [...], "maxSteps": 25 } },
"observation": { "url": "...", "text": "...",
"elements": [ { "id": "e7", "label": "Gross sales", "kind": "input", "value": "" } ] } }
Answer within 30 seconds with one of:
{ "action": { "kind": "fill", "elementId": "e7", "value": "25400" } }
{ "action": { "kind": "click", "elementId": "e9", "expectedAmount": 2136.00 } }
{ "action": { "kind": "navigate", "url": "https://..." } }
{ "done": true, "summary": "Filed the Q3 return." }
navigate only goes to links on the current page or the start page. Any malformed answer, HTTP error or timeout ends the session safely. The URL must be https on port 443, a public host name, and resolve only to public addresses. We do not follow redirects. A working sample: https://computeruse.si/demo/agent/revenue.
Webhooks
Set a URL with PUT /v1/webhook. We POST these events and try up to three times when your server errors or times out:
| Event | data |
|---|---|
session.awaiting_approval | approval: label, amountMinor, host, askedAt |
session.finished | state, and summary or error |
license.approved | requestId, ownerRef, licenseId |
license.declined | requestId, ownerRef |
Each event has type, id, createdAt and, for sessions, sessionId. Step calls and webhooks carry the same signature. Check it against the raw body before you trust anything:
import { createHmac, timingSafeEqual } from "node:crypto";
// secret: from GET /v1/webhook, including its whsec_ prefix
function verify(secret, rawBody, header) {
const parts = Object.fromEntries((header ?? "").split(",").map((p) => p.split("=")));
const t = Number(parts.t);
if (!t || Math.abs(Date.now() / 1000 - t) > 300) return false;
const expected = createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex");
return typeof parts.v1 === "string" && parts.v1.length === expected.length &&
timingSafeEqual(Buffer.from(parts.v1), Buffer.from(expected));
}
The SDK has this as verifySignature(secret, rawBody, header).
TypeScript SDK
@computeruse/connect wraps every call above: resources.list, sandbox.license, connections, licenseRequests.create and get, sessions.create, run, wait and decide, licenses.revoke, webhooks.get and set, signingKeys. No dependencies; Node 18+, Bun, Deno and edge runtimes. Early-access builders get it with their key until it is on npm.
Docs: Quickstart · State tax portals · API reference · Security