API reference#

The full, machine-readable reference is the OpenAPI 3.1 spec:

  • Hosted: https://api.task.cloud/v1/openapi.yaml
  • On this site: openapi.yaml (a copy of api/openapi.yaml from the repository, published with every docs build)

Generate a client in any language from it (for example with openapi-generator), or import it into Postman or Insomnia. The official TypeScript and Python SDKs are hand-written from the same file and tested against it.

Basics#

Topic Rule
Base URL https://api.task.cloud/v1
Auth Authorization: Bearer taskcloud_sk_... (scheme name case-insensitive); each endpoint needs the scope listed below (Security)
Format JSON with snake_case fields; file content is raw bytes; streams are Server-Sent Events; PTY is a WebSocket
IDs sbx_ sandbox, cmd_ command, pty_ PTY, dsk_ desktop stream, snap_ snapshot, tpl_ template, whk_ webhook, evt_ event, key_ API key
Timestamps RFC 3339, UTC
Pagination ?limit= (1–100, default 20) and ?cursor=; responses {"data": [...], "has_more": true, "next_cursor": "..."}
Idempotency Idempotency-Key header on POST /sandboxes, /fork, /snapshots, /templates (kept 24 h)
Rate limits RateLimit-Policy and RateLimit headers on every response, including 401 and unknown routes; 429 with Retry-After (Limits)
Request ID X-Request-Id on every response
Wake on request Calls that need a running VM wake a paused sandbox; add ?auto_resume=false to get 409 sandbox_paused instead

Errors#

Every error has the same shape:

{
  "error": {
    "code": "concurrency_limit_reached",
    "message": "Your plan allows 10 concurrent sandboxes.",
    "retryable": false,
    "status": 409,
    "request_id": "req_01HF3X",
    "details": { "limit": 10, "used": 10 }
  }
}

Branch on code, never on message. Retry only when retryable is true, after Retry-After if present.

