Skip to main content
@opencomputer/sdk/agents is the TypeScript client for the management API: create sessions, send turns, read the event log, list and label sessions, and manage a project’s memory, webhooks, event subscriptions and GitHub repositories. Use it in your application’s server; use @opencomputer/react in the browser and @opencomputer/agent to define agent behavior. The client uses web-standard APIs and runs on Cloudflare Workers without Node compatibility, Vercel functions, Deno and Node. The package root, @opencomputer/sdk, provides the separate sandbox client.
Use it from trusted server code. The key belongs to an organization and reaches every project, agent and session in it; it must not reach a browser. Authenticate your users and check their access before forwarding requests.
This client requires SDK 2.0 or later. Version 2 removes the older session client and moves startSessionOnDocument, memory types and event-subscription types to @opencomputer/sdk/agents. See the migration notes for changed imports and errors. Applications using the older session API should remain on SDK 1.1.1 until migrated.

new OpenComputer(options)

Methods accept an AbortSignal in their options; startOnDocument takes signal in its params. Return shapes are listed below. Paged session lists return { sessions, nextCursor }; repository lists return { repositories, nextCursor }. Event reads return an array.

Errors

HTTP failures throw OpenComputerError with code, status and message. code is the API’s stable code when the body carried one (idempotency_conflict, session_ended, insufficient_credits, session_publication_unconfirmed); when the body had only text, it is derived from the status: unauthorized, forbidden, not_found, conflict, rate_limited, unavailable for 5xx, request_failed otherwise. A 429 also carries retryAfter in seconds, and an error the API tied to a session carries sessionId. Network failures, response-body read failures and cancellation propagate the underlying error, such as TypeError or AbortError. They do not prove that a write was rejected. A request can commit before its response is lost. The client does not retry automatically. Keep the same parameters and key for a submission’s retries; use a new key only for new work. Use bounded backoff and an AbortSignal, and retain the submission if the retry budget expires. Aborting the HTTP request does not cancel admitted work. A successful create or label update confirms publication to the list. See the Management API for each operation’s errors and guarantees. The client does not follow redirects. The API key is sent to baseUrl and to no other origin: a redirect answer fails the call with code redirected and the redirect’s status, and nothing is sent to the address it named. Check baseUrl when you see it. Two codes come from the client rather than the API:

Validation

The client checks response envelopes and selected fields before returning; unknown fields pass through. Application-owned values such as session.result.data and turn payloads still need your application schema. Event reads check seq, type and that data is an object. They do not validate each known event type’s payload; identity and timestamp fields are checked only when present. The exported event types describe the API contract, not complete runtime validation. Validate event data before using it where its contents affect application correctness or access.

Sessions

create takes agentId, deploymentId, environment, memory, source and labels as documented. turns.send takes input, idempotencyKey, mode and payload; both create and turns.send send the key as the Idempotency-Key header. The receipt carries the turn’s persisted status: queued or running for a new turn, and for a repeated key the existing turn’s status, completed, failed or cancelled once it has settled, with duplicate: true. The client maps nothing, so a retry after a lost reply learns what became of the turn. list takes project, environment, agent, status, labels (up to three, sent as label.<key>=<value>), cursor and limit.

Create and submit

Create the session, then send its first turn. Resolve the deployment once when composing the submission and retain its ID, both keys and the inputs. Retrying either call then returns the same session or turn, even if the agent is redeployed between attempts.
Send follow-ups to the same session with a fresh key per submission. To display work in a browser, attach the React hook through your authenticated application routes.

Read progress and results

Read events from sequence 0, then request only events after the last sequence processed:
Each read returns up to 500 events. Continue immediately while catching up; when a read is empty, wait before polling again. A cursor skips earlier events; it does not reconstruct state you have discarded. See Session events for payloads and replay. sessions.get(id) returns the latest typed result, if the agent has reported one. Results retain their turn provenance and can outlive later work; see Sessions before treating a result as ready for review.

Start a session on a memory document

sessions.startOnDocument creates a memory document if it does not exist, then a session bound to it, and reports both ids and whether each already existed. These are two requests, not an atomic operation: the document remains if session creation fails. Retries reuse the document and converge on the session while the agent’s deployment and bindings remain unchanged.
The steps, in order:
  1. PUT /projects/<projectId>/memory/<resource>/documents/<documentId> with If-None-Match: * and the document body. 201 means the document was created. 412 means it exists; the call reads it with GET and leaves its content as it is. A 404 on that read means the ID was deleted and is reserved, which fails with code memory_document_deleted, since a binding to it would fail admission.
  2. POST /sessions with agentId: "<agent>@<environment>", source, and memory set to your further bindings plus { [resource]: { scope: "document", id: documentId, access } }. The Idempotency-Key header is sessionIdempotencyKey(idempotencyKey), the SHA-256 hex digest of opencomputer.memory.session, a NUL byte and your key. 201 created the session; 200 means the key had already created it. Anything else under that key fails with code idempotency_key_reused; the document was left as it is.
The result: The helper resolves the environment’s agent alias on every call and cannot pin a deployment. If that alias changes between a successful create and its retry, the retry fails with idempotency_key_reused. A new key would create another session; it does not recover a lost response. When retries must survive redeploys, create/read the document separately and pass its binding to sessions.create with a retained deploymentId and key. startSessionOnDocument({ apiKey, baseUrl?, fetch?, ...params }), exported from the same subpath, is the standalone form of the call for code that holds a key and no client, and sessionIdempotencyKey(key) derives the session-create key.

Projects

Memory

Every call takes { environment } last; conditional writes also take the revision the write is conditional on, sent as If-Match. Bodies, the document object and the error codes are on Document memory.

Webhooks

create and rotateToken return the webhook with its token and full invocationUrl once; see Agent webhooks.

Event subscriptions

The shapes are on Event subscriptions.

GitHub repositories

projects.github.repositories(p, { environment, cursor?, limit? }) calls GET /projects/<p>/github/repositories and returns { repositories, nextCursor }, each repository { id, fullName, private, defaultBranch, archived } as the environment’s GitHub installation covers them.

Agents and deployments

Types

The subpath exports the types of every object above: Session, SessionSummary, SessionCreated, Turn, TurnReceipt, SessionEvent, Project, AgentSummary, Deployment, Webhook, Repository, the Create…Params and List…Query shapes, and DataValue for JSON payloads and results. The memory types (MemoryDocument, MemoryBindings, SessionMemoryBinding, MemoryResourceInventory, the document bodies, MemorySavedEvent, MemoryErrorCode) and the event subscription types (EventSubscription, CreateEventSubscriptionBody, OutcomeEvent, EventInput, TurnOutcomeDelivery, EventSubscriptionErrorCode) are exported from the same place.