Coasty sessions API
Stateful CUA sessions with persistent trajectory.
Stateful CUA sessions with persistent trajectory.
openapi: 3.1.0
info:
title: Coasty Public keys sessions API
version: 1.0.0
summary: Computer Use Agents, scheduled automation, and managed VMs.
description: "# Coasty Public API\n\nCoasty is a Computer Use Agent (CUA) platform: predict actions from screenshots,\nprovision managed VMs, and run scheduled automation against them.\n\n## Authentication\n\nAll endpoints (except `/v1/triggers/webhook/{webhook_id}` and health checks) require an API key.\nPass it as either:\n\n- `X-API-Key: sk-coasty-live-...` (or `sk-coasty-test-...` for sandbox)\n- `Authorization: Bearer sk-coasty-live-...`\n\nThe external webhook endpoint does not use an API key, but it is authenticated:\nsend the HMAC-SHA256 `Coasty-Signature` credential documented on that operation.\n\nTest-mode keys (`sk-coasty-test-*`) hit the same validation paths as live keys but\nreturn mock VMs / mock action results and never bill credits — ideal for CI.\n\n## Pricing & budgeting\n\nPer-call rates (subject to change — see `lib/pricing/tiers.ts METERED_RATES`):\n\n| Endpoint | Credits |\n|---|---|\n| `POST /v1/predict` | ~5 |\n| `POST /v1/sessions` | 10 |\n| `POST /v1/sessions/{id}/predict` | ~4 |\n| `POST /v1/ground` | ~3 |\n| `POST /v1/parse` | 0 (free) |\n\nLong-running CUA jobs orchestrated through the dashboard (not this API) bill at\n10 credits/minute with a 20-credit minimum. Subscription tiers (`free | starter |\nprofessional | enterprise`) gate feature availability (e.g. custom system prompts),\nschedule counts, and the maximum trajectory length.\n\n## Errors\n\nEvery error response uses the same envelope:\n\n```json\n{\n \"error\": {\n \"code\": \"INSUFFICIENT_CREDITS\",\n \"message\": \"Need 5, have 2.\",\n \"type\": \"billing_error\",\n \"request_id\": \"req_a1b2c3d4e5f6\",\n \"retryable\": false,\n \"retry_with_same_idempotency_key\": false\n }\n}\n```\n\nInclude the `request_id` in support requests.\n\n## Idempotency\n\nOperations marked `x-idempotency: reserve-and-replay` accept `Idempotency-Key:\n<≤128 chars of [A-Za-z0-9_-:]>`. Replays\nof the same key + identical body return the original response (with\n`X-Coasty-Idempotent-Replay: true`) for 24 h. Reusing the key with a different body\nis a 422 `IDEMPOTENCY_KEY_REUSED`.\nOperations marked `x-idempotency: webhook-payload-dedup` instead deduplicate the\nsame webhook id + identical raw body for 60 seconds; they do not accept an\nIdempotency-Key.\n\n## Clients & MCP\n\nUse the HTTP API directly from any language. Official TypeScript and Python SDKs\nare not currently published; generate a client from this OpenAPI document if needed.\n- MCP server: `npx -y @coasty/mcp` (see `x-mcp-server`)\n\n## Reference\n\nComplete (machine-readable) spec is hosted at `/.well-known/openapi.json` and\n`/openapi.json` (Stripe / Vercel conventions)."
contact:
name: Coasty Developer Support
url: https://coasty.ai/support
email: founders@coasty.ai
license:
name: MIT
identifier: MIT
termsOfService: https://coasty.ai/terms
servers:
- url: https://coasty.ai
description: Production
- url: https://coasty.ai
description: Sandbox — use sk-coasty-test-* keys against the same host. No billing, mock VMs.
security:
- apiKey: []
- bearerAuth: []
tags:
- name: sessions
description: Stateful CUA sessions with persistent trajectory.
paths:
/v1/sessions:
post:
tags:
- sessions
operationId: createSession
summary: Create a stateful CUA session
description: Persistent session with a 2-hour (7200s) idle TTL, reset on each predict/reset; expires_at is returned. A predict/reset against an expired or unknown session is a 404 SESSION_NOT_FOUND. Maintains trajectory across predictions. Concurrent-session limits are tier- and deployment-configured; clients must handle 429 responses instead of hardcoding a tier limit.
security:
- apiKey: []
- bearerAuth: []
parameters:
- $ref: '#/components/parameters/IdempotencyKey'
- $ref: '#/components/parameters/XLLMProvider'
- $ref: '#/components/parameters/XLLMApiKey'
- $ref: '#/components/parameters/XLLMModel'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateSessionRequest'
responses:
'200':
description: Session created.
content:
application/json:
schema:
$ref: '#/components/schemas/CreateSessionResponse'
headers:
X-Coasty-Request-Id:
$ref: '#/components/headers/CoastyRequestId'
X-Coasty-Key-Kind:
$ref: '#/components/headers/KeyKind'
X-Coasty-Test-Mode:
$ref: '#/components/headers/TestMode'
X-Credits-Charged:
$ref: '#/components/headers/CreditsCharged'
X-Credits-Remaining:
$ref: '#/components/headers/CreditsRemaining'
X-RateLimit-Limit:
$ref: '#/components/headers/RateLimit'
X-RateLimit-Remaining:
$ref: '#/components/headers/RateRemaining'
X-RateLimit-Reset:
$ref: '#/components/headers/RateReset'
RateLimit-Limit:
$ref: '#/components/headers/RateLimit'
RateLimit-Remaining:
$ref: '#/components/headers/RateRemaining'
RateLimit-Reset:
$ref: '#/components/headers/RateReset'
Idempotency-Replayed:
$ref: '#/components/headers/IdempotencyReplayed'
X-Coasty-Idempotent-Replay:
$ref: '#/components/headers/IdempotentReplay'
Idempotency-Status:
$ref: '#/components/headers/IdempotencyStatus'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'402':
$ref: '#/components/responses/PaymentRequired'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'409':
$ref: '#/components/responses/Conflict'
'413':
$ref: '#/components/responses/PayloadTooLarge'
'422':
$ref: '#/components/responses/UnprocessableEntity'
'429':
$ref: '#/components/responses/RateLimited'
'500':
$ref: '#/components/responses/ServerError'
'502':
$ref: '#/components/responses/BadGateway'
'503':
$ref: '#/components/responses/ServiceUnavailable'
'504':
$ref: '#/components/responses/GatewayTimeout'
x-auth-mode: api_key
x-required-scope: session
x-required-scopes:
- session
x-scope-policy: required
x-billing-code: session_create
x-offering: cua
x-feature-flag: PUBLIC_CUA_API_ENABLED
x-idempotency: reserve-and-replay
get:
tags:
- sessions
operationId: listSessions
summary: List active sessions
security:
- apiKey: []
- bearerAuth: []
responses:
'200':
description: Active sessions for this key.
content:
application/json:
schema:
type: object
properties:
sessions:
type: array
items:
$ref: '#/components/schemas/SessionInfoResponse'
headers:
X-Coasty-Request-Id:
$ref: '#/components/headers/CoastyRequestId'
X-Coasty-Key-Kind:
$ref: '#/components/headers/KeyKind'
X-Coasty-Test-Mode:
$ref: '#/components/headers/TestMode'
X-Credits-Charged:
$ref: '#/components/headers/CreditsCharged'
X-Credits-Remaining:
$ref: '#/components/headers/CreditsRemaining'
X-RateLimit-Limit:
$ref: '#/components/headers/RateLimit'
X-RateLimit-Remaining:
$ref: '#/components/headers/RateRemaining'
X-RateLimit-Reset:
$ref: '#/components/headers/RateReset'
RateLimit-Limit:
$ref: '#/components/headers/RateLimit'
RateLimit-Remaining:
$ref: '#/components/headers/RateRemaining'
RateLimit-Reset:
$ref: '#/components/headers/RateReset'
Idempotency-Replayed:
$ref: '#/components/headers/IdempotencyReplayed'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'409':
$ref: '#/components/responses/Conflict'
'413':
$ref: '#/components/responses/PayloadTooLarge'
'422':
$ref: '#/components/responses/UnprocessableEntity'
'429':
$ref: '#/components/responses/RateLimited'
'500':
$ref: '#/components/responses/ServerError'
'502':
$ref: '#/components/responses/BadGateway'
'503':
$ref: '#/components/responses/ServiceUnavailable'
'504':
$ref: '#/components/responses/GatewayTimeout'
x-auth-mode: api_key
x-required-scope: session
x-required-scopes:
- session
x-scope-policy: required
x-billing-code: null
x-offering: cua
x-feature-flag: PUBLIC_CUA_API_ENABLED
x-idempotency: none
/v1/sessions/{session_id}:
parameters:
- $ref: '#/components/parameters/SessionId'
get:
tags:
- sessions
operationId: getSession
summary: Get session info
security:
- apiKey: []
- bearerAuth: []
responses:
'200':
description: Session info.
content:
application/json:
schema:
$ref: '#/components/schemas/SessionInfoResponse'
headers:
X-Coasty-Request-Id:
$ref: '#/components/headers/CoastyRequestId'
X-Coasty-Key-Kind:
$ref: '#/components/headers/KeyKind'
X-Coasty-Test-Mode:
$ref: '#/components/headers/TestMode'
X-Credits-Charged:
$ref: '#/components/headers/CreditsCharged'
X-Credits-Remaining:
$ref: '#/components/headers/CreditsRemaining'
X-RateLimit-Limit:
$ref: '#/components/headers/RateLimit'
X-RateLimit-Remaining:
$ref: '#/components/headers/RateRemaining'
X-RateLimit-Reset:
$ref: '#/components/headers/RateReset'
RateLimit-Limit:
$ref: '#/components/headers/RateLimit'
RateLimit-Remaining:
$ref: '#/components/headers/RateRemaining'
RateLimit-Reset:
$ref: '#/components/headers/RateReset'
Idempotency-Replayed:
$ref: '#/components/headers/IdempotencyReplayed'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'409':
$ref: '#/components/responses/Conflict'
'413':
$ref: '#/components/responses/PayloadTooLarge'
'422':
$ref: '#/components/responses/UnprocessableEntity'
'429':
$ref: '#/components/responses/RateLimited'
'500':
$ref: '#/components/responses/ServerError'
'502':
$ref: '#/components/responses/BadGateway'
'503':
$ref: '#/components/responses/ServiceUnavailable'
'504':
$ref: '#/components/responses/GatewayTimeout'
x-auth-mode: api_key
x-required-scope: session
x-required-scopes:
- session
x-scope-policy: required
x-billing-code: null
x-offering: cua
x-feature-flag: PUBLIC_CUA_API_ENABLED
x-idempotency: none
delete:
tags:
- sessions
operationId: deleteSession
summary: Delete a session
security:
- apiKey: []
- bearerAuth: []
responses:
'200':
description: Deleted.
content:
application/json:
schema:
$ref: '#/components/schemas/SessionMutationResponse'
headers:
X-Coasty-Request-Id:
$ref: '#/components/headers/CoastyRequestId'
X-Coasty-Key-Kind:
$ref: '#/components/headers/KeyKind'
X-Coasty-Test-Mode:
$ref: '#/components/headers/TestMode'
X-Credits-Charged:
$ref: '#/components/headers/CreditsCharged'
X-Credits-Remaining:
$ref: '#/components/headers/CreditsRemaining'
X-RateLimit-Limit:
$ref: '#/components/headers/RateLimit'
X-RateLimit-Remaining:
$ref: '#/components/headers/RateRemaining'
X-RateLimit-Reset:
$ref: '#/components/headers/RateReset'
RateLimit-Limit:
$ref: '#/components/headers/RateLimit'
RateLimit-Remaining:
$ref: '#/components/headers/RateRemaining'
RateLimit-Reset:
$ref: '#/components/headers/RateReset'
Idempotency-Replayed:
$ref: '#/components/headers/IdempotencyReplayed'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'409':
$ref: '#/components/responses/Conflict'
'413':
$ref: '#/components/responses/PayloadTooLarge'
'422':
$ref: '#/components/responses/UnprocessableEntity'
'429':
$ref: '#/components/responses/RateLimited'
'500':
$ref: '#/components/responses/ServerError'
'502':
$ref: '#/components/responses/BadGateway'
'503':
$ref: '#/components/responses/ServiceUnavailable'
'504':
$ref: '#/components/responses/GatewayTimeout'
x-auth-mode: api_key
x-required-scope: session
x-required-scopes:
- session
x-scope-policy: required
x-billing-code: null
x-offering: cua
x-feature-flag: PUBLIC_CUA_API_ENABLED
x-idempotency: none
/v1/sessions/{session_id}/predict:
parameters:
- $ref: '#/components/parameters/SessionId'
post:
tags:
- sessions
operationId: sessionPredict
summary: Predict within an existing session
security:
- apiKey: []
- bearerAuth: []
parameters:
- $ref: '#/components/parameters/IdempotencyKey'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/SessionPredictRequest'
responses:
'200':
description: Predicted actions for the next step.
content:
application/json:
schema:
$ref: '#/components/schemas/SessionPredictResponse'
text/event-stream:
schema:
type: string
description: 'SSE keepalive stream ending with a JSON result event. Request with Accept: text/event-stream.'
headers:
X-Coasty-Request-Id:
$ref: '#/components/headers/CoastyRequestId'
X-Coasty-Key-Kind:
$ref: '#/components/headers/KeyKind'
X-Coasty-Test-Mode:
$ref: '#/components/headers/TestMode'
X-Credits-Charged:
$ref: '#/components/headers/CreditsCharged'
X-Credits-Remaining:
$ref: '#/components/headers/CreditsRemaining'
X-RateLimit-Limit:
$ref: '#/components/headers/RateLimit'
X-RateLimit-Remaining:
$ref: '#/components/headers/RateRemaining'
X-RateLimit-Reset:
$ref: '#/components/headers/RateReset'
RateLimit-Limit:
$ref: '#/components/headers/RateLimit'
RateLimit-Remaining:
$ref: '#/components/headers/RateRemaining'
RateLimit-Reset:
$ref: '#/components/headers/RateReset'
Idempotency-Replayed:
$ref: '#/components/headers/IdempotencyReplayed'
X-Coasty-Idempotent-Replay:
$ref: '#/components/headers/IdempotentReplay'
Idempotency-Status:
$ref: '#/components/headers/IdempotencyStatus'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'402':
$ref: '#/components/responses/PaymentRequired'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'409':
$ref: '#/components/responses/Conflict'
'413':
$ref: '#/components/responses/PayloadTooLarge'
'422':
$ref: '#/components/responses/UnprocessableEntity'
'429':
$ref: '#/components/responses/RateLimited'
'500':
$ref: '#/components/responses/ServerError'
'502':
$ref: '#/components/responses/BadGateway'
'503':
$ref: '#/components/responses/ServiceUnavailable'
'504':
$ref: '#/components/responses/GatewayTimeout'
x-auth-mode: api_key
x-required-scope: session
x-required-scopes:
- session
x-scope-policy: required
x-billing-code: session_predict
x-offering: cua
x-feature-flag: PUBLIC_CUA_API_ENABLED
x-idempotency: reserve-and-replay
/v1/sessions/{session_id}/reset:
parameters:
- $ref: '#/components/parameters/SessionId'
post:
tags:
- sessions
operationId: resetSession
summary: Reset session state
security:
- apiKey: []
- bearerAuth: []
responses:
'200':
description: Reset.
content:
application/json:
schema:
$ref: '#/components/schemas/SessionMutationResponse'
headers:
X-Coasty-Request-Id:
$ref: '#/components/headers/CoastyRequestId'
X-Coasty-Key-Kind:
$ref: '#/components/headers/KeyKind'
X-Coasty-Test-Mode:
$ref: '#/components/headers/TestMode'
X-Credits-Charged:
$ref: '#/components/headers/CreditsCharged'
X-Credits-Remaining:
$ref: '#/components/headers/CreditsRemaining'
X-RateLimit-Limit:
$ref: '#/components/headers/RateLimit'
X-RateLimit-Remaining:
$ref: '#/components/headers/RateRemaining'
X-RateLimit-Reset:
$ref: '#/components/headers/RateReset'
RateLimit-Limit:
$ref: '#/components/headers/RateLimit'
RateLimit-Remaining:
$ref: '#/components/headers/RateRemaining'
RateLimit-Reset:
$ref: '#/components/headers/RateReset'
Idempotency-Replayed:
$ref: '#/components/headers/IdempotencyReplayed'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'409':
$ref: '#/components/responses/Conflict'
'413':
$ref: '#/components/responses/PayloadTooLarge'
'422':
$ref: '#/components/responses/UnprocessableEntity'
'429':
$ref: '#/components/responses/RateLimited'
'500':
$ref: '#/components/responses/ServerError'
'502':
$ref: '#/components/responses/BadGateway'
'503':
$ref: '#/components/responses/ServiceUnavailable'
'504':
$ref: '#/components/responses/GatewayTimeout'
x-auth-mode: api_key
x-required-scope: session
x-required-scopes:
- session
x-scope-policy: required
x-billing-code: null
x-offering: cua
x-feature-flag: PUBLIC_CUA_API_ENABLED
x-idempotency: none
components:
schemas:
ActionResponse:
type: object
required:
- action_type
additionalProperties: false
properties:
action_type:
type: string
enum:
- click
- type_text
- key_press
- key_combo
- scroll
- drag
- move
- wait
- done
- fail
params:
type: object
additionalProperties: true
description:
type: string
raw_code:
type: string
SessionMutationResponse:
type: object
required:
- status
- session_id
properties:
status:
type: string
enum:
- ok
session_id:
type: string
ApiError:
type: object
required:
- error
properties:
error:
type: object
required:
- code
- message
- type
- retryable
- retry_with_same_idempotency_key
- request_id
properties:
code:
type: string
description: Stable machine-readable error code (e.g. INVALID_API_KEY, INSUFFICIENT_CREDITS).
examples:
- INVALID_API_KEY
message:
type: string
description: Human-readable explanation. May include suggestions or examples.
type:
type: string
enum:
- auth_error
- validation_error
- rate_limit_error
- billing_error
- not_found_error
- state_error
- server_error
- client_error
request_id:
type: string
description: Server-assigned correlation ID. Include in support requests.
examples:
- req_a1b2c3d4e5f6
suggestion:
type: string
description: A concrete next step, auto-filled per code. LLM agents can act on it to self-recover.
retryable:
type: boolean
description: 'true when retrying the same call may succeed (transient server failures + back-pressure: INTERNAL_ERROR, DB_UNAVAILABLE, SERVICE_UNAVAILABLE, UPSTREAM_*, PREDICTION_FAILED, *_FAILED, RATE_LIMITED, TOO_MANY_RUNS, IDEMPOTENCY_IN_FLIGHT, ...). false for deterministic client errors. A CUA BILLING_UNAVAILABLE caused by refund uncertainty is false unless the server confirmed a shared recovery checkpoint. Present on EVERY error envelope, including gateway/5xx/timeout paths.'
retry_with_same_idempotency_key:
type: boolean
description: 'true only when the concrete response permits replay, the original operation is one of the exact 18 reserve-and-replay operations, and that original request already carried the key. Reuse that SAME key and identical body. A retryable error alone does not make an operation idempotent, and a key cannot be added retroactively. For CUA refund uncertainty this is true only after an exact shared checkpoint was confirmed; unkeyed or uncheckpointed responses are false and must not be retried automatically. A confirmed refunded failure sets this false even when retryable remains true: use a new key, because the old debit is compensated and wallet-guarded by IDEMPOTENCY_ALREADY_REFUNDED. false for deterministic errors.'
retry_after:
type:
- integer
- 'null'
description: Seconds to wait before retrying (accompanies retryable:true back-pressure codes; mirrors the Retry-After header).
examples:
type: object
additionalProperties: true
description: 'Machine-readable limits for self-correction. On PAYLOAD_TOO_LARGE / INVALID_SCREENSHOT: { max_base64_bytes: 10485760, max_mb: 10, min_base64_chars: 100, formats: ["png","jpeg"] }.'
CreateSessionRequest:
type: object
additionalProperties: false
properties:
cua_version:
type: string
enum:
- v1
- v3
- v4
- v5
default: v5
model:
type:
- string
- 'null'
minLength: 1
maxLength: 512
screen_width:
type: integer
minimum: 320
maximum: 3840
default: 1920
screen_height:
type: integer
minimum: 240
maximum: 2160
default: 1080
max_trajectory_length:
type: integer
minimum: 1
maximum: 20
default: 3
system_prompt:
type:
- string
- 'null'
maxLength: 16000
instructions:
type:
- string
- 'null'
maxLength: 16000
tools:
type:
- array
- 'null'
minItems: 1
maxItems: 8
uniqueItems: true
items:
type: string
enum:
- click
- type_text
- key_press
- key_combo
- scroll
- drag
- move
- wait
metadata:
type:
- object
- 'null'
maxProperties: 32
additionalProperties: true
description: JSON object capped at 16,384 UTF-8 bytes by the server.
llm:
$ref: '#/components/schemas/LlmConfig'
SessionPredictResponse:
type: object
required:
- request_id
- session_id
- step
- actions
- status
- usage
properties:
request_id:
type: string
session_id:
type: string
step:
type: integer
actions:
type: array
items:
$ref: '#/components/schemas/ActionResponse'
raw_code:
type: array
items:
type: string
reasoning:
type: string
status:
type: string
enum:
- continue
- done
- fail
cua_version:
type:
- string
- 'null'
description: 'Echo: the CUA engine version that actually served this step (e.g. "v5").'
usage:
$ref: '#/components/schemas/UsageInfo'
SessionPredictRequest:
type: object
required:
- screenshot
- instruction
additionalProperties: false
properties:
screenshot:
type: string
minLength: 100
maxLength: 10485760
pattern: ^[A-Za-z0-9+/=]+$
instruction:
type: string
minLength: 1
maxLength: 32000
include_reasoning:
type: boolean
default: true
include_raw_code:
type: boolean
default: true
UsageInfo:
type: object
properties:
input_tokens:
type: integer
default: 0
output_tokens:
type: integer
default: 0
credits_charged:
type: integer
default: 0
cost_cents:
type: integer
default: 0
description: USD cost in cents (credits_charged * $0.01).
breakdown:
type:
- array
- 'null'
description: Self-auditable per-call cost breakdown; line credits sum to credits_charged. null on free/test/no-charge calls and /v1/parse.
items:
type: object
required:
- item
- credits
properties:
item:
type: string
enum:
- base
- trajectory
- hd_images
- engine
- custom_prompt
credits:
type: integer
count:
type:
- integer
- 'null'
description: Optional multiplier (e.g. number of HD screenshots billed); omitted where it adds nothing.
billed:
type: boolean
description: 'true on a real billed call; false on test keys (sk-coasty-test-*) and on idempotent replays (which return credits_charged: 0).'
LlmConfig:
type: object
additionalProperties: false
description: 'Opt-in BYOK model selection. provider ''managed'' (or omitting llm) keeps the platform default. There is deliberately no api_key field (422 if attempted): keys ride the X-LLM-Api-Key header or the encrypted /v1/llm/keys store only. Once BYOK is requested there is NO silent fallback to Coasty''s platform LLM keys.'
properties:
provider:
type: string
enum:
- managed
- anthropic
- openai
default: managed
description: Whose LLM account runs the harness. Anything else is 422 LLM_PROVIDER_UNSUPPORTED.
model:
type:
- string
- 'null'
minLength: 1
maxLength: 512
description: 'Main worker model. Defaults: claude-sonnet-4-6 (anthropic), gpt-4o (openai). Any model string your account can access; must be vision-capable.'
grounding_model:
type:
- string
- 'null'
minLength: 1
maxLength: 512
description: Override for pixel-coordinate grounding. Defaults to model. Grounding quality is tuned on the platform model; expect best results with the defaults.
compaction_model:
type:
- string
- 'null'
minLength: 1
maxLength: 512
description: Override for trajectory compaction. Defaults to model. A cheaper model here is the classic cost tune.
code_agent_model:
type:
- string
- 'null'
minLength: 1
maxLength: 512
description: Override for the code agent. Defaults to model.
SessionInfoResponse:
type: object
required:
- session_id
- cua_version
- screen_size
- created_at
- expires_at
properties:
session_id:
type: string
cua_version:
type: string
screen_size:
type: string
step_count:
type: integer
default: 0
created_at:
type: string
format: date-time
expires_at:
type: string
format: date-time
total_credits_used:
type: integer
default: 0
CreateSessionResponse:
type: object
required:
- request_id
- session_id
- cua_version
- screen_size
- created_at
- expires_at
- usage
properties:
request_id:
type: string
session_id:
type: string
cua_version:
type: string
screen_size:
type: string
examples:
- 1920x1080
created_at:
type: string
format: date-time
expires_at:
type: string
format: date-time
usage:
$ref: '#/components/schemas/UsageInfo'
headers:
CreditsCharged:
description: Credits charged by this response (zero for sandbox keys and stored replays).
schema:
type: integer
minimum: 0
RateReset:
description: Unix timestamp when the current rate window resets.
schema:
type: integer
minimum: 0
RetryAfter:
description: Seconds to wait before retrying. Present on retryable back-pressure and transient failures.
schema:
type: integer
minimum: 0
IdempotencyStatus:
description: Lifecycle status of the canonical idempotent attempt when applicable.
schema:
type: string
# --- truncated at 32 KB (47 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/coasty/refs/heads/main/openapi/coasty-sessions-api-openapi.yml