Status Codes
400 invalid_request, invalid_path, invalid_template, invalid_image
401 unauthorized
402 payment_required, spend_limit_reached, free_hours_exhausted
403 forbidden, insufficient_scope
404 not_found
408 exec_timeout
409 invalid_state, sandbox_paused, sandbox_busy (retryable, Retry-After), concurrency_limit_reached, idempotency_conflict, already_exists, desktop_not_available, snapshot_in_use
412 precondition_failed
413 payload_too_large
416 invalid_request: a Range on GET .../files/content starts past the end of the file (details.size)
429 rate_limited (retryable); details.reason = "too_many_operations": too many concurrent operations on one sandbox
500 internal_error (retryable)
502 sandbox_unreachable (see retryable)
503 capacity_unavailable (retryable; details.reason = "incompatible_host" when a paused sandbox's snapshot needs a compatible host, see pause_reason), service_unavailable (retryable)
507 insufficient_storage: the sandbox disk is full (not retryable)

Endpoints#

Sandboxes#

Method Path Summary Scope
GET /sandboxes List sandboxes sandboxes:read
POST /sandboxes Create a sandbox sandboxes:write
GET /sandboxes/{sandbox_id} Get a sandbox sandboxes:read
PATCH /sandboxes/{sandbox_id} Update a sandbox sandboxes:write
DELETE /sandboxes/{sandbox_id} Delete a sandbox sandboxes:write
POST /sandboxes/{sandbox_id}/pause Pause a sandbox sandboxes:write
POST /sandboxes/{sandbox_id}/resume Resume a sandbox sandboxes:write
POST /sandboxes/{sandbox_id}/fork Fork a sandbox sandboxes:write

Exec#

Method Path Summary Scope
POST /sandboxes/{sandbox_id}/exec Run a command exec
GET /sandboxes/{sandbox_id}/commands List commands exec
GET /sandboxes/{sandbox_id}/commands/{command_id} Get a command exec
GET /sandboxes/{sandbox_id}/commands/{command_id}/stream Attach to a command's output (SSE) exec
POST /sandboxes/{sandbox_id}/commands/{command_id}/stdin Write to a command's stdin exec
POST /sandboxes/{sandbox_id}/commands/{command_id}/kill Send a signal to a command exec
POST /sandboxes/{sandbox_id}/pty Create an interactive PTY session exec
GET /sandboxes/{sandbox_id}/pty/{pty_id} Get a PTY session (and a fresh connect URL) exec
DELETE /sandboxes/{sandbox_id}/pty/{pty_id} Close a PTY session exec
GET /sandboxes/{sandbox_id}/pty/{pty_id}/connect PTY WebSocket endpoint signed token

Files#

Method Path Summary Scope
GET /sandboxes/{sandbox_id}/files List a directory files:read
DELETE /sandboxes/{sandbox_id}/files Delete a file or directory files:write
GET /sandboxes/{sandbox_id}/files/content Read a file files:read
PUT /sandboxes/{sandbox_id}/files/content Write a file files:write
GET /sandboxes/{sandbox_id}/files/stat Get file metadata files:read
POST /sandboxes/{sandbox_id}/files/mkdir Create a directory files:write
POST /sandboxes/{sandbox_id}/files/move Move or rename a file or directory files:write
POST /sandboxes/{sandbox_id}/files/upload Upload files (multipart) files:write
GET /sandboxes/{sandbox_id}/files/download Download a directory as an archive files:read
POST /sandboxes/{sandbox_id}/files/upload-url Create a signed upload URL files:write
POST /sandboxes/{sandbox_id}/files/download-url Create a signed download URL files:read
GET /sandboxes/{sandbox_id}/files/watch Watch a path for changes (SSE) files:read

Networking#

Method Path Summary Scope
GET /sandboxes/{sandbox_id}/ports List exposed ports sandboxes:read
POST /sandboxes/{sandbox_id}/ports Expose a port on a public HTTPS URL sandboxes:write
DELETE /sandboxes/{sandbox_id}/ports/{port} Remove a public URL sandboxes:write
POST /sandboxes/{sandbox_id}/access-tokens Create an access token for private ports sandboxes:write
POST /sandboxes/{sandbox_id}/ssh Get SSH access ssh
GET /ssh-keys List account SSH keys ssh
POST /ssh-keys Add an account SSH key ssh
DELETE /ssh-keys/{ssh_key_id} Remove an account SSH key ssh

Desktop#

Method Path Summary Scope
POST /sandboxes/{sandbox_id}/desktop Create a desktop stream URL desktop
GET /sandboxes/{sandbox_id}/desktop List active desktop stream URLs desktop
DELETE /sandboxes/{sandbox_id}/desktop/{stream_id} Revoke a desktop stream URL desktop
GET /sandboxes/{sandbox_id}/screenshot Take a screenshot desktop
POST /sandboxes/{sandbox_id}/input Send mouse and keyboard input desktop
GET /sandboxes/{sandbox_id}/cursor Get the cursor position desktop

Snapshots#

Method Path Summary Scope
POST /sandboxes/{sandbox_id}/snapshots Create a named snapshot snapshots:write
GET /snapshots List snapshots snapshots:read
GET /snapshots/{snapshot_id} Get a snapshot snapshots:read
DELETE /snapshots/{snapshot_id} Delete a snapshot snapshots:write

Templates#

Method Path Summary Scope
GET /templates List templates templates:read
POST /templates Create a template templates:write
GET /templates/{template_id} Get a template templates:read
DELETE /templates/{template_id} Delete a template templates:write
GET /templates/{template_id}/logs Get template build logs templates:read

Webhooks#

Method Path Summary Scope
GET /webhooks List webhook endpoints webhooks:manage
POST /webhooks Create a webhook endpoint webhooks:manage
GET /webhooks/{webhook_id} Get a webhook endpoint webhooks:manage
PATCH /webhooks/{webhook_id} Update a webhook endpoint webhooks:manage
DELETE /webhooks/{webhook_id} Delete a webhook endpoint webhooks:manage
POST /webhooks/{webhook_id}/rotate-secret Rotate the signing secret webhooks:manage
POST /webhooks/{webhook_id}/test Send a test event webhooks:manage
GET /webhooks/{webhook_id}/deliveries List recent deliveries webhooks:manage

Usage#

Method Path Summary Scope
GET /usage Get usage and cost usage:read
GET /sandboxes/{sandbox_id}/usage Get usage for one sandbox usage:read
GET /limits Get account limits and current consumption usage:read

API keys#

Method Path Summary Scope
GET /api-keys List API keys api_keys:manage
POST /api-keys Create an API key api_keys:manage
GET /api-keys/{api_key_id} Get an API key api_keys:manage
DELETE /api-keys/{api_key_id} Revoke an API key api_keys:manage
POST /api-keys/{api_key_id}/rotate Rotate an API key api_keys:manage

Account#

Method Path Summary Scope
GET /account Get the account account:read
PUT /account/spend-limit Set the monthly spend limit account:manage

Members and billing#

Used by the web console with a session, or with an API key (Teams and roles).

Method Path Summary Scope
GET /members List organization members account:read
PATCH /members/{user_id} Change a member's role account:manage
DELETE /members/{user_id} Remove a member (or leave) account:manage
GET /invitations List invitations account:read
POST /invitations Invite someone to the organization account:manage
DELETE /invitations/{invitation_id} Revoke a pending invitation account:manage
GET /billing Get the billing overview account:read
POST /billing/checkout Upgrade to a paid plan account:manage
POST /billing/portal Open the billing portal account:manage

Console sign-in and sessions#

Cookie-based endpoints of the web console (app.task.cloud); API keys get 403 on the session-only ones.

Method Path Summary Auth
POST /auth/magic-link E-mail a sign-in link none
POST /auth/magic-link/verify Sign in with a magic-link token none
GET /auth/github/start Start GitHub sign-in none
GET /auth/github/callback GitHub sign-in callback none
POST /auth/logout Sign out session
GET /me Get the signed-in user session
PATCH /me Update the profile session
POST /me/switch-org Switch the session's organization session
GET /me/sessions List my active sessions session
DELETE /me/sessions/{session_id} Revoke one of my sessions session
POST /organizations Create a team organization session
POST /invitations/accept Accept an invitation session

Outgoing webhooks#

Events sandbox.ready, sandbox.paused, sandbox.resumed, sandbox.error, sandbox.deleted, usage.threshold (and webhook.test) are POSTed to your endpoints, signed with HMAC-SHA256 in Webhook-Signature. Defined under webhooks in the spec; see Webhooks.