{"openapi":"3.1.0","info":{"title":"Coasty Public 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-*`) preserve the same core schemas for documented\nsandbox-supported operations and never debit Coasty credits. With a test Coasty key,\nexplicit BYOK is provider-direct only for the direct CUA flow: `POST /v1/predict`,\n`POST /v1/ground`, `POST /v1/sessions`, and `POST /v1/sessions/{id}/predict`.\nPredict, ground, and session create require an explicit per-request X-LLM-Api-Key plus\nX-LLM-Provider under test auth. A body provider without that header returns 422\nLLM_KEY_NOT_CONFIGURED: Stored provider keys are unavailable for test API keys. Send\nX-LLM-Api-Key explicitly for direct BYOK. Test auth never reads or uses a stored live provider\nkey. Session create fixes that explicit key for\ninherited predicts but makes no inference call. Predict, ground, and session predict can bill\nthe supplied provider account. Managed-mode Task runs, Workflow runs, and schedules remain\ndeterministic sandbox. BYOK intent on those async endpoints returns 422\nLLM_PROVIDER_UNSUPPORTED before execution: BYOK is unavailable for synthetic test runs,\nworkflows, and schedules. Use managed mode or a live Coasty API key. They never decrypt or\nrequire a stored provider key and do not call or bill Anthropic/OpenAI.\nLive-only stored BYOK-key access or mutation is unavailable to test keys. Keep real provider\nsecrets out of sandbox and CI requests, and use a live Coasty key for real async execution.\n\n## Pricing & budgeting\n\nPublished base rates and defaults (read effective deployed CUA/task pricing at\n`GET /v1/models` → `pricing`, and machine runtime pricing at `GET /v1/machines/pricing`):\n\n| Endpoint | Credits |\n|---|---|\n| `POST /v1/predict` | Managed: 5 base; BYOK: 0 |\n| `POST /v1/sessions` | Managed: 10 fixed; BYOK: 0 |\n| `POST /v1/sessions/{id}/predict` | Managed: 4 base; BYOK: 0 |\n| `POST /v1/ground` | Managed: 3 base; BYOK: 0 |\n| `POST /v1/parse` | 0 (free) |\n\nPredict and session-predict can add provider-visible trajectory-image, HD current/trajectory\nimage, v1-engine, and combined system_prompt + trimmed-instructions (>500 chars) surcharges.\nGround can add only the current-image HD surcharge; session creation has no surcharge.\nManaged-model published defaults: scheduled CUA execution bills the consumer subscription-credit balance\nat 10 credits/minute with a 20-credit start minimum for non-Unlimited accounts. Unlimited\nbypasses that runtime credit meter/start gate but retains token and concurrency safeguards.\nManaged schedule create/run-now use a $0.20 API-wallet eligibility gate. BYOK schedules\nbypass that gate and the runtime credit meter and debit zero Coasty platform credits.\nLive-key schedule execution is provider-billed. Managed-mode test execution is deterministic sandbox; test-auth BYOK intent returns 422 LLM_PROVIDER_UNSUPPORTED.\nRead `GET /v1/models` →\n`pricing.schedules` for effective values, plan applicability, and webhook policy.\nYour subscription tier (`free | starter | professional | enterprise`) is\nreported on the key, but the developer API is PREPAID: what bounds you is your\ncredit balance, not your plan. Custom prompts in particular are NOT tier-gated.\n`system_prompt` and `instructions` are available on every tier including free,\nagainst a budget of 32,000 characters SHARED between the two fields (the sum is\nmeasured, and exceeding it returns 400 INPUT_TOO_LARGE).\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 operation and body return the original response (with\n`X-Coasty-Idempotent-Replay: true`) for 24 h. The key is scoped to one concrete\nAPI-key credential plus live/test mode; cross-endpoint reuse, or reuse with a\ndifferent body, is a 422 `IDEMPOTENCY_KEY_REUSED`. External-machine enrollment\nis the account-scoped key-rotation-safe exception.\nOperations marked `x-idempotency: webhook-payload-dedup` instead deduplicate the\nsame webhook id + identical raw body for a published default of 60 seconds; they do\nnot accept an Idempotency-Key. Read the effective window at `GET /v1/models` →\n`pricing.schedules.webhook_dedup_window_seconds`.\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 Coasty billing. Explicit-header BYOK can call the provider only for predict, ground, and inherited session predict; session create fixes the header key without inference, and test auth never reads a stored live key. Managed-mode Tasks, Workflows, and schedules remain deterministic sandbox. BYOK intent on those async endpoints returns 422 LLM_PROVIDER_UNSUPPORTED before execution and makes no provider call."}],"security":[{"apiKey":[]},{"bearerAuth":[]}],"tags":[{"name":"predict","description":"Stateless CUA action prediction and grounding."},{"name":"sessions","description":"Stateful CUA sessions with persistent trajectory."},{"name":"machines","description":"Provision managed VMs or enroll customer-operated external machines. Runs and Workflow task steps use the same machine_id contract for both kinds."},{"name":"schedules","description":"Cron and one-shot scheduled CUA jobs."},{"name":"triggers","description":"Webhook and chain triggers for schedules."},{"name":"keys","description":"API key management and usage reporting."},{"name":"runs","description":"Autonomous task runs — the agent drives a task to completion on a machine."},{"name":"workflows","description":"Versioned, branching multi-step automations (DSL) and their runs."}],"paths":{"/v1/predict":{"post":{"tags":["predict"],"operationId":"predict","x-max-request-body-bytes":15728640,"summary":"Stateless action prediction","description":"Send a screenshot + instruction; receive structured actions to execute on the target machine. Managed inference has a published 5-credit base plus the documented provider-visible trajectory-image, HD current/trajectory image, v1-engine, and combined system_prompt + trimmed instructions (>500 characters) surcharges. BYOK runs the complete harness on the selected Anthropic/OpenAI account, debits zero Coasty platform credits, and still returns real provider token usage and non-secret attribution. This is a direct CUA primitive: under a test Coasty key, provider-direct BYOK requires an explicit per-request X-LLM-Api-Key plus X-LLM-Provider and can bill that provider account. A body provider without the key header returns 422 LLM_KEY_NOT_CONFIGURED: Stored provider keys are unavailable for test API keys. Send X-LLM-Api-Key explicitly for direct BYOK. Test auth never resolves a stored live provider key. Task instruction is excluded from the managed prompt surcharge. Read effective deployed pricing from GET /v1/models under pricing.","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/PredictRequest"},"example":{"screenshot":"<base64-png>","instruction":"Click the Sign In button","cua_version":"v5"}}}},"responses":{"200":{"description":"Predicted actions.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PredictResponse"}},"text/event-stream":{"schema":{"type":"string"},"description":"SSE keepalive stream ending with a JSON result event. Request with Accept: text/event-stream."}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"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":"predict","x-required-scopes":["predict"],"x-scope-policy":"required","x-billing-code":"predict","x-offering":"cua","x-feature-flag":"PUBLIC_CUA_API_ENABLED","x-idempotency":"reserve-and-replay"}},"/v1/sessions":{"post":{"tags":["sessions"],"operationId":"createSession","summary":"Create a stateful CUA session","description":"Persistent session with a managed-inference 10-credit fixed creation price and a 2-hour (7200s) idle TTL, reset on each predict/reset; expires_at is returned. BYOK session creation and every inherited predict debit zero Coasty platform credits. Session create configures and holds the inherited provider key but does not make an inference call, reports zero provider tokens, and does not itself incur provider billing; billing begins when session predict calls Anthropic/OpenAI. Under a test Coasty key, BYOK session create requires an explicit per-request X-LLM-Api-Key plus X-LLM-Provider. A body provider without the key header returns 422 LLM_KEY_NOT_CONFIGURED: Stored provider keys are unavailable for test API keys. Send X-LLM-Api-Key explicitly for direct BYOK. Test auth never reads or uses a stored live provider key. The owning process keeps that fixed create-time BYOK configuration in memory and every later predict inherits it. Deleting or rotating a stored key does not update or revoke an active session; DELETE /v1/sessions/{session_id} (or let it expire), or revoke the key at the provider, to stop further calls. Session creation has no managed request surcharge. 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. Read effective deployed pricing from GET /v1/models under pricing.","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-Request-Id":{"$ref":"#/components/headers/RequestId"},"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-Request-Id":{"$ref":"#/components/headers/RequestId"},"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-Request-Id":{"$ref":"#/components/headers/RequestId"},"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-Request-Id":{"$ref":"#/components/headers/RequestId"},"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","description":"Managed-inference base: 4 credits per stateful prediction. The same trajectory-image, HD current/trajectory image, v1-engine, and combined system_prompt + trimmed instructions (>500 characters) surcharges as POST /v1/predict can apply; the stateful trajectory surcharge uses the provider-visible post-compaction image count. A session created with BYOK inherits that provider/key for every predict and debits zero Coasty platform credits while returning actual provider tokens. Session predict is a direct CUA primitive and remains provider-direct under a test Coasty key only when session create supplied the explicit per-request X-LLM-Api-Key; the provider account can then be billed. Test auth never resolves a stored live provider key for the session. Read effective deployed pricing from GET /v1/models under pricing.","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-Request-Id":{"$ref":"#/components/headers/RequestId"},"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-Request-Id":{"$ref":"#/components/headers/RequestId"},"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/ground":{"post":{"tags":["predict"],"operationId":"ground","summary":"Coordinate grounding","description":"Find (x, y) for a described UI element using the supplied screenshot. Managed inference has a published 3-credit base and can add only the current-image HD surcharge; trajectory, v1-engine, and prompt surcharges do not apply. BYOK is provider-direct, debits zero Coasty platform credits, and returns actual provider token usage plus non-secret attribution. Ground is a direct CUA primitive: under a test Coasty key, provider-direct BYOK requires an explicit per-request X-LLM-Api-Key plus X-LLM-Provider and can bill that provider account. A body provider without the key header returns 422 LLM_KEY_NOT_CONFIGURED: Stored provider keys are unavailable for test API keys. Send X-LLM-Api-Key explicitly for direct BYOK. Test auth never resolves a stored live provider key. Read effective deployed pricing from GET /v1/models under pricing.","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/GroundRequest"}}}},"responses":{"200":{"description":"Grounded coordinates.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GroundResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"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":"ground","x-required-scopes":["ground"],"x-scope-policy":"required","x-billing-code":"ground","x-offering":"cua","x-feature-flag":"PUBLIC_CUA_API_ENABLED","x-idempotency":"reserve-and-replay"}},"/v1/parse":{"post":{"tags":["predict"],"operationId":"parse","summary":"Parse pyautogui code into structured actions","description":"Free, no LLM call. Returns structured Action objects.","security":[{"apiKey":[]},{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ParseRequest"}}}},"responses":{"200":{"description":"Parsed actions.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ParseResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"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":"parse","x-required-scopes":["parse"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"cua","x-feature-flag":"PUBLIC_CUA_API_ENABLED","x-idempotency":"none"}},"/v1/models":{"get":{"tags":["predict"],"operationId":"listModels","summary":"List models, CUA versions, action types, and effective runtime pricing","security":[{"apiKey":[]},{"bearerAuth":[]}],"responses":{"200":{"description":"Model/capability catalog plus the billing engine's effective CUA and task-step prices.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModelsResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"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":null,"x-required-scopes":[],"x-scope-policy":"none","x-billing-code":null,"x-offering":"cua","x-feature-flag":"PUBLIC_CUA_API_ENABLED","x-idempotency":"none"}},"/v1/usage":{"get":{"tags":["keys"],"operationId":"getUsage","summary":"Usage summary for a billing period","security":[{"apiKey":[]},{"bearerAuth":[]}],"parameters":[{"name":"period","in":"query","required":false,"schema":{"type":"string","pattern":"^[0-9]{4}-(0[1-9]|1[0-2])$","description":"ISO YYYY-MM with a real month 01..12 (defaults to current month)."}}],"responses":{"200":{"description":"Usage summary.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageSummaryResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"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":"usage","x-required-scopes":["usage"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"cua","x-feature-flag":"PUBLIC_CUA_API_ENABLED","x-idempotency":"none"}},"/v1/idempotency/{key}":{"parameters":[{"$ref":"#/components/parameters/IdempotencyKeyPath"}],"get":{"tags":["keys"],"operationId":"getIdempotencyResult","summary":"Fetch a result by Idempotency-Key","description":"Collect a generic reserve-and-replay result by its Idempotency-Key alone, using the same concrete API-key credential and live/test mode that created it. 'completed' returns the original body + original_status; 'processing' means it is still running; unknown/expired is 404. External-machine enrollment is excluded from this cache: recover it only by repeating the exact POST /v1/machines/external key and body during its 24-hour account-scoped window.","security":[{"apiKey":[]},{"bearerAuth":[]}],"responses":{"200":{"description":"The cached result (completed) or its in-flight status (processing).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IdempotencyLookupResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"X-Coasty-Key-Kind":{"$ref":"#/components/headers/KeyKind"},"X-Coasty-Test-Mode":{"$ref":"#/components/headers/TestMode"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/ServerError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"x-auth-mode":"api_key","x-required-scope":null,"x-required-scopes":[],"x-scope-policy":"none","x-billing-code":null,"x-offering":"idempotency","x-feature-flag":"PUBLIC_IDEMPOTENCY_API_ENABLED","x-idempotency":"none"}},"/v1/keys":{"post":{"tags":["keys"],"operationId":"createApiKey","summary":"Create an API key","description":"Scope: `keys` (always opt-in; a default-minted key cannot mint further keys). Returns the raw key ONCE. Subsequent reads only return the prefix.\n\nAn account may hold up to 200 active keys by default; beyond that, creation fails with KEY_LIMIT_REACHED. Revoke unused keys rather than reusing one across services. A key-store outage returns 503 DB_UNAVAILABLE with Retry-After rather than a bare 500.","security":[{"apiKey":[]},{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}}},"responses":{"200":{"description":"Key created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"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":"keys","x-required-scopes":["keys"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"cua","x-feature-flag":"PUBLIC_CUA_API_ENABLED","x-idempotency":"none"},"get":{"tags":["keys"],"operationId":"listApiKeys","summary":"List API keys","description":"Scope: `keys` (always opt-in). Scoped to the CALLING key's mode: a sandbox (sk-coasty-test-*) key sees only sandbox keys, a live key sees live plus legacy. Each item carries `key_kind` so you can tell them apart. A key-store outage returns 503 DB_UNAVAILABLE with Retry-After rather than a bare 500.","security":[{"apiKey":[]},{"bearerAuth":[]}],"responses":{"200":{"description":"Keys.","content":{"application/json":{"schema":{"type":"object","properties":{"keys":{"type":"array","items":{"$ref":"#/components/schemas/APIKeyListItem"}}}}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"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":"keys","x-required-scopes":["keys"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"cua","x-feature-flag":"PUBLIC_CUA_API_ENABLED","x-idempotency":"none"}},"/v1/keys/{key_id}":{"parameters":[{"name":"key_id","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":128,"pattern":"^[A-Za-z0-9_-]+$"}}],"delete":{"tags":["keys"],"operationId":"revokeApiKey","summary":"Revoke an API key","description":"Scope: `keys` (always opt-in). Scoped to the CALLING key's mode: a sandbox key cannot revoke a live key. A cross-mode id yields no rows and returns 404 exactly like an unknown id, so it cannot be used to probe for the existence of live keys. A key-store outage returns 503 DB_UNAVAILABLE with Retry-After rather than a bare 500.","security":[{"apiKey":[]},{"bearerAuth":[]}],"responses":{"200":{"description":"Revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RevokeAPIKeyResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"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":"keys","x-required-scopes":["keys"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"cua","x-feature-flag":"PUBLIC_CUA_API_ENABLED","x-idempotency":"none"}},"/v1/llm/keys":{"get":{"tags":["keys"],"operationId":"listLlmKeys","summary":"List stored BYOK LLM keys","description":"Scope: `llm_keys` (granted to new live keys by default). Requires a live API key; sandbox keys cannot inspect the production credential store. Returns non-secret metadata only: provider, sha256-prefix fingerprint, timestamps. The key itself is never returned.\n\nA key-store outage returns 503 DB_UNAVAILABLE with Retry-After, not a bare 500, so a transient failure is distinguishable from a permanent one and is safe to retry.","security":[{"apiKey":[]},{"bearerAuth":[]}],"responses":{"200":{"description":"Stored keys (non-secret metadata).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListLlmKeysResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"X-Coasty-Key-Kind":{"$ref":"#/components/headers/KeyKind"},"X-Coasty-Test-Mode":{"$ref":"#/components/headers/TestMode"}}},"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":"llm_keys","x-required-scopes":["llm_keys"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"llm_keys","x-feature-flag":"PUBLIC_LLM_KEYS_API_ENABLED","x-idempotency":"none"}},"/v1/llm/keys/{provider}":{"parameters":[{"name":"provider","in":"path","required":true,"description":"The BYOK provider: anthropic or openai. 'managed' has no storable key and any other value is 422 LLM_PROVIDER_UNSUPPORTED.","schema":{"type":"string","enum":["anthropic","openai"]}}],"put":{"tags":["keys"],"operationId":"storeLlmKey","summary":"Store (upsert) your own provider LLM key","description":"Scope: `llm_keys`. Requires a live API key; sandbox keys cannot modify the production credential store. Stores the caller's own Anthropic/OpenAI API key for BYOK, AES-256-GCM encrypted at rest. The plaintext key exists only in this request body; every response carries only the non-secret sha256-prefix `key_fingerprint` — the key is never returned, logged, or echoed again. Naturally idempotent (an upsert), so no Idempotency-Key is needed.","security":[{"apiKey":[]},{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StoreLlmKeyRequest"},"example":{"api_key":"sk-ant-your_key_here"}}}},"responses":{"200":{"description":"Key stored (fingerprint only; the key is never returned again).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StoreLlmKeyResponse"},"example":{"provider":"anthropic","key_fingerprint":"a1b2c3d4e5f6","stored":true}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"X-Coasty-Key-Kind":{"$ref":"#/components/headers/KeyKind"},"X-Coasty-Test-Mode":{"$ref":"#/components/headers/TestMode"}}},"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":"llm_keys","x-required-scopes":["llm_keys"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"llm_keys","x-feature-flag":"PUBLIC_LLM_KEYS_API_ENABLED","x-idempotency":"none"},"delete":{"tags":["keys"],"operationId":"deleteLlmKey","summary":"Delete your stored BYOK LLM key","description":"Scope: `llm_keys`. Requires a live API key; sandbox keys cannot modify the production credential store. Deletes the stored key for the provider — 404 LLM_KEY_NOT_FOUND when none exists. Schedules that opted into this provider then fail loudly at fire time with LLM_KEY_NOT_CONFIGURED; they never silently run on Coasty's platform keys. Deletion stops future stored-key lookups but does not revoke an encrypted snapshot already held by an active run or workflow, or the fixed create-time key held in memory by an active session. Cancel active runs/workflows and DELETE /v1/sessions/{session_id} for active sessions to stop further calls; terminal run transition scrubs ciphertext. Provider-side revocation stops the key upstream.\n\nA key-store outage returns 503 DB_UNAVAILABLE with Retry-After, not a bare 500. The same distinction applies when a request resolves a stored BYOK key: a store outage is a retryable 503, and 422 LLM_KEY_INVALID is reserved for a key the provider actually rejected.","security":[{"apiKey":[]},{"bearerAuth":[]}],"responses":{"200":{"description":"Deleted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteLlmKeyResponse"},"example":{"deleted":true}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"X-Coasty-Key-Kind":{"$ref":"#/components/headers/KeyKind"},"X-Coasty-Test-Mode":{"$ref":"#/components/headers/TestMode"}}},"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":"llm_keys","x-required-scopes":["llm_keys"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"llm_keys","x-feature-flag":"PUBLIC_LLM_KEYS_API_ENABLED","x-idempotency":"none"}},"/v1/health":{"get":{"tags":["predict"],"operationId":"health","summary":"Public CUA API health check","description":"No authentication required.","security":[],"responses":{"200":{"description":"OK.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}}},"x-auth-mode":"public","x-required-scope":null,"x-required-scopes":[],"x-scope-policy":"none","x-billing-code":null,"x-offering":"cua","x-feature-flag":null,"x-idempotency":"none"}},"/v1/machines":{"post":{"tags":["machines"],"operationId":"provisionMachine","summary":"Provision a new VM","description":"Managed VM provisioning. Managed machines debit the Developer API wallet by runtime state, not agent-minute execution: published defaults are 5 credits/hour running Linux, 9 running Windows, and 1 stopped/suspended, with per-minute granularity. Read effective deployed rates from GET /v1/machines/pricing. Test keys (sk-coasty-test-*) return mock VMs with no cloud calls.","security":[{"apiKey":[]},{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProvisionRequest"}}}},"responses":{"200":{"description":"Machine provisioned (or in-progress).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProvisionResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"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-Coasty-Idempotent-Replay":{"$ref":"#/components/headers/IdempotentReplay"},"Idempotency-Replayed":{"$ref":"#/components/headers/IdempotencyReplayed"},"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":"machines:write","x-required-scopes":["machines:write"],"x-scope-policy":"required","x-billing-code":"machine_runtime","x-offering":"machines","x-feature-flag":"PUBLIC_MACHINES_API_ENABLED","x-idempotency":"reserve-and-replay"},"get":{"tags":["machines"],"operationId":"listMachines","summary":"List machines","security":[{"apiKey":[]},{"bearerAuth":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":200,"default":50}}],"responses":{"200":{"description":"Machines list.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListMachinesResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"X-Coasty-Key-Kind":{"$ref":"#/components/headers/KeyKind"},"X-Coasty-Test-Mode":{"$ref":"#/components/headers/TestMode"}}},"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":"machines:read","x-required-scopes":["machines:read"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"machines","x-feature-flag":"PUBLIC_MACHINES_API_ENABLED","x-idempotency":"none"}},"/v1/machines/external":{"post":{"tags":["machines"],"operationId":"enrollExternalMachine","summary":"Enroll a customer-operated machine","description":"Scope: `machines:write`. Creates an external machine_id for normal Tasks, Workflows, and schedules without provisioning Coasty compute. Authenticate this enrollment with the OWNER API key. Idempotency-Key is required: same key + canonical body safely replays the committed enrollment; a different body conflicts. The response contains a machine-scoped device_token only in this no-store enrollment response/replay, never in list/get; never put an owner API key in the driver.","security":[{"apiKey":[]},{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/RequiredIdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExternalMachineEnrollRequest"}}}},"responses":{"201":{"description":"External machine enrolled. Persist device_token immediately. It is recoverable only by replaying the exact Idempotency-Key/body within the 24-hour enrollment recovery window; list/get never return it.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"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-Coasty-Idempotent-Replay":{"$ref":"#/components/headers/IdempotentReplay"},"Idempotency-Replayed":{"$ref":"#/components/headers/IdempotencyReplayed"},"Idempotency-Status":{"$ref":"#/components/headers/IdempotencyStatus"},"Cache-Control":{"description":"Enrollment contains a one-time secret and must never be cached.","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExternalMachineEnrollResponse"}}}},"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":"machines:write","x-required-scopes":["machines:write"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"machines","x-feature-flag":"PUBLIC_MACHINES_API_ENABLED","x-idempotency":"account-enrollment-replay"}},"/v1/machines/health":{"get":{"tags":["machines"],"operationId":"machinesHealth","summary":"Machines API health check","security":[],"responses":{"200":{"description":"OK.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}}},"x-auth-mode":"public","x-required-scope":null,"x-required-scopes":[],"x-scope-policy":"none","x-billing-code":null,"x-offering":"machines","x-feature-flag":null,"x-idempotency":"none"}},"/v1/machines/pricing":{"get":{"tags":["machines"],"operationId":"getMachinePricing","summary":"Get the live machine runtime rate card","description":"Scope: `machines:read`. Returns deployment-effective runtime rates, one-time charges, provisioning eligibility gate (a minimum-balance gate, not a fee), billing granularity, insufficient-funds behavior, and TTL bounds.","security":[{"apiKey":[]},{"bearerAuth":[]}],"responses":{"200":{"description":"Current machine pricing and lease policy.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MachinePricingResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"X-Coasty-Key-Kind":{"$ref":"#/components/headers/KeyKind"},"X-Coasty-Test-Mode":{"$ref":"#/components/headers/TestMode"}}},"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":"machines:read","x-required-scopes":["machines:read"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"machines","x-feature-flag":"PUBLIC_MACHINES_API_ENABLED","x-idempotency":"none"}},"/v1/billing/active":{"get":{"tags":["machines"],"operationId":"getActiveBilling","summary":"What is billing me right now","description":"Lists every API-billed machine currently metering your wallet (running OR stopped — stopped bills at the storage-only rate). current_run_rate_cents_per_hour is the summed instantaneous burn rate. Test-mode keys return an empty fleet (active: [], rate 0). 1 credit = 1 cent.","security":[{"apiKey":[]},{"bearerAuth":[]}],"responses":{"200":{"description":"Currently-metering fleet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingActiveResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"X-Coasty-Key-Kind":{"$ref":"#/components/headers/KeyKind"},"X-Coasty-Test-Mode":{"$ref":"#/components/headers/TestMode"}}},"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":"machines:read","x-required-scopes":["machines:read"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"billing","x-feature-flag":"PUBLIC_BILLING_API_ENABLED","x-idempotency":"none"}},"/v1/machines/{machine_id}":{"parameters":[{"$ref":"#/components/parameters/MachineId"}],"get":{"tags":["machines"],"operationId":"getMachine","summary":"Get machine details","security":[{"apiKey":[]},{"bearerAuth":[]}],"responses":{"200":{"description":"Machine.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetMachineResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"X-Coasty-Key-Kind":{"$ref":"#/components/headers/KeyKind"},"X-Coasty-Test-Mode":{"$ref":"#/components/headers/TestMode"}}},"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":"machines:read","x-required-scopes":["machines:read"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"machines","x-feature-flag":"PUBLIC_MACHINES_API_ENABLED","x-idempotency":"none"},"delete":{"tags":["machines"],"operationId":"terminateMachine","summary":"Terminate or revoke a machine","description":"Irreversible owner operation. Managed machines are terminated and stop runtime billing. External-machine registration is deleted, and its device token and every outstanding command lease are revoked immediately; caller-owned host and storage are untouched.","security":[{"apiKey":[]},{"bearerAuth":[]}],"responses":{"200":{"description":"Termination requested.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LifecycleResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"X-Coasty-Key-Kind":{"$ref":"#/components/headers/KeyKind"},"X-Coasty-Test-Mode":{"$ref":"#/components/headers/TestMode"}}},"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":"machines:write","x-required-scopes":["machines:write"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"machines","x-feature-flag":"PUBLIC_MACHINES_API_ENABLED","x-idempotency":"none"},"patch":{"tags":["machines"],"operationId":"updateMachine","summary":"Set, extend, or clear a machine resource-expiry lease","description":"Scope: `machines:write`. `ttl_minutes=0` clears expiry; values 5..10080 schedule expiry from now. Expiry destroys managed infrastructure. For an external machine it deletes only the Coasty registration and revokes device access/leases; caller-owned host and storage remain untouched.","security":[{"apiKey":[]},{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateMachineRequest"}}}},"responses":{"200":{"description":"Updated lease.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateMachineResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"X-Coasty-Key-Kind":{"$ref":"#/components/headers/KeyKind"},"X-Coasty-Test-Mode":{"$ref":"#/components/headers/TestMode"}}},"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":"machines:write","x-required-scopes":["machines:write"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"machines","x-feature-flag":"PUBLIC_MACHINES_API_ENABLED","x-idempotency":"none"}},"/v1/machines/{machine_id}/commands":{"parameters":[{"$ref":"#/components/parameters/MachineId"}],"get":{"tags":["machines"],"operationId":"listExternalMachineCommands","summary":"Long-poll commands for an external machine","description":"DEVICE TOKEN ONLY. Returns commands after an exclusive cursor. Persist next_cursor only after durably processing the batch. A long-poll timeout returns 200 with data=[]; reconnect with the last committed cursor. The server permits exactly one queued or delivered command per external machine; concurrent dispatch returns 409 MACHINE_BUSY, preventing cross-replica races on one physical display. Each command is fenced, deadline-bound, and tied to the frame in precondition_frame_id. A driver must reject expired, stale-fenced, unsupported, or visibly stale commands instead of executing them.","security":[{"machineToken":[]}],"parameters":[{"$ref":"#/components/parameters/ExternalCommandAfter"},{"$ref":"#/components/parameters/ExternalCommandLimit"},{"$ref":"#/components/parameters/ExternalCommandWaitSeconds"}],"responses":{"200":{"description":"Command batch, or an empty data array when the long poll expires.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExternalMachineCommandsResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/DeviceUnauthorized"},"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":"device_token","x-required-scope":null,"x-required-scopes":[],"x-scope-policy":"machine_token","x-billing-code":null,"x-offering":"machines","x-feature-flag":"PUBLIC_MACHINES_API_ENABLED","x-idempotency":"none"}},"/v1/machines/{machine_id}/observations":{"parameters":[{"$ref":"#/components/parameters/MachineId"}],"post":{"tags":["machines"],"operationId":"submitExternalMachineObservation","summary":"Submit a screenshot observation","description":"DEVICE TOKEN ONLY. Upload one monotonically sequenced, one-frame PNG/JPEG. The encoded payload is limited to 10,485,760 base64 characters (after an optional exact PNG/JPEG data-URI prefix), and decoded dimensions to 320x240 through 3840x2160. The server verifies format, dimensions, and the optional submitted-byte SHA-256, then strips metadata and re-encodes; the response SHA-256 covers those normalized bytes and may differ. Identical sequence replays are safe; reusing a sequence with different bytes is 409. Live transport frames are encrypted, logically expire after 15 minutes, and are excluded from SSE, webhooks, ordinary logs, and ordinary durable run history. Separately, if a live BYOK Task, Workflow, or schedule uses a frame for a visual decision, the fail-closed pre-provider audit retains an exact model-input copy under the account-lifetime screenshot rules.","security":[{"machineToken":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExternalMachineObservationRequest"}}}},"responses":{"200":{"description":"Verified observation, including its canonical frame_id and decoded dimensions.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExternalMachineObservationResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/DeviceUnauthorized"},"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":"device_token","x-required-scope":null,"x-required-scopes":[],"x-scope-policy":"machine_token","x-billing-code":null,"x-offering":"machines","x-feature-flag":"PUBLIC_MACHINES_API_ENABLED","x-idempotency":"none"}},"/v1/machines/{machine_id}/commands/{command_id}/results":{"parameters":[{"$ref":"#/components/parameters/MachineId"},{"$ref":"#/components/parameters/ExternalCommandId"}],"post":{"tags":["machines"],"operationId":"submitExternalMachineCommandResult","summary":"Acknowledge an external-machine command","description":"DEVICE TOKEN ONLY. Submit a terminal success/failure using the exact fencing_token and precondition_frame_id from the command. The optional observation atomically supplies the post-action frame. An identical result replay returns replayed=true; a different body for a completed command, a frame-precondition mismatch, an expired command, or a stale fencing token returns 409 and is never re-executed.","security":[{"machineToken":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExternalMachineCommandResultRequest"}}}},"responses":{"200":{"description":"Command result accepted or safely replayed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExternalMachineCommandResultResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/DeviceUnauthorized"},"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":"device_token","x-required-scope":null,"x-required-scopes":[],"x-scope-policy":"machine_token","x-billing-code":null,"x-offering":"machines","x-feature-flag":"PUBLIC_MACHINES_API_ENABLED","x-idempotency":"none"}},"/v1/machines/{machine_id}/heartbeat":{"parameters":[{"$ref":"#/components/parameters/MachineId"}],"post":{"tags":["machines"],"operationId":"heartbeatExternalMachine","summary":"Renew an external-machine driver lease","description":"DEVICE TOKEN ONLY. Refreshes connection_status and last_seen_at using the current fencing_token and returns authoritative last_sequence/last_frame_id recovery state. A restarted driver can long-poll once to learn the current fence, heartbeat, then submit sequence=last_sequence+1. A revoked machine or stale lease generation is rejected; heartbeats never revive an old device token.","security":[{"machineToken":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExternalMachineHeartbeatRequest"}}}},"responses":{"200":{"description":"Lease renewed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExternalMachineHeartbeatResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/DeviceUnauthorized"},"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":"device_token","x-required-scope":null,"x-required-scopes":[],"x-scope-policy":"machine_token","x-billing-code":null,"x-offering":"machines","x-feature-flag":"PUBLIC_MACHINES_API_ENABLED","x-idempotency":"none"}},"/v1/machines/{machine_id}/start":{"parameters":[{"$ref":"#/components/parameters/MachineId"}],"post":{"tags":["machines"],"operationId":"startMachine","summary":"Start a stopped machine","description":"Managed: requests a power-on. External: logical dispatch start only — increments the fencing generation, cancels pending commands, and marks the driver stale until it reconnects; Coasty does not power the caller-owned host.","security":[{"apiKey":[]},{"bearerAuth":[]}],"responses":{"200":{"description":"Started.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LifecycleResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"X-Coasty-Key-Kind":{"$ref":"#/components/headers/KeyKind"},"X-Coasty-Test-Mode":{"$ref":"#/components/headers/TestMode"}}},"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":"machines:write","x-required-scopes":["machines:write"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"machines","x-feature-flag":"PUBLIC_MACHINES_API_ENABLED","x-idempotency":"none"}},"/v1/machines/{machine_id}/stop":{"parameters":[{"$ref":"#/components/parameters/MachineId"}],"post":{"tags":["machines"],"operationId":"stopMachine","summary":"Stop a running machine","description":"Managed: requests a power-off while preserving disk. External: logical dispatch stop only — increments the fencing generation, cancels pending commands, and marks the driver disconnected; Coasty does not power the caller-owned host.","security":[{"apiKey":[]},{"bearerAuth":[]}],"responses":{"200":{"description":"Stopped.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LifecycleResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"X-Coasty-Key-Kind":{"$ref":"#/components/headers/KeyKind"},"X-Coasty-Test-Mode":{"$ref":"#/components/headers/TestMode"}}},"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":"machines:write","x-required-scopes":["machines:write"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"machines","x-feature-flag":"PUBLIC_MACHINES_API_ENABLED","x-idempotency":"none"}},"/v1/machines/{machine_id}/restart":{"parameters":[{"$ref":"#/components/parameters/MachineId"}],"post":{"tags":["machines"],"operationId":"restartMachine","summary":"Restart a running machine","description":"Managed: requests a reboot. External: logical dispatch restart only — increments the fencing generation, cancels pending commands, and marks the driver stale until it reconnects; Coasty does not reboot the caller-owned host.","security":[{"apiKey":[]},{"bearerAuth":[]}],"responses":{"200":{"description":"Restart requested.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LifecycleResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"X-Coasty-Key-Kind":{"$ref":"#/components/headers/KeyKind"},"X-Coasty-Test-Mode":{"$ref":"#/components/headers/TestMode"}}},"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":"machines:write","x-required-scopes":["machines:write"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"machines","x-feature-flag":"PUBLIC_MACHINES_API_ENABLED","x-idempotency":"none"}},"/v1/machines/{machine_id}/snapshot":{"parameters":[{"$ref":"#/components/parameters/MachineId"}],"post":{"tags":["machines"],"operationId":"snapshotMachine","summary":"Snapshot a machine","description":"Managed machines only. External machines return 400 UNSUPPORTED_MACHINE_KIND because Coasty does not own their disks. For managed machines, captures a restorable image and requires `snapshots:write`. The configured one-time fee is charged before dispatch. A conclusive pre-creation rejection is refunded; a timeout, 5xx, or malformed post-dispatch result may already have created the image and returns terminal 503 SNAPSHOT_OUTCOME_UNKNOWN without a blind refund/re-execution.","security":[{"apiKey":[]},{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Snapshot created.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"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-Coasty-Idempotent-Replay":{"$ref":"#/components/headers/IdempotentReplay"},"Idempotency-Replayed":{"$ref":"#/components/headers/IdempotencyReplayed"},"Idempotency-Status":{"$ref":"#/components/headers/IdempotencyStatus"},"X-Credits-Charged":{"$ref":"#/components/headers/CreditsCharged"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SnapshotResponse"}}}},"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":"snapshots:write","x-required-scopes":["snapshots:write"],"x-scope-policy":"required","x-billing-code":"snapshot","x-offering":"machines","x-feature-flag":"PUBLIC_MACHINES_API_ENABLED","x-idempotency":"reserve-and-replay"}},"/v1/machines/{machine_id}/screenshot":{"parameters":[{"$ref":"#/components/parameters/MachineId"}],"get":{"tags":["machines"],"operationId":"getScreenshot","summary":"Capture a screenshot of the machine","description":"Returns raw base64 pixels and decoded dimensions. External-machine responses also return a canonical frame_id; pass that value as the next mutation's precondition_frame_id so changed screens fail closed. A fresh screenshot is a read-only resynchronization operation and advances the external observation frame.","security":[{"apiKey":[]},{"bearerAuth":[]}],"responses":{"200":{"description":"Screenshot.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScreenshotResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"X-Coasty-Key-Kind":{"$ref":"#/components/headers/KeyKind"},"X-Coasty-Test-Mode":{"$ref":"#/components/headers/TestMode"}}},"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":"machines:read","x-required-scopes":["machines:read"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"machines","x-feature-flag":"PUBLIC_MACHINES_API_ENABLED","x-idempotency":"none"}},"/v1/machines/{machine_id}/connection":{"parameters":[{"$ref":"#/components/parameters/MachineId"}],"get":{"tags":["machines"],"operationId":"getConnectionDetails","summary":"Get SSH key + VNC password (HIGH-RISK)","description":"Managed machines only. External machines return 409 INVALID_STATE because Coasty never issues SSH, VNC, WebSocket, or browser-debug credentials for caller-owned devices. For managed machines, returns plaintext credentials gated by `connection:read`; the response is `Cache-Control: no-store`. Store credentials in a secrets manager — Coasty cannot re-issue them; rotate by terminating + reprovisioning.","security":[{"apiKey":[]},{"bearerAuth":[]}],"responses":{"200":{"description":"Connection details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectionDetailsFull"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"X-Coasty-Key-Kind":{"$ref":"#/components/headers/KeyKind"},"X-Coasty-Test-Mode":{"$ref":"#/components/headers/TestMode"}}},"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":"connection:read","x-required-scopes":["connection:read"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"machines","x-feature-flag":"PUBLIC_MACHINES_API_ENABLED","x-idempotency":"none"}},"/v1/machines/{machine_id}/actions":{"parameters":[{"$ref":"#/components/parameters/MachineId"}],"post":{"tags":["machines"],"operationId":"executeAction","summary":"Execute a single action on the machine","description":"Required scope varies by command: terminal_* → `terminal:exec`; file_* → `files:read|write`; browser_execute → `browser:execute`; everything else → `actions:exec`. See the ActionRequest command enum and /v1/models for current capabilities. For an external machine, capture a frame, plan against those pixels, and send its frame_id as precondition_frame_id. The driver revalidates the pixels immediately before input and atomically commits the result plus post-action observation. A stale frame fails closed with 409 FRAME_PRECONDITION_MISMATCH or a typed unsuccessful action result; never blindly reissue an input whose outcome is unknown. Successful fresh responses may include screenshot, frame_id, and observation_available=true. Idempotent replays never execute again and omit screenshot pixels while retaining frame_id.","security":[{"apiKey":[]},{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActionRequest"}}}},"responses":{"200":{"description":"Action result.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActionResultResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"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-Coasty-Idempotent-Replay":{"$ref":"#/components/headers/IdempotentReplay"},"Idempotency-Replayed":{"$ref":"#/components/headers/IdempotencyReplayed"},"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":"per-command","x-required-scopes":["actions:exec","terminal:exec","files:read","files:write","browser:execute"],"x-scope-policy":"dynamic","x-billing-code":null,"x-offering":"machines","x-feature-flag":"PUBLIC_MACHINES_API_ENABLED","x-idempotency":"reserve-and-replay"}},"/v1/machines/{machine_id}/actions/batch":{"parameters":[{"$ref":"#/components/parameters/MachineId"}],"post":{"tags":["machines"],"operationId":"executeBatch","summary":"Execute up to 50 sequential actions","description":"Shell `&&`-style semantics: aborts on first failure when `stop_on_error=true` (default). External GUI control should normally use one action per observe→plan→act turn: every committed mutation creates a new frame_id, so a later coordinate action cannot safely be pre-bound to an unknown future frame. External batches fail closed when a step's precondition is omitted or stale; they do not silently auto-bind future screen state.","security":[{"apiKey":[]},{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchActionRequest"}}}},"responses":{"200":{"description":"Per-step results.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchActionResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"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-Coasty-Idempotent-Replay":{"$ref":"#/components/headers/IdempotentReplay"},"Idempotency-Replayed":{"$ref":"#/components/headers/IdempotencyReplayed"},"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":"union-of-command-scopes","x-required-scopes":["actions:exec","terminal:exec","files:read","files:write","browser:execute"],"x-scope-policy":"dynamic","x-billing-code":null,"x-offering":"machines","x-feature-flag":"PUBLIC_MACHINES_API_ENABLED","x-idempotency":"reserve-and-replay"}},"/v1/machines/{machine_id}/browser/{op}":{"parameters":[{"$ref":"#/components/parameters/MachineId"},{"name":"op","in":"path","required":true,"description":"Browser sub-op. One of: open, navigate, click, type, dom, clickables, state, info, scroll, close, screenshot, wait, list-tabs, open-tab, close-tab, switch-tab.","schema":{"type":"string","enum":["open","navigate","click","type","dom","clickables","state","info","scroll","close","screenshot","wait","list-tabs","open-tab","close-tab","switch-tab"]}}],"post":{"tags":["machines"],"operationId":"browserOp","summary":"Browser convenience sub-API","description":"Convenience mapping to the strict browser_* action commands. A mutating operation on an external machine requires precondition_frame_id; read-only state/DOM/screenshot operations may omit it.","security":[{"apiKey":[]},{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrowserOpRequest"}}}},"responses":{"200":{"description":"Browser action result.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActionResultResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"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-Coasty-Idempotent-Replay":{"$ref":"#/components/headers/IdempotentReplay"},"Idempotency-Replayed":{"$ref":"#/components/headers/IdempotencyReplayed"},"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":"actions:exec","x-required-scopes":["actions:exec"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"machines","x-feature-flag":"PUBLIC_MACHINES_API_ENABLED","x-idempotency":"reserve-and-replay"}},"/v1/machines/{machine_id}/terminal":{"parameters":[{"$ref":"#/components/parameters/MachineId"}],"post":{"tags":["machines"],"operationId":"terminalExec","summary":"Execute a shell command","description":"Output truncated VM-side to 5000 chars. Hard cap 120s (Cloudflare edge timeout). Requires `terminal:exec` scope. An external terminal execution is a mutation and requires precondition_frame_id; use the direct action surface for terminal_read if a read-only operation is needed.","security":[{"apiKey":[]},{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TerminalRequest"}}}},"responses":{"200":{"description":"Terminal output.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActionResultResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"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-Coasty-Idempotent-Replay":{"$ref":"#/components/headers/IdempotentReplay"},"Idempotency-Replayed":{"$ref":"#/components/headers/IdempotencyReplayed"},"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":"terminal:exec","x-required-scopes":["terminal:exec"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"machines","x-feature-flag":"PUBLIC_MACHINES_API_ENABLED","x-idempotency":"reserve-and-replay"}},"/v1/machines/{machine_id}/files/{op}":{"parameters":[{"$ref":"#/components/parameters/MachineId"},{"name":"op","in":"path","required":true,"description":"File sub-op. Read scope: read, exists, list, list-directory, download, list-downloads. Write scope: write, edit, append, delete, delete-directory.","schema":{"type":"string","enum":["read","exists","list","list-directory","download","list-downloads","write","edit","append","delete","delete-directory"]}}],"post":{"tags":["machines"],"operationId":"filesOp","summary":"File operations sub-API","description":"Read ops require `files:read`; mutating ops require `files:write`. Body capped at 50 MB. Mutating external-machine file operations require precondition_frame_id; read-only operations may omit it.","security":[{"apiKey":[]},{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FilesOpRequest"}}}},"responses":{"200":{"description":"File op result.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActionResultResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"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-Coasty-Idempotent-Replay":{"$ref":"#/components/headers/IdempotentReplay"},"Idempotency-Replayed":{"$ref":"#/components/headers/IdempotencyReplayed"},"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":"files:read-or-files:write","x-required-scopes":["files:read","files:write"],"x-scope-policy":"dynamic","x-billing-code":null,"x-offering":"machines","x-feature-flag":"PUBLIC_MACHINES_API_ENABLED","x-idempotency":"reserve-and-replay"}},"/v1/schedules":{"post":{"tags":["schedules"],"operationId":"createSchedule","summary":"Create a schedule","description":"Cron-based or one-shot (run_at) scheduled task. Managed defaults: creation is free behind a $0.20 Developer API wallet gate; non-Unlimited execution uses the consumer subscription-credit balance at 10 credits/minute with a 20-credit start minimum. BYOK bypasses those Coasty wallet/start/runtime meters and debits zero platform credits. With a live Coasty key, the developer's provider bills actual tokens. Under test auth, a managed-mode schedule remains deterministic sandbox execution. Any BYOK header or provider metadata instead returns 422 LLM_PROVIDER_UNSUPPORTED before execution: BYOK is unavailable for synthetic test runs, workflows, and schedules. Use managed mode or a live Coasty API key. Test execution never decrypts or requires a stored provider key and does not call or bill Anthropic/OpenAI. Live schedules require a stored key because fires have no request headers. A supplied header key is validation-only and must match the stored key; each live fire resolves the CURRENT stored key. Deleting it makes future live firings fail loudly with LLM_KEY_NOT_CONFIGURED, never platform fallback. Once a live firing produces a provider result, its terminal transition and content-free, zero-credit usage admission commit atomically; deferred projection remains service-only and retryable. The creating Coasty key id is internal usage attribution and is never added to the schedule response. Operator overrides remain discoverable under GET /v1/models pricing.schedules.","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/ScheduleCreateRequest"}}}},"responses":{"200":{"description":"Schedule created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"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-Coasty-Idempotent-Replay":{"$ref":"#/components/headers/IdempotentReplay"},"Idempotency-Replayed":{"$ref":"#/components/headers/IdempotencyReplayed"},"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":"schedules:write","x-required-scopes":["schedules:write"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"schedules","x-feature-flag":"PUBLIC_SCHEDULES_API_ENABLED","x-idempotency":"reserve-and-replay"},"get":{"tags":["schedules"],"operationId":"listSchedules","summary":"List schedules","description":"Scope: `schedules:read`. A schedule-store outage returns 503 DB_UNAVAILABLE with Retry-After, not a bare 500.","security":[{"apiKey":[]},{"bearerAuth":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":200,"default":50}}],"responses":{"200":{"description":"Schedules.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListSchedulesResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"X-Coasty-Key-Kind":{"$ref":"#/components/headers/KeyKind"},"X-Coasty-Test-Mode":{"$ref":"#/components/headers/TestMode"}}},"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":"schedules:read","x-required-scopes":["schedules:read"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"schedules","x-feature-flag":"PUBLIC_SCHEDULES_API_ENABLED","x-idempotency":"none"}},"/v1/schedules/health":{"get":{"tags":["schedules"],"operationId":"schedulesHealth","summary":"Schedules API health check","security":[],"responses":{"200":{"description":"OK.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}}},"x-auth-mode":"public","x-required-scope":null,"x-required-scopes":[],"x-scope-policy":"none","x-billing-code":null,"x-offering":"schedules","x-feature-flag":null,"x-idempotency":"none"}},"/v1/schedules/{schedule_id}":{"parameters":[{"$ref":"#/components/parameters/ScheduleId"}],"get":{"tags":["schedules"],"operationId":"getSchedule","summary":"Get schedule details","description":"Scope: `schedules:read`. An unknown or cross-tenant schedule id returns the standard 404 error envelope; a schedule-store outage returns 503 DB_UNAVAILABLE with Retry-After. Neither surfaces as a bare 500.","security":[{"apiKey":[]},{"bearerAuth":[]}],"responses":{"200":{"description":"Schedule.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"X-Coasty-Key-Kind":{"$ref":"#/components/headers/KeyKind"},"X-Coasty-Test-Mode":{"$ref":"#/components/headers/TestMode"}}},"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":"schedules:read","x-required-scopes":["schedules:read"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"schedules","x-feature-flag":"PUBLIC_SCHEDULES_API_ENABLED","x-idempotency":"none"},"patch":{"tags":["schedules"],"operationId":"updateSchedule","summary":"Update a schedule","description":"Updates mutable schedule fields only. llm, machine_id, and run_at are not accepted; delete and recreate the schedule to change its BYOK provider/model-role preference, target machine, or one-shot time. Rotating the separately stored provider key takes effect on the next fire without recreating the schedule. The ScheduleResponse fingerprint remains its creation-time reference; per-fire usage attribution records the actual key.","security":[{"apiKey":[]},{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleUpdateRequest"}}}},"responses":{"200":{"description":"Updated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"X-Coasty-Key-Kind":{"$ref":"#/components/headers/KeyKind"},"X-Coasty-Test-Mode":{"$ref":"#/components/headers/TestMode"}}},"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":"schedules:write","x-required-scopes":["schedules:write"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"schedules","x-feature-flag":"PUBLIC_SCHEDULES_API_ENABLED","x-idempotency":"none"},"delete":{"tags":["schedules"],"operationId":"deleteSchedule","summary":"Delete a schedule","security":[{"apiKey":[]},{"bearerAuth":[]}],"responses":{"200":{"description":"Deleted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteScheduleResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"X-Coasty-Key-Kind":{"$ref":"#/components/headers/KeyKind"},"X-Coasty-Test-Mode":{"$ref":"#/components/headers/TestMode"}}},"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":"schedules:write","x-required-scopes":["schedules:write"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"schedules","x-feature-flag":"PUBLIC_SCHEDULES_API_ENABLED","x-idempotency":"none"}},"/v1/schedules/{schedule_id}/pause":{"parameters":[{"$ref":"#/components/parameters/ScheduleId"}],"post":{"tags":["schedules"],"operationId":"pauseSchedule","summary":"Pause a schedule","security":[{"apiKey":[]},{"bearerAuth":[]}],"responses":{"200":{"description":"Paused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"X-Coasty-Key-Kind":{"$ref":"#/components/headers/KeyKind"},"X-Coasty-Test-Mode":{"$ref":"#/components/headers/TestMode"}}},"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":"schedules:write","x-required-scopes":["schedules:write"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"schedules","x-feature-flag":"PUBLIC_SCHEDULES_API_ENABLED","x-idempotency":"none"}},"/v1/schedules/{schedule_id}/resume":{"parameters":[{"$ref":"#/components/parameters/ScheduleId"}],"post":{"tags":["schedules"],"operationId":"resumeSchedule","summary":"Resume a paused schedule","security":[{"apiKey":[]},{"bearerAuth":[]}],"responses":{"200":{"description":"Resumed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"X-Coasty-Key-Kind":{"$ref":"#/components/headers/KeyKind"},"X-Coasty-Test-Mode":{"$ref":"#/components/headers/TestMode"}}},"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":"schedules:write","x-required-scopes":["schedules:write"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"schedules","x-feature-flag":"PUBLIC_SCHEDULES_API_ENABLED","x-idempotency":"none"}},"/v1/schedules/{schedule_id}/run":{"parameters":[{"$ref":"#/components/parameters/ScheduleId"}],"post":{"tags":["schedules"],"operationId":"runScheduleNow","summary":"Trigger a schedule run immediately","description":"Managed-model published defaults: queueing run-now is free behind a $0.20 Developer API wallet gate; resulting non-Unlimited execution uses consumer subscription credits at 10 credits/minute with a 20-credit start minimum. Unlimited bypasses this runtime credit meter and start-balance gate while retaining separate token/concurrency safeguards. A BYOK schedule bypasses both wallet gates and the consumer-credit runtime meter and debits zero Coasty platform credits. Live-key schedule execution is billed directly by the selected provider. Under test auth, managed-mode execution remains deterministic sandbox; BYOK intent returns 422 LLM_PROVIDER_UNSUPPORTED before execution. It never decrypts or requires a stored provider key and makes no provider call. Read GET /v1/models pricing.schedules for effective deployed values and plan applicability.","security":[{"apiKey":[]},{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunScheduleRequest"}}}},"responses":{"200":{"description":"Run queued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunScheduleResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"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-Coasty-Idempotent-Replay":{"$ref":"#/components/headers/IdempotentReplay"},"Idempotency-Replayed":{"$ref":"#/components/headers/IdempotencyReplayed"},"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":"schedules:write","x-required-scopes":["schedules:write"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"schedules","x-feature-flag":"PUBLIC_SCHEDULES_API_ENABLED","x-idempotency":"reserve-and-replay"}},"/v1/schedules/{schedule_id}/runs":{"parameters":[{"$ref":"#/components/parameters/ScheduleId"}],"get":{"tags":["schedules"],"operationId":"listScheduleRuns","summary":"List historical runs of a schedule","security":[{"apiKey":[]},{"bearerAuth":[]}],"parameters":[{"name":"cursor","in":"query","required":false,"schema":{"type":"string"}},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["running","completed","failed","skipped","cancelled","insufficient_credits"]}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":200,"default":50}}],"responses":{"200":{"description":"Runs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListScheduleRunsResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"X-Coasty-Key-Kind":{"$ref":"#/components/headers/KeyKind"},"X-Coasty-Test-Mode":{"$ref":"#/components/headers/TestMode"}}},"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":"schedules:read","x-required-scopes":["schedules:read"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"schedules","x-feature-flag":"PUBLIC_SCHEDULES_API_ENABLED","x-idempotency":"none"}},"/v1/schedules/{schedule_id}/runs/{run_id}":{"parameters":[{"$ref":"#/components/parameters/ScheduleId"},{"name":"run_id","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[A-Za-z0-9_\\-]+$"}}],"get":{"tags":["schedules"],"operationId":"getScheduleRun","summary":"Get a single run","description":"Scope: `schedules:read`. A run absent from this schedule returns 404 RUN_NOT_FOUND; a store outage returns 503 DB_UNAVAILABLE with Retry-After. Neither surfaces as a bare 500.","security":[{"apiKey":[]},{"bearerAuth":[]}],"responses":{"200":{"description":"Run.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleRunRecord"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"X-Coasty-Key-Kind":{"$ref":"#/components/headers/KeyKind"},"X-Coasty-Test-Mode":{"$ref":"#/components/headers/TestMode"}}},"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":"schedules:read","x-required-scopes":["schedules:read"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"schedules","x-feature-flag":"PUBLIC_SCHEDULES_API_ENABLED","x-idempotency":"none"}},"/v1/schedules/{schedule_id}/triggers":{"parameters":[{"$ref":"#/components/parameters/ScheduleId"}],"get":{"tags":["triggers"],"operationId":"listTriggers","summary":"List triggers attached to a schedule","security":[{"apiKey":[]},{"bearerAuth":[]}],"responses":{"200":{"description":"Triggers.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListTriggersResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"X-Coasty-Key-Kind":{"$ref":"#/components/headers/KeyKind"},"X-Coasty-Test-Mode":{"$ref":"#/components/headers/TestMode"}}},"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":"schedules:read","x-required-scopes":["schedules:read"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"schedules","x-feature-flag":"PUBLIC_SCHEDULES_API_ENABLED","x-idempotency":"none"},"post":{"tags":["triggers"],"operationId":"addTrigger","summary":"Add a trigger (webhook | chain)","description":"For `webhook`, create and exact bounded Idempotency-Key replay responses include the same HMAC `webhook_secret`; GET/list never expose it. It is encrypted at rest for verification/replay recovery, so store your copy securely. Chain triggers support a max depth of 5.","security":[{"apiKey":[]},{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TriggerCreateRequest"}}}},"responses":{"200":{"description":"Trigger created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TriggerResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"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-Coasty-Idempotent-Replay":{"$ref":"#/components/headers/IdempotentReplay"},"Idempotency-Replayed":{"$ref":"#/components/headers/IdempotencyReplayed"},"Idempotency-Status":{"$ref":"#/components/headers/IdempotencyStatus"}}},"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":"triggers:write","x-required-scopes":["triggers:write"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"schedules","x-feature-flag":"PUBLIC_SCHEDULES_API_ENABLED","x-idempotency":"reserve-and-replay"}},"/v1/schedules/{schedule_id}/triggers/{trigger_id}":{"parameters":[{"$ref":"#/components/parameters/ScheduleId"},{"$ref":"#/components/parameters/TriggerId"}],"delete":{"tags":["triggers"],"operationId":"removeTrigger","summary":"Remove a trigger","security":[{"apiKey":[]},{"bearerAuth":[]}],"responses":{"200":{"description":"Removed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteTriggerResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"X-Coasty-Key-Kind":{"$ref":"#/components/headers/KeyKind"},"X-Coasty-Test-Mode":{"$ref":"#/components/headers/TestMode"}}},"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":"triggers:write","x-required-scopes":["triggers:write"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"schedules","x-feature-flag":"PUBLIC_SCHEDULES_API_ENABLED","x-idempotency":"none"}},"/v1/triggers/webhook/{webhook_id}":{"parameters":[{"$ref":"#/components/parameters/WebhookId"}],"post":{"tags":["triggers"],"operationId":"fireWebhook","summary":"Fire a schedule from an HMAC-authenticated external webhook","description":"No Coasty API key is used. The request is authenticated with HMAC-SHA256 over `<unix_ts>.<body>` using the secret from trigger creation. Send either `Coasty-Signature: t=<ts>,v1=<sig>` or its `X-Coasty-Signature` compatibility alias. Published defaults are a 300-second replay window, 1,000,000-byte body cap, and 60-second identical-(webhook_id, body) deduplication window. Read effective deployed values from GET /v1/models under pricing.schedules.","security":[{"webhookHmac":[]},{"webhookHmacLegacy":[]}],"parameters":[{"name":"Coasty-Signature","in":"header","required":false,"description":"Primary HMAC credential. Exactly one supported signature header is required.","schema":{"type":"string","examples":["t=1714900000,v1=4d2f...e7"]}},{"name":"X-Coasty-Signature","in":"header","required":false,"description":"Compatibility alias for Coasty-Signature. Send one signature header, not both.","schema":{"type":"string","examples":["t=1714900000,v1=4d2f...e7"]}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}},"text/plain":{"schema":{"type":"string"}},"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"responses":{"200":{"description":"Webhook accepted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookFireResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/WebhookUnauthorized"},"402":{"$ref":"#/components/responses/PaymentRequired"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"413":{"description":"Body exceeds 1 MB.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"},"X-Credits-Charged":{"$ref":"#/components/headers/CreditsCharged"},"X-Credits-Refunded":{"$ref":"#/components/headers/CreditsRefunded"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"PAYLOAD_TOO_LARGE","message":"An error occurred. See `code` for details.","type":"validation_error","request_id":"req_a1b2c3d4e5f6","retryable":false,"retry_with_same_idempotency_key":false}}}}},"429":{"description":"Webhook per-minute rate limit exceeded. Honor Retry-After.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"},"X-Credits-Charged":{"$ref":"#/components/headers/CreditsCharged"},"X-Credits-Refunded":{"$ref":"#/components/headers/CreditsRefunded"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"RATE_LIMITED","message":"An error occurred. See `code` for details.","type":"validation_error","request_id":"req_a1b2c3d4e5f6","retryable":false,"retry_with_same_idempotency_key":false}}}}},"500":{"$ref":"#/components/responses/ServerError"}},"x-auth-mode":"hmac_sha256","x-required-scope":null,"x-required-scopes":[],"x-scope-policy":"none","x-billing-code":null,"x-offering":"triggers","x-feature-flag":"PUBLIC_TRIGGERS_API_ENABLED","x-idempotency":"webhook-payload-dedup"}},"/v1/triggers/health":{"get":{"tags":["triggers"],"operationId":"triggersHealth","summary":"Triggers API health check","security":[],"responses":{"200":{"description":"OK.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}}},"x-auth-mode":"public","x-required-scope":null,"x-required-scopes":[],"x-scope-policy":"none","x-billing-code":null,"x-offering":"triggers","x-feature-flag":null,"x-idempotency":"none"}},"/v1/tasks":{"post":{"tags":["runs"],"operationId":"createAutonomousTask","summary":"Submit a task and let Coasty handle everything","description":"Scope: `runs:write`. The high-level submit-and-forget API. Coasty asynchronously provisions an ephemeral managed desktop, runs the screenshot→act→observe→verify loop, refuses human takeover, and never enters awaiting_human. A handoff request is suppressed and the agent is told to carry on with a fresh screen: there is no retry budget and no challenge-specific terminal error, so a verification screen, CAPTCHA or email confirmation is treated as part of the task. max_steps, deadline_seconds and the credit balance are the only hard stops. Credentials, inboxes and codes supplied in the task are the agent's to use — fetching a confirmation code from an inbox you provided is ordinary work, not an escalation. Coasty does not provide or integrate third-party CAPTCHA solvers, stealth/proxy evasion, access-control bypasses, or fabricated authority, and the agent is explicitly prohibited from using them. Per-step model-input frames are retained for every run and readable at GET /v1/runs/{run_id}/screenshots, and the assembled step-by-step trajectory (reasoning, actions, outcomes) at GET /v1/runs/{run_id}/log — which is where you read a finished run's full trajectory or final answer, since result.summary is only the last 2000 characters. It records a terminal succeeded/failed/timed_out outcome, starts idempotent machine cleanup, and sends the optional HMAC-signed webhook. Webhook delivery can precede completed provider termination, so inspect machine.cleanup_status (terminating, retrying, or terminated). The admission response is immediate and uses the normal agent.run resource, so GET /v1/runs/{id}, cancellation, and SSE remain available but are not required when a webhook is supplied. Idempotency-Key deduplicates task admission and machine provisioning. Managed CUA steps and machine runtime are billed normally; BYOK makes LLM execution zero Coasty platform credits but does not make machine runtime free.","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/AutonomousTaskRequest"}}}},"responses":{"200":{"description":"Task accepted (agent.run status \"queued\").","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"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-Coasty-Idempotent-Replay":{"$ref":"#/components/headers/IdempotentReplay"},"Idempotency-Replayed":{"$ref":"#/components/headers/IdempotencyReplayed"},"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":"runs:write","x-required-scopes":["runs:write"],"x-scope-policy":"required","x-billing-code":"run_step","x-offering":"runs","x-feature-flag":"RUNS_API_ENABLED","x-idempotency":"reserve-and-replay"}},"/v1/runs":{"post":{"tags":["runs"],"operationId":"createRun","summary":"Start an autonomous run","description":"Scope: `runs:write`. Drives `task` to completion on `machine_id`, running the screenshot→act→verify loop server-side. Managed defaults charge 5 credits per completed agent step on v3/v4/v5 and 8 on v1. With a live Coasty key, BYOK runs every role on YOUR provider key and debits zero Coasty platform credits for creation and every step, while persisting actual provider tokens; no wallet runway is required. Under test auth, a managed-mode run remains deterministic sandbox execution. Any BYOK header or provider metadata instead returns 422 LLM_PROVIDER_UNSUPPORTED before execution: BYOK is unavailable for synthetic test runs, workflows, and schedules. Use managed mode or a live Coasty API key. Test execution never decrypts or requires a stored provider key and does not call or bill Anthropic/OpenAI. Run steps do not inherit /v1/predict trajectory, HD-image, or combined-prompt surcharges. Idempotency-Key deduplicates top-level creation, not later GUI/terminal/file side effects. `webhook_secret` is returned only by create/replay; a live BYOK key snapshot is encrypted for crash recovery and scrubbed at terminal state.","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/RunRequest"}}}},"responses":{"200":{"description":"Run created (status \"queued\").","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"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-Coasty-Idempotent-Replay":{"$ref":"#/components/headers/IdempotentReplay"},"Idempotency-Replayed":{"$ref":"#/components/headers/IdempotencyReplayed"},"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":"runs:write","x-required-scopes":["runs:write"],"x-scope-policy":"required","x-billing-code":"run_step","x-offering":"runs","x-feature-flag":"RUNS_API_ENABLED","x-idempotency":"reserve-and-replay"},"get":{"tags":["runs"],"operationId":"listRuns","summary":"List runs","description":"Scope: `runs:read`. Free. Optional `status` filter and `limit` (1-200, default 20).","security":[{"apiKey":[]},{"bearerAuth":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["queued","running","awaiting_human","succeeded","failed","cancelled","timed_out"]}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":200,"default":20}}],"responses":{"200":{"description":"A list of runs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListRunsResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"X-Coasty-Key-Kind":{"$ref":"#/components/headers/KeyKind"},"X-Coasty-Test-Mode":{"$ref":"#/components/headers/TestMode"}}},"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":"runs:read","x-required-scopes":["runs:read"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"runs","x-feature-flag":"RUNS_API_ENABLED","x-idempotency":"none"}},"/v1/runs/{run_id}":{"parameters":[{"$ref":"#/components/parameters/RunId"}],"get":{"tags":["runs"],"operationId":"getRun","summary":"Get a run","description":"Scope: `runs:read`. Free. Returns status, result, and credits charged.","security":[{"apiKey":[]},{"bearerAuth":[]}],"responses":{"200":{"description":"The run.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"X-Coasty-Key-Kind":{"$ref":"#/components/headers/KeyKind"},"X-Coasty-Test-Mode":{"$ref":"#/components/headers/TestMode"}}},"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":"runs:read","x-required-scopes":["runs:read"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"runs","x-feature-flag":"RUNS_API_ENABLED","x-idempotency":"none"}},"/v1/runs/{run_id}/events":{"parameters":[{"$ref":"#/components/parameters/RunId"}],"get":{"tags":["runs"],"operationId":"streamRunEvents","summary":"Stream run events (SSE)","description":"Scope: `runs:read`. Free. An ordered at-least-once Server-Sent Events stream. Successfully persisted frames have an effectively unbounded replay window and resume with `Last-Event-ID` or `?after=<seq>`. Intermediate appends are best-effort and can be absent after a transient storage failure; terminal status/done are transactionally admitted with Agent Run terminal state. The edge may rotate a connection after 300 seconds, so reconnect with the last sequence and reconcile authoritative state with GET /v1/runs/{run_id}.\n\nA stream can close on any of THREE terminal frames, not just `done`:\n- `event: done` — the run reached a terminal state and the sentinel was delivered.\n- `event: timeout` with `data: {\"reason\":\"stream_max_duration\"}` — the server hit its own stream wall-clock ceiling. The RUN may still be going. Reconnect with the last sequence; do not treat this as a run outcome.\n- `event: error` with `data: {\"code\":..., \"message\":...}` — the event read failed. Reconnect with `Last-Event-ID` to replay from the cursor.\n\nEach frame's `data:` field carries only the event's inner payload; `seq` is on the `id:` line and the event type is the event name. To read a finished run's whole trajectory as plain JSON, use GET /v1/runs/{run_id}/log instead.","security":[{"apiKey":[]},{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/LastEventId"},{"name":"after","in":"query","required":false,"schema":{"type":"integer","minimum":0}}],"responses":{"200":{"description":"SSE stream (text/event-stream).","content":{"text/event-stream":{"schema":{"type":"string"},"description":"A Server-Sent Events byte stream. Each frame carries an event name/id and JSON in its data field; reconnect with Last-Event-ID."}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"X-Coasty-Key-Kind":{"$ref":"#/components/headers/KeyKind"},"X-Coasty-Test-Mode":{"$ref":"#/components/headers/TestMode"}}},"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":"runs:read","x-required-scopes":["runs:read"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"runs","x-feature-flag":"RUNS_API_ENABLED","x-idempotency":"none"}},"/v1/runs/{run_id}/log":{"parameters":[{"$ref":"#/components/parameters/RunId"}],"get":{"tags":["runs"],"operationId":"getRunLog","summary":"Read what a run actually did, step by step","description":"Scope: `runs:read`. Free. **This is the supported way to read a finished run's full trajectory or its final answer.** `GET /v1/runs/{run_id}/events` streams the same source over SSE, which suits watching a run live but makes inspecting a completed one awkward; `result.summary` on the run object is only the last 2000 characters.\n\nEach step arrives assembled: the model's reasoning already unwrapped from its `<cua-section>` markup (`analysis`, `next_action`, `grounded_action`, `action_result`), then every action with its coordinates and outcome, plus what the step cost and the `screenshot_index` of the frame the agent saw before acting. No parsing required. Pass `include_events=true` to also get the raw events, nested inside the step they belong to.\n\n**Read `log_complete` before concluding anything from an absence.** The event log is BEST EFFORT and is not written inside the run's transaction, so a step can execute and be billed while its log rows are lost. When `log_complete` is false, `steps_completed` is the authoritative count and a step missing here did not necessarily fail to happen.\n\nPage with `after_step`. `lifecycle` is returned whole on every page because it is small and usually contains the reason the run stopped.\n\nErrors: 404 RUN_NOT_FOUND for an unknown or cross-tenant run (ownership is checked first, so a run you do not own is never revealed as an empty log). 503 DB_UNAVAILABLE with Retry-After when the event store is failing.","security":[{"apiKey":[]},{"bearerAuth":[]}],"parameters":[{"name":"limit","in":"query","required":false,"description":"Steps per page. Outside 1..200 returns 400 INVALID_LIMIT.","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"after_step","in":"query","required":false,"description":"Return steps with a step number strictly greater than this. Negative values return 400 INVALID_EVENT_CURSOR.","schema":{"type":"integer","minimum":0,"default":0}},{"name":"include_events","in":"query","required":false,"description":"Nest the raw events each step was folded from inside that step.","schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"A page of assembled steps, plus run-level lifecycle events.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListRunLogResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"X-Coasty-Key-Kind":{"$ref":"#/components/headers/KeyKind"},"X-Coasty-Test-Mode":{"$ref":"#/components/headers/TestMode"}}},"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":"runs:read","x-required-scopes":["runs:read"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"runs","x-feature-flag":"RUNS_API_ENABLED","x-idempotency":"none"}},"/v1/runs/{run_id}/screenshots":{"parameters":[{"$ref":"#/components/parameters/RunId"}],"get":{"tags":["runs"],"operationId":"listRunScreenshots","summary":"List run screenshots","description":"Scope: `runs:read`. Free. The model-input frames for a run, oldest first — the exact images the agent saw before each decision, which is what you want when reconstructing why it did something. Captured for every run, managed and BYOK alike.\n\nMetadata only by default: a single frame is several hundred KB of base64, so pass `include_image=true` to inline `image_b64` (page size is clamped to 10 in that mode, and the response is `Cache-Control: no-store` because frames can show whatever was on screen).\n\nPage with `after_index`. `index` is flat and monotonic across the WHOLE run and is the stable address for a frame: a run that was reaped and retried starts a new attempt whose `step` counter restarts at 1, so `step` alone is not unique — `attempt` tells you which try a frame belongs to. A frame whose stored bytes cannot be decoded is returned with `image_unavailable: true` rather than failing the page.","security":[{"apiKey":[]},{"bearerAuth":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"after_index","in":"query","required":false,"description":"Return frames with index greater than or equal to this.","schema":{"type":"integer","minimum":0,"default":0}},{"name":"include_image","in":"query","required":false,"description":"Inline base64 PNG per frame. Clamps limit to 10 and sets Cache-Control: no-store.","schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"A page of run screenshots.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListRunScreenshotsResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"X-Coasty-Key-Kind":{"$ref":"#/components/headers/KeyKind"},"X-Coasty-Test-Mode":{"$ref":"#/components/headers/TestMode"}}},"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":"runs:read","x-required-scopes":["runs:read"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"runs","x-feature-flag":"RUNS_API_ENABLED","x-idempotency":"none"}},"/v1/runs/{run_id}/cancel":{"parameters":[{"$ref":"#/components/parameters/RunId"}],"post":{"tags":["runs"],"operationId":"cancelRun","summary":"Cancel a run","description":"Scope: `runs:write`. Free. Cancels an in-flight run.","security":[{"apiKey":[]},{"bearerAuth":[]}],"responses":{"200":{"description":"The cancelled run.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"X-Coasty-Key-Kind":{"$ref":"#/components/headers/KeyKind"},"X-Coasty-Test-Mode":{"$ref":"#/components/headers/TestMode"}}},"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":"runs:write","x-required-scopes":["runs:write"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"runs","x-feature-flag":"RUNS_API_ENABLED","x-idempotency":"none"}},"/v1/runs/{run_id}/resume":{"parameters":[{"$ref":"#/components/parameters/RunId"}],"post":{"tags":["runs"],"operationId":"resumeRun","summary":"Resume a run after human takeover","description":"Scope: `runs:write`. Free. Resumes a run paused in `awaiting_human`. Body is optional.","security":[{"apiKey":[]},{"bearerAuth":[]}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResumeRunRequest"}}}},"responses":{"200":{"description":"The resumed run.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"X-Coasty-Key-Kind":{"$ref":"#/components/headers/KeyKind"},"X-Coasty-Test-Mode":{"$ref":"#/components/headers/TestMode"}}},"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":"runs:write","x-required-scopes":["runs:write"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"runs","x-feature-flag":"RUNS_API_ENABLED","x-idempotency":"none"}},"/v1/workflows":{"post":{"tags":["workflows"],"operationId":"createWorkflow","summary":"Create a workflow","description":"Scope: `workflows:write`. Free (definition only). Creates a versioned workflow from a DSL `definition`.","security":[{"apiKey":[]},{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowCreateRequest"}}}},"responses":{"200":{"description":"The created workflow.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"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-Coasty-Idempotent-Replay":{"$ref":"#/components/headers/IdempotentReplay"},"Idempotency-Replayed":{"$ref":"#/components/headers/IdempotencyReplayed"},"Idempotency-Status":{"$ref":"#/components/headers/IdempotencyStatus"}}},"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":"workflows:write","x-required-scopes":["workflows:write"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"workflows","x-feature-flag":"WORKFLOWS_API_ENABLED","x-idempotency":"reserve-and-replay"},"get":{"tags":["workflows"],"operationId":"listWorkflows","summary":"List workflows","description":"Scope: `workflows:read`. Free. `limit` 1-200 (default 20).","security":[{"apiKey":[]},{"bearerAuth":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":200,"default":20}}],"responses":{"200":{"description":"A list of workflows.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListWorkflowsResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"X-Coasty-Key-Kind":{"$ref":"#/components/headers/KeyKind"},"X-Coasty-Test-Mode":{"$ref":"#/components/headers/TestMode"}}},"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":"workflows:read","x-required-scopes":["workflows:read"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"workflows","x-feature-flag":"WORKFLOWS_API_ENABLED","x-idempotency":"none"}},"/v1/workflows/runs":{"post":{"tags":["workflows"],"operationId":"startAdhocWorkflowRun","summary":"Start an ad-hoc workflow run","description":"Scope: `workflows:write`. Runs an inline `definition` without saving it. Managed defaults charge 5 credits per completed `task` step on v3/v4/v5 and 8 on v1; other step types are free and budget_cents caps managed spend. With a live Coasty key, BYOK runs every task role on YOUR provider key with zero Coasty platform credits and no managed-step budget reservation, while persisting actual provider tokens. Under test auth, managed-mode Workflow task children remain deterministic sandbox execution. Any BYOK header or provider metadata instead returns 422 LLM_PROVIDER_UNSUPPORTED before execution: BYOK is unavailable for synthetic test runs, workflows, and schedules. Use managed mode or a live Coasty API key. Test execution never decrypts or requires a stored provider key and does not call or bill Anthropic/OpenAI. Task steps do not inherit /v1/predict trajectory, HD-image, or combined-prompt surcharges. The live BYOK key snapshot is encrypted for recovery and scrubbed at terminal state.","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/StartAdhocWorkflowRunRequest"}}}},"responses":{"200":{"description":"The started workflow run.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowRunResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"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-Coasty-Idempotent-Replay":{"$ref":"#/components/headers/IdempotentReplay"},"Idempotency-Replayed":{"$ref":"#/components/headers/IdempotencyReplayed"},"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":"workflows:write","x-required-scopes":["workflows:write"],"x-scope-policy":"required","x-billing-code":"run_step","x-offering":"workflows","x-feature-flag":"WORKFLOWS_API_ENABLED","x-idempotency":"reserve-and-replay"},"get":{"tags":["workflows"],"operationId":"listWorkflowRuns","summary":"List workflow runs","description":"Scope: `workflows:read`. Free. Optional `workflow_id` filter and `limit` (1-200, default 20).","security":[{"apiKey":[]},{"bearerAuth":[]}],"parameters":[{"name":"workflow_id","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":200,"default":20}}],"responses":{"200":{"description":"A list of workflow runs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListWorkflowRunsResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"X-Coasty-Key-Kind":{"$ref":"#/components/headers/KeyKind"},"X-Coasty-Test-Mode":{"$ref":"#/components/headers/TestMode"}}},"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":"workflows:read","x-required-scopes":["workflows:read"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"workflows","x-feature-flag":"WORKFLOWS_API_ENABLED","x-idempotency":"none"}},"/v1/workflows/runs/{run_id}":{"parameters":[{"$ref":"#/components/parameters/RunId"}],"get":{"tags":["workflows"],"operationId":"getWorkflowRun","summary":"Get a workflow run","description":"Scope: `workflows:read`. Free.","security":[{"apiKey":[]},{"bearerAuth":[]}],"responses":{"200":{"description":"The workflow run.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowRunResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"X-Coasty-Key-Kind":{"$ref":"#/components/headers/KeyKind"},"X-Coasty-Test-Mode":{"$ref":"#/components/headers/TestMode"}}},"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":"workflows:read","x-required-scopes":["workflows:read"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"workflows","x-feature-flag":"WORKFLOWS_API_ENABLED","x-idempotency":"none"}},"/v1/workflows/runs/{run_id}/events":{"parameters":[{"$ref":"#/components/parameters/RunId"}],"get":{"tags":["workflows"],"operationId":"streamWorkflowRunEvents","summary":"Stream workflow run events (SSE)","description":"Scope: `workflows:read`. Free. Ordered at-least-once SSE for successfully persisted frames; resume with `Last-Event-ID` or `?after=<seq>`. Workflow event appends, including terminal frames, are best-effort and can be absent if storage or the worker fails after the durable state transition. The edge may rotate a connection after 300 seconds; reconcile authoritative state with GET /v1/workflows/runs/{run_id} rather than waiting indefinitely for a terminal frame.\n\nAs with run streams, the connection can close on `event: done`, on `event: timeout` with `data: {\"reason\":\"stream_max_duration\"}` when the server's stream wall-clock ceiling is reached (the workflow run may still be going), or on `event: error` with `data: {\"code\":..., \"message\":...}`. Only `done` describes the run; the other two describe the stream.","security":[{"apiKey":[]},{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/LastEventId"},{"name":"after","in":"query","required":false,"schema":{"type":"integer","minimum":0}}],"responses":{"200":{"description":"SSE stream (text/event-stream).","content":{"text/event-stream":{"schema":{"type":"string"},"description":"A Server-Sent Events byte stream. Each frame carries an event name/id and JSON in its data field; reconnect with Last-Event-ID."}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"X-Coasty-Key-Kind":{"$ref":"#/components/headers/KeyKind"},"X-Coasty-Test-Mode":{"$ref":"#/components/headers/TestMode"}}},"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":"workflows:read","x-required-scopes":["workflows:read"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"workflows","x-feature-flag":"WORKFLOWS_API_ENABLED","x-idempotency":"none"}},"/v1/workflows/runs/{run_id}/cancel":{"parameters":[{"$ref":"#/components/parameters/RunId"}],"post":{"tags":["workflows"],"operationId":"cancelWorkflowRun","summary":"Cancel a workflow run","description":"Scope: `workflows:write`. Free.","security":[{"apiKey":[]},{"bearerAuth":[]}],"responses":{"200":{"description":"The cancelled workflow run.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowRunResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"X-Coasty-Key-Kind":{"$ref":"#/components/headers/KeyKind"},"X-Coasty-Test-Mode":{"$ref":"#/components/headers/TestMode"}}},"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":"workflows:write","x-required-scopes":["workflows:write"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"workflows","x-feature-flag":"WORKFLOWS_API_ENABLED","x-idempotency":"none"}},"/v1/workflows/runs/{run_id}/resume":{"parameters":[{"$ref":"#/components/parameters/RunId"}],"post":{"tags":["workflows"],"operationId":"resumeWorkflowRun","summary":"Approve or reject a paused workflow run","description":"Scope: `workflows:write`. Free. Approves (continues) or rejects (fails) a run paused on a `human_approval` step.","security":[{"apiKey":[]},{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResumeWorkflowRunRequest"}}}},"responses":{"200":{"description":"The resumed workflow run.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowRunResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"X-Coasty-Key-Kind":{"$ref":"#/components/headers/KeyKind"},"X-Coasty-Test-Mode":{"$ref":"#/components/headers/TestMode"}}},"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":"workflows:write","x-required-scopes":["workflows:write"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"workflows","x-feature-flag":"WORKFLOWS_API_ENABLED","x-idempotency":"none"}},"/v1/workflows/{workflow_id}":{"parameters":[{"$ref":"#/components/parameters/WorkflowId"}],"get":{"tags":["workflows"],"operationId":"getWorkflow","summary":"Get a workflow","description":"Scope: `workflows:read`. Free.","security":[{"apiKey":[]},{"bearerAuth":[]}],"responses":{"200":{"description":"The workflow.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"X-Coasty-Key-Kind":{"$ref":"#/components/headers/KeyKind"},"X-Coasty-Test-Mode":{"$ref":"#/components/headers/TestMode"}}},"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":"workflows:read","x-required-scopes":["workflows:read"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"workflows","x-feature-flag":"WORKFLOWS_API_ENABLED","x-idempotency":"none"},"put":{"tags":["workflows"],"operationId":"updateWorkflow","summary":"Update a workflow","description":"Scope: `workflows:write`. Free. Every successful update bumps the workflow `version` exactly once. A stale concurrent update returns 409 CONFLICT; fetch the latest workflow and retry.","security":[{"apiKey":[]},{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowUpdateRequest"}}}},"responses":{"200":{"description":"The updated workflow.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"X-Coasty-Key-Kind":{"$ref":"#/components/headers/KeyKind"},"X-Coasty-Test-Mode":{"$ref":"#/components/headers/TestMode"}}},"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":"workflows:write","x-required-scopes":["workflows:write"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"workflows","x-feature-flag":"WORKFLOWS_API_ENABLED","x-idempotency":"none"},"delete":{"tags":["workflows"],"operationId":"deleteWorkflow","summary":"Archive a workflow","description":"Scope: `workflows:write`. Free. Archives the workflow.","security":[{"apiKey":[]},{"bearerAuth":[]}],"responses":{"200":{"description":"Deletion acknowledged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowDeleteResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"X-Coasty-Key-Kind":{"$ref":"#/components/headers/KeyKind"},"X-Coasty-Test-Mode":{"$ref":"#/components/headers/TestMode"}}},"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":"workflows:write","x-required-scopes":["workflows:write"],"x-scope-policy":"required","x-billing-code":null,"x-offering":"workflows","x-feature-flag":"WORKFLOWS_API_ENABLED","x-idempotency":"none"}},"/v1/workflows/{workflow_id}/runs":{"parameters":[{"$ref":"#/components/parameters/WorkflowId"}],"post":{"tags":["workflows"],"operationId":"startWorkflowRun","summary":"Start a run of a saved workflow","description":"Scope: `workflows:write`. Runs the saved workflow. Managed defaults charge 5 credits per completed `task` step on v3/v4/v5 and 8 on v1; other steps are free and budget_cents caps managed spend. With a live Coasty key, BYOK runs every task role on YOUR provider key, reserves/charges zero Coasty platform credits, and persists actual provider tokens; no silent fallback. Under test auth, managed-mode Workflow task children remain deterministic sandbox execution. Any BYOK header or provider metadata instead returns 422 LLM_PROVIDER_UNSUPPORTED before execution: BYOK is unavailable for synthetic test runs, workflows, and schedules. Use managed mode or a live Coasty API key. Test execution never decrypts or requires a stored provider key and does not call or bill Anthropic/OpenAI. Task steps do not inherit /v1/predict trajectory, HD-image, or combined-prompt surcharges. The live BYOK key snapshot is encrypted for recovery and scrubbed at terminal state.","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/StartWorkflowRunRequest"}}}},"responses":{"200":{"description":"The started workflow run.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowRunResponse"}}},"headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"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-Coasty-Idempotent-Replay":{"$ref":"#/components/headers/IdempotentReplay"},"Idempotency-Replayed":{"$ref":"#/components/headers/IdempotencyReplayed"},"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":"workflows:write","x-required-scopes":["workflows:write"],"x-scope-policy":"required","x-billing-code":"run_step","x-offering":"workflows","x-feature-flag":"WORKFLOWS_API_ENABLED","x-idempotency":"reserve-and-replay"}}},"components":{"securitySchemes":{"apiKey":{"type":"apiKey","name":"X-API-Key","in":"header","description":"Coasty API key. Live: `sk-coasty-live-...`. Sandbox: `sk-coasty-test-...`."},"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"Coasty API key (sk-coasty-{live,test}-...)","description":"Equivalent to X-API-Key. Use whichever your client supports."},"machineToken":{"type":"http","scheme":"bearer","bearerFormat":"dvc_coasty_{live|test}_<token>","description":"External-machine driver credential returned by POST /v1/machines/external. Valid only for that machine's commands, observations, results, and heartbeat endpoints. It is not an owner API key and cannot enroll, list, inspect, run, or delete resources. Before authentication, malformed or rotating credentials share a peer bucket of 1,000 requests/minute and 40,000/hour. After authentication, each device token is limited to 300 requests/minute and 12,000/hour, and all device tokens owned by one account share 1,200 requests/minute and 48,000/hour. Screenshot observations additionally have a per-token limit of 60/minute and 3,600/hour. 429 responses include retry metadata."},"webhookHmac":{"type":"apiKey","name":"Coasty-Signature","in":"header","description":"HMAC-SHA256 credential for external schedule webhooks: t=<unix_ts>,v1=<hex_digest>."},"webhookHmacLegacy":{"type":"apiKey","name":"X-Coasty-Signature","in":"header","description":"Compatibility alias for the Coasty-Signature HMAC credential."}},"schemas":{"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 and the original request already carried the key. This covers the exact 18 generic reserve-and-replay operations plus the separate account-scoped external-enrollment replay domain. Reuse that SAME key with its identical bound inputs. 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)."},"rule":{"type":"string","enum":["max_actions","structured_action","allowed_actions","blocked_actions","blocked_keys","block_window_close","coordinate_bounds"],"description":"Present on ACTION_POLICY_VIOLATION errors and identifies the enforced policy rule."},"action_index":{"type":"integer","minimum":0,"description":"Zero-based proposed-action index on ACTION_POLICY_VIOLATION when the rule is attributable to one action; omitted for batch-level rules such as max_actions."},"action_type":{"type":"string","description":"Proposed action type on ACTION_POLICY_VIOLATION when attributable to one action; omitted for batch-level or uninspectable values."},"examples":{"type":"object","additionalProperties":true,"description":"Machine-readable limits for self-correction. On PAYLOAD_TOO_LARGE / INVALID_SCREENSHOT: { max_base64_bytes: 10485760 (legacy name), max_base64_chars: 10485760, max_request_body_bytes: 15728640, max_mb: 10, min_base64_chars: 100, formats: [\"png\",\"jpeg\"] }."}}}}},"DirectEmptyParameters":{"type":"object","maxProperties":0,"additionalProperties":false},"DirectClickParameters":{"type":"object","required":["x","y"],"additionalProperties":false,"properties":{"x":{"type":"integer","minimum":0,"maximum":100000},"y":{"type":"integer","minimum":0,"maximum":100000},"button":{"type":"string","enum":["left","right","middle"],"default":"left"},"clicks":{"type":"integer","minimum":1,"maximum":3,"default":1}}},"DirectDoubleClickParameters":{"type":"object","required":["x","y"],"additionalProperties":false,"properties":{"x":{"type":"integer","minimum":0,"maximum":100000},"y":{"type":"integer","minimum":0,"maximum":100000},"button":{"type":"string","enum":["left","right","middle"],"default":"left"}}},"DirectModifiedClickParameters":{"type":"object","required":["x","y"],"additionalProperties":false,"not":{"required":["hold_keys","modifiers"]},"properties":{"x":{"type":"integer","minimum":0,"maximum":100000},"y":{"type":"integer","minimum":0,"maximum":100000},"button":{"type":"string","enum":["left","right","middle"],"default":"left"},"clicks":{"type":"integer","minimum":1,"maximum":3,"default":1},"hold_keys":{"type":"array","maxItems":8,"items":{"type":"string","minLength":1,"maxLength":64},"default":[]},"modifiers":{"type":"array","maxItems":8,"items":{"type":"string","minLength":1,"maxLength":64},"description":"Alias for hold_keys. Send only one vocabulary."}}},"DirectTypeParameters":{"type":"object","required":["text"],"additionalProperties":false,"properties":{"text":{"type":"string","maxLength":1000000},"interval":{"type":"number","minimum":0,"maximum":10}}},"DirectKeyPressParameters":{"type":"object","additionalProperties":false,"oneOf":[{"required":["key"]},{"required":["keys"]}],"properties":{"key":{"type":"string","minLength":1,"maxLength":64},"keys":{"type":"array","minItems":1,"maxItems":100,"items":{"type":"string","minLength":1,"maxLength":64}}}},"DirectKeyComboParameters":{"type":"object","required":["keys"],"additionalProperties":false,"properties":{"keys":{"type":"array","minItems":2,"maxItems":8,"items":{"type":"string","minLength":1,"maxLength":64}}}},"DirectScrollParameters":{"type":"object","additionalProperties":false,"oneOf":[{"required":["clicks"]},{"required":["amount"]}],"dependentRequired":{"x":["y"],"y":["x"]},"properties":{"clicks":{"type":"integer","minimum":-100,"maximum":100,"not":{"const":0}},"amount":{"type":"integer","minimum":1,"maximum":100},"direction":{"type":"string","enum":["vertical","horizontal","up","down","left","right"],"default":"vertical"},"x":{"type":"integer","minimum":0,"maximum":100000},"y":{"type":"integer","minimum":0,"maximum":100000}}},"DirectDragParameters":{"type":"object","required":["x1","y1","x2","y2"],"additionalProperties":false,"properties":{"x1":{"type":"integer","minimum":0,"maximum":100000},"y1":{"type":"integer","minimum":0,"maximum":100000},"x2":{"type":"integer","minimum":0,"maximum":100000},"y2":{"type":"integer","minimum":0,"maximum":100000},"button":{"type":"string","enum":["left","right","middle"],"default":"left"},"hold_keys":{"type":"array","maxItems":8,"items":{"type":"string","minLength":1,"maxLength":64},"default":[]}}},"DirectMoveParameters":{"type":"object","required":["x","y"],"additionalProperties":false,"properties":{"x":{"type":"integer","minimum":0,"maximum":100000},"y":{"type":"integer","minimum":0,"maximum":100000}}},"DirectWindowTargetParameters":{"type":"object","additionalProperties":false,"not":{"required":["window_title","window_id"]},"properties":{"window_title":{"type":"string","minLength":1,"maxLength":512},"window_id":{"type":"string","minLength":1,"maxLength":128}}},"DirectSwitchWindowParameters":{"type":"object","required":["window"],"additionalProperties":false,"properties":{"window":{"type":"string","minLength":1,"maxLength":512}}},"DirectArrangeWindowsParameters":{"type":"object","additionalProperties":false,"properties":{"arrangement":{"type":"string","enum":["tile","cascade","minimize_all","show_desktop","restore_all"],"default":"tile"}}},"DirectMoveWindowParameters":{"type":"object","required":["x","y"],"additionalProperties":false,"not":{"required":["window_title","window_id"]},"dependentRequired":{"width":["height"],"height":["width"]},"properties":{"window_title":{"type":"string","minLength":1,"maxLength":512},"window_id":{"type":"string","minLength":1,"maxLength":128},"x":{"type":"integer","minimum":-100000,"maximum":100000},"y":{"type":"integer","minimum":-100000,"maximum":100000},"width":{"type":"integer","minimum":1,"maximum":100000},"height":{"type":"integer","minimum":1,"maximum":100000}}},"DirectTerminalConnectParameters":{"type":"object","additionalProperties":false,"properties":{"cwd":{"type":"string","minLength":1,"maxLength":4096}}},"DirectTerminalExecuteParameters":{"type":"object","required":["command"],"additionalProperties":false,"properties":{"command":{"type":"string","minLength":1,"maxLength":8192},"wait_for_output":{"type":"boolean","default":true},"timeout":{"type":"integer","minimum":1,"maximum":120,"default":30},"session_id":{"type":"string","minLength":1,"maxLength":128},"cwd":{"type":"string","minLength":1,"maxLength":4096}}},"DirectTerminalSessionParameters":{"type":"object","additionalProperties":false,"properties":{"session_id":{"type":"string","minLength":1,"maxLength":128}}},"DirectPathParameters":{"type":"object","additionalProperties":false,"anyOf":[{"required":["path"]},{"required":["filepath"]}],"description":"Send path or filepath. If both aliases are present, their strings must be identical.","properties":{"path":{"type":"string","minLength":1,"maxLength":4096},"filepath":{"type":"string","minLength":1,"maxLength":4096}}},"DirectFileReadParameters":{"type":"object","additionalProperties":false,"anyOf":[{"required":["path"]},{"required":["filepath"]}],"description":"Send path or filepath. If both aliases are present, their strings must be identical.","properties":{"path":{"type":"string","minLength":1,"maxLength":4096},"filepath":{"type":"string","minLength":1,"maxLength":4096},"encoding":{"type":"string","enum":["auto","utf-8","base64"]}}},"DirectFileContentParameters":{"type":"object","required":["content"],"additionalProperties":false,"anyOf":[{"required":["path"]},{"required":["filepath"]}],"description":"Send path or filepath. If both aliases are present, their strings must be identical.","properties":{"path":{"type":"string","minLength":1,"maxLength":4096},"filepath":{"type":"string","minLength":1,"maxLength":4096},"content":{"type":"string"}}},"DirectFileEditParameters":{"type":"object","additionalProperties":false,"allOf":[{"anyOf":[{"required":["path"]},{"required":["filepath"]}]},{"oneOf":[{"required":["find","replace"],"not":{"anyOf":[{"required":["old_text"]},{"required":["new_text"]}]}},{"required":["old_text","new_text"],"not":{"anyOf":[{"required":["find"]},{"required":["replace"]}]}}]}],"description":"Send path or filepath plus exactly one complete edit vocabulary: find/replace or old_text/new_text. If both path aliases are present they must match.","properties":{"path":{"type":"string","minLength":1,"maxLength":4096},"filepath":{"type":"string","minLength":1,"maxLength":4096},"find":{"type":"string","minLength":1},"replace":{"type":"string"},"old_text":{"type":"string","minLength":1},"new_text":{"type":"string"},"all":{"type":"boolean","const":true,"default":true}}},"DirectDirectoryParameters":{"type":"object","additionalProperties":false,"description":"Defaults to '.'. If path and dirpath are both present, their strings must be identical.","properties":{"path":{"type":"string","minLength":1,"maxLength":4096},"dirpath":{"type":"string","minLength":1,"maxLength":4096}}},"DirectRequiredDirectoryParameters":{"type":"object","additionalProperties":false,"anyOf":[{"required":["path"]},{"required":["dirpath"]}],"description":"Send path or dirpath. If both aliases are present, their strings must be identical.","properties":{"path":{"type":"string","minLength":1,"maxLength":4096},"dirpath":{"type":"string","minLength":1,"maxLength":4096}}},"DirectListDownloadsParameters":{"type":"object","additionalProperties":false,"description":"Directory defaults to '.'. If path and dirpath are both present, their strings must be identical.","properties":{"path":{"type":"string","minLength":1,"maxLength":4096},"dirpath":{"type":"string","minLength":1,"maxLength":4096},"recursive":{"type":"boolean","default":false},"max_files":{"type":"integer","minimum":1,"maximum":1000,"default":100}}},"DirectBrowserOptionalUrlParameters":{"type":"object","additionalProperties":false,"properties":{"url":{"type":"string","minLength":1,"maxLength":8192}}},"DirectBrowserUrlParameters":{"type":"object","required":["url"],"additionalProperties":false,"properties":{"url":{"type":"string","minLength":1,"maxLength":8192}}},"DirectBrowserClickParameters":{"type":"object","additionalProperties":false,"oneOf":[{"required":["selector"]},{"required":["text"]},{"required":["x","y"]}],"dependentRequired":{"x":["y"],"y":["x"]},"properties":{"selector":{"type":"string","minLength":1,"maxLength":4096},"text":{"type":"string","minLength":1,"maxLength":4096},"x":{"type":"integer","minimum":0,"maximum":100000},"y":{"type":"integer","minimum":0,"maximum":100000}}},"DirectBrowserTypeParameters":{"type":"object","required":["text"],"additionalProperties":false,"properties":{"text":{"type":"string","maxLength":1000000},"selector":{"type":"string","minLength":1,"maxLength":4096},"clear":{"type":"boolean","default":true}}},"DirectBrowserScrollParameters":{"type":"object","additionalProperties":false,"properties":{"direction":{"type":"string","enum":["up","down","left","right"],"default":"down"},"amount":{"type":"integer","minimum":1,"maximum":100000,"default":500}}},"DirectBrowserWaitParameters":{"type":"object","additionalProperties":false,"not":{"required":["selector","text"]},"properties":{"selector":{"type":"string","minLength":1,"maxLength":4096},"text":{"type":"string","minLength":1,"maxLength":4096},"timeout":{"type":"integer","minimum":1,"maximum":120000,"default":5000}}},"DirectBrowserScreenshotParameters":{"type":"object","additionalProperties":false,"properties":{"selector":{"type":"string","minLength":1,"maxLength":4096}}},"DirectTabIndexParameters":{"type":"object","additionalProperties":false,"not":{"required":["tab_index","index"]},"properties":{"tab_index":{"type":"integer","minimum":0,"maximum":10000},"index":{"type":"integer","minimum":0,"maximum":10000}}},"DirectRequiredTabIndexParameters":{"type":"object","additionalProperties":false,"oneOf":[{"required":["tab_index"]},{"required":["index"]}],"properties":{"tab_index":{"type":"integer","minimum":0,"maximum":10000},"index":{"type":"integer","minimum":0,"maximum":10000}}},"DirectBrowserExecuteParameters":{"type":"object","additionalProperties":false,"oneOf":[{"required":["script"]},{"required":["code"]}],"properties":{"script":{"type":"string","minLength":1,"maxLength":100000},"code":{"type":"string","minLength":1,"maxLength":100000}}},"PredictionClickParameters":{"type":"object","required":["x","y"],"additionalProperties":false,"properties":{"x":{"type":"integer","minimum":0,"maximum":100000},"y":{"type":"integer","minimum":0,"maximum":100000},"button":{"type":"string","enum":["left","right","middle"],"default":"left"},"clicks":{"type":"integer","minimum":1,"maximum":3,"default":1},"hold_keys":{"type":"array","maxItems":8,"items":{"type":"string","minLength":1,"maxLength":64}}}},"PredictionTypeTextParameters":{"type":"object","required":["text"],"additionalProperties":false,"description":"Literal text entry into whichever control currently owns focus. This action does not read or paste the clipboard.","properties":{"text":{"type":"string","maxLength":32000,"description":"Literal characters to type at the current focus."}}},"PredictionKeyPressParameters":{"type":"object","required":["keys"],"additionalProperties":false,"description":"Sequential key taps at the current focus. Each listed key is pressed and released before the next key; this is not a chord.","properties":{"keys":{"type":"array","minItems":1,"maxItems":100,"items":{"type":"string","minLength":1,"maxLength":64},"description":"Ordered taps. For example, [\"tab\", \"enter\"] means Tab, release, then Enter, release."}}},"PredictionKeyComboParameters":{"type":"object","required":["keys"],"additionalProperties":false,"description":"One focus-sensitive keyboard chord: modifiers are held together while the final key is pressed. Clipboard paste is one [ctrl,v] chord on Windows/Linux or [cmd,v] on macOS; the client must preload the clipboard and focus the destination first.","properties":{"keys":{"type":"array","minItems":2,"maxItems":8,"items":{"type":"string","minLength":1,"maxLength":64},"description":"Keys held as one chord, for example [\"ctrl\", \"v\"], not two sequential taps."}}},"PredictionScrollParameters":{"type":"object","required":["clicks"],"additionalProperties":false,"dependentRequired":{"x":["y"],"y":["x"]},"properties":{"clicks":{"type":"integer","minimum":-100,"maximum":100,"not":{"const":0}},"direction":{"type":"string","enum":["vertical","horizontal"],"default":"vertical"},"x":{"type":"integer","minimum":0,"maximum":100000},"y":{"type":"integer","minimum":0,"maximum":100000}}},"PredictionDragParameters":{"type":"object","required":["x1","y1","x2","y2"],"additionalProperties":false,"properties":{"x1":{"type":"integer","minimum":0,"maximum":100000},"y1":{"type":"integer","minimum":0,"maximum":100000},"x2":{"type":"integer","minimum":0,"maximum":100000},"y2":{"type":"integer","minimum":0,"maximum":100000},"button":{"type":"string","enum":["left","right","middle"],"default":"left"},"hold_keys":{"type":"array","maxItems":8,"items":{"type":"string","minLength":1,"maxLength":64}}}},"PredictionMoveParameters":{"type":"object","required":["x","y"],"additionalProperties":false,"properties":{"x":{"type":"integer","minimum":0,"maximum":100000},"y":{"type":"integer","minimum":0,"maximum":100000}}},"PredictionWaitParameters":{"type":"object","required":["seconds"],"additionalProperties":false,"properties":{"seconds":{"type":"number","minimum":0,"maximum":30}}},"PredictionEmptyParameters":{"type":"object","maxProperties":0,"additionalProperties":false},"PredictionFailParameters":{"type":"object","additionalProperties":false,"properties":{"reason":{"type":"string","maxLength":32000},"code":{"type":"string","const":"ACTION_POLICY_VIOLATION","description":"Present when fail is the structured result of post-model action-policy enforcement."},"rule":{"type":"string","enum":["max_actions","structured_action","allowed_actions","blocked_actions","blocked_keys","block_window_close","coordinate_bounds"]},"message":{"type":"string","maxLength":32000},"action_index":{"type":"integer","minimum":0,"description":"Zero-based index when the violation is attributable to one proposed action; omitted for batch-level rules such as max_actions."},"action_type":{"type":"string","description":"Action type when the violation is attributable to one proposed action; omitted for batch-level or uninspectable values."}}},"ScreenshotBase64":{"description":"One static PNG/JPEG screenshot as raw base64 or an exact data:image/png;base64 / data:image/jpeg;base64 URI. Animated and multi-frame images are rejected. This per-image limit does not multiply the ordinary 15 MiB aggregate JSON request-body cap.","oneOf":[{"type":"string","minLength":100,"maxLength":10485760,"pattern":"^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$","title":"Raw base64"},{"type":"string","minLength":122,"maxLength":10485782,"pattern":"^data:image/png;base64,(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$","title":"PNG data URI"},{"type":"string","minLength":123,"maxLength":10485783,"pattern":"^data:image/jpeg;base64,(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$","title":"JPEG data URI"}]},"IdempotencyLookupResponse":{"type":"object","required":["status","request_id"],"description":"Result of GET /v1/idempotency/{key} for the generic concrete-credential reserve cache. 'completed' returns the replay-safe response body plus original_status; 'processing' means the original is still running; an unknown/expired key is a 404 NOT_FOUND. Screenshot pixels are deliberately excluded from action replay records: frame_id remains available, but screenshot is null and observation_available=false. External-machine enrollment uses its separate account-scoped replay path and is recovered only by repeating the exact enrollment POST.","properties":{"status":{"type":"string","enum":["completed","processing"],"description":"completed = a cached result is included; processing = the original is still executing."},"request_id":{"type":"string"},"result":{"anyOf":[{"description":"The replay-safe response body. Present only when status is 'completed'. Action screenshots are response-only and are not retained in this cache."},{"type":"null"}]},"original_status":{"type":["integer","null"],"description":"The HTTP status the original response returned (e.g. 200). Present only when status is 'completed'."}}},"ActionResponse":{"oneOf":[{"type":"object","required":["action_type","params"],"additionalProperties":false,"properties":{"action_type":{"type":"string","const":"click"},"params":{"$ref":"#/components/schemas/PredictionClickParameters"},"description":{"type":"string"},"raw_code":{"type":"string","description":"Canonical safe pyautogui generated from the validated structured action. Never unsanitized model text."}}},{"type":"object","required":["action_type","params"],"additionalProperties":false,"properties":{"action_type":{"type":"string","const":"type_text"},"params":{"$ref":"#/components/schemas/PredictionTypeTextParameters"},"description":{"type":"string"},"raw_code":{"type":"string","description":"Canonical safe pyautogui generated from the validated structured action. Never unsanitized model text."}}},{"type":"object","required":["action_type","params"],"additionalProperties":false,"properties":{"action_type":{"type":"string","const":"key_press"},"params":{"$ref":"#/components/schemas/PredictionKeyPressParameters"},"description":{"type":"string"},"raw_code":{"type":"string","description":"Canonical safe pyautogui generated from the validated structured action. Never unsanitized model text."}}},{"type":"object","required":["action_type","params"],"additionalProperties":false,"properties":{"action_type":{"type":"string","const":"key_combo"},"params":{"$ref":"#/components/schemas/PredictionKeyComboParameters"},"description":{"type":"string"},"raw_code":{"type":"string","description":"Canonical safe pyautogui generated from the validated structured action. Never unsanitized model text."}}},{"type":"object","required":["action_type","params"],"additionalProperties":false,"properties":{"action_type":{"type":"string","const":"scroll"},"params":{"$ref":"#/components/schemas/PredictionScrollParameters"},"description":{"type":"string"},"raw_code":{"type":"string","description":"Canonical safe pyautogui generated from the validated structured action. Never unsanitized model text."}}},{"type":"object","required":["action_type","params"],"additionalProperties":false,"properties":{"action_type":{"type":"string","const":"drag"},"params":{"$ref":"#/components/schemas/PredictionDragParameters"},"description":{"type":"string"},"raw_code":{"type":"string","description":"Canonical safe pyautogui generated from the validated structured action. Never unsanitized model text."}}},{"type":"object","required":["action_type","params"],"additionalProperties":false,"properties":{"action_type":{"type":"string","const":"move"},"params":{"$ref":"#/components/schemas/PredictionMoveParameters"},"description":{"type":"string"},"raw_code":{"type":"string","description":"Canonical safe pyautogui generated from the validated structured action. Never unsanitized model text."}}},{"type":"object","required":["action_type","params"],"additionalProperties":false,"properties":{"action_type":{"type":"string","const":"wait"},"params":{"$ref":"#/components/schemas/PredictionWaitParameters"},"description":{"type":"string"},"raw_code":{"type":"string","description":"Canonical safe pyautogui generated from the validated structured action. Never unsanitized model text."}}},{"type":"object","required":["action_type","params"],"additionalProperties":false,"properties":{"action_type":{"type":"string","const":"done","description":"Terminal model completion claim with no OS effect. Read the top-level status and verify fresh post-action pixels/application state before accepting business completion."},"params":{"$ref":"#/components/schemas/PredictionEmptyParameters"},"description":{"type":"string"},"raw_code":{"type":"string","description":"Canonical safe pyautogui generated from the validated structured action. Never unsanitized model text."}}},{"type":"object","required":["action_type","params"],"additionalProperties":false,"properties":{"action_type":{"type":"string","const":"fail"},"params":{"$ref":"#/components/schemas/PredictionFailParameters"},"description":{"type":"string"},"raw_code":{"type":"string","description":"Canonical safe pyautogui generated from the validated structured action. Never unsanitized model text."}}}],"discriminator":{"propertyName":"action_type"},"description":"A deny-by-default structured CUA action. params is selected by action_type; unknown keys and unsafe model text are never returned."},"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-cent amount; the same numeric value as credits_charged (divide by 100 for USD)."},"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 Coasty wallet debit; false on BYOK, test keys (sk-coasty-test-*), and idempotent replays (all return credits_charged: 0)."},"llm_provider":{"type":"string","enum":["managed","anthropic","openai"],"default":"managed","description":"Effective inference provider. Non-managed values identify provider-direct BYOK execution."},"llm_model":{"type":["string","null"],"description":"Effective BYOK model id; null for managed inference."},"llm_key_fingerprint":{"type":["string","null"],"minLength":12,"maxLength":12,"pattern":"^[0-9a-f]{12}$","description":"Non-secret SHA-256 prefix identifying the BYOK key; never the key itself."},"llm_key_source":{"type":["string","null"],"enum":["header","stored"],"description":"Where the effective BYOK key came from; null for managed inference."},"platform_cost_exempt":{"type":"boolean","default":false,"description":"true for BYOK. Coasty credits/cost are zero. Provider billing occurs only for provider-direct execution. Managed-mode test Task, Workflow, and schedule sandbox execution makes no provider call; test-auth BYOK intent on those async endpoints is rejected before execution."}}},"CoordinateBounds":{"type":"object","required":["max_x","max_y"],"additionalProperties":false,"description":"Inclusive coordinate rectangle in the request screenshot's pixel space.","properties":{"min_x":{"type":"integer","minimum":0,"maximum":3840,"default":0},"min_y":{"type":"integer","minimum":0,"maximum":2160,"default":0},"max_x":{"type":"integer","minimum":0,"maximum":3840},"max_y":{"type":"integer","minimum":0,"maximum":2160}}},"ActionPolicy":{"type":"object","additionalProperties":false,"description":"Opt-in, fail-closed post-model action enforcement. The complete normalized batch is checked atomically before actions are returned or dispatched. allowed_actions and blocked_actions cannot overlap. Prediction, Session, and Parse surfaces use prediction action names such as type_text; direct Machine routes use command names such as type. Task, Workflow, and Schedule policies are create-time controls inherited across execution and recovery.","properties":{"allowed_actions":{"type":["array","null"],"minItems":1,"maxItems":128,"uniqueItems":true,"items":{"type":"string","pattern":"^\\s*[A-Za-z][A-Za-z0-9_:-]{0,63}\\s*$"},"description":"Optional action allowlist. Values are trimmed and lowercased before validation; duplicates after normalization are rejected. Terminal done/fail/awaiting_human signals remain allowed."},"blocked_actions":{"type":"array","maxItems":128,"uniqueItems":true,"default":[],"items":{"type":"string","pattern":"^\\s*[A-Za-z][A-Za-z0-9_:-]{0,63}\\s*$"},"description":"Action denylist. Values are trimmed and lowercased before validation; duplicates after normalization are rejected."},"blocked_keys":{"type":"array","maxItems":128,"uniqueItems":true,"default":[],"items":{"type":"string","pattern":"^\\s*[A-Za-z0-9_+\\-=\\[\\]\\\\;',./`]{1,64}\\s*$"},"description":"Keys forbidden in key_press, key_combo, and modifier-bearing actions. Values are trimmed and lowercased; duplicates after normalization are rejected; esc aliases escape."},"block_window_close":{"type":"boolean","default":false,"description":"Block explicit close commands and common Alt+F4, Ctrl/Cmd+W, and Cmd+Q shortcuts."},"max_actions":{"type":["integer","null"],"minimum":1,"maximum":10000,"description":"Maximum number of actions admitted in one prediction/session step, parsed action batch, or direct Machine batch."},"coordinate_bounds":{"anyOf":[{"$ref":"#/components/schemas/CoordinateBounds"},{"type":"null"}]}}},"TrajectoryStep":{"type":"object","required":["screenshot"],"additionalProperties":false,"dependentRequired":{"screen_width":["screen_height"],"screen_height":["screen_width"]},"properties":{"screenshot":{"$ref":"#/components/schemas/ScreenshotBase64"},"screen_width":{"type":["integer","null"],"minimum":320,"maximum":3840,"description":"Coordinate-space width for this step's actions. Supply with screen_height; omit both to use the decoded image width."},"screen_height":{"type":["integer","null"],"minimum":240,"maximum":2160,"description":"Coordinate-space height for this step's actions. Supply with screen_width; omit both to use the decoded image height."},"actions":{"type":"array","maxItems":10,"items":{"$ref":"#/components/schemas/ActionResponse"}},"reasoning":{"type":"string","maxLength":16000}}},"PredictRequest":{"type":"object","required":["screenshot","instruction"],"additionalProperties":false,"description":"Stateless screenshot-to-actions request. The current screenshot, every trajectory screenshot, and all remaining JSON together must fit the 15 MiB (15,728,640-byte) request-body cap; compress/downscale history or use a stateful session for long trajectories.","dependentRequired":{"screen_width":["screen_height"],"screen_height":["screen_width"]},"properties":{"screenshot":{"$ref":"#/components/schemas/ScreenshotBase64"},"instruction":{"type":"string","minLength":1,"maxLength":32000,"description":"Natural-language task instruction. This task text is not counted toward the custom-prompt surcharge."},"cua_version":{"type":"string","enum":["v1","v3","v4","v5"],"default":"v5","description":"v1 = baseline full pipeline. v3 = lean, v4 = autonomous, v5 = latest/default. For managed stateless predict, v3/v4/v5 share the low-latency single-call planner; sessions, runs, workflows, and BYOK predictions use the selected full engine. Inspect GET /models managed_stateless_predict_mode."},"model":{"type":["string","null"],"enum":["default"],"description":"Managed model alias. For BYOK model selection use llm.model."},"system_prompt":{"type":["string","null"],"maxLength":16000,"description":"Optional custom prompt. Its full length plus trimmed instructions determines the custom-prompt surcharge; exactly the discovered threshold is free."},"instructions":{"type":["string","null"],"maxLength":16000,"description":"Optional appended guidance. Its trimmed length plus system_prompt determines the custom-prompt surcharge; task instruction is excluded."},"screen_width":{"type":["integer","null"],"minimum":320,"maximum":3840,"description":"Omit to use the screenshot's true size (measured server-side); no longer defaults to 1920."},"screen_height":{"type":["integer","null"],"minimum":240,"maximum":2160,"description":"Omit to use the screenshot's true size (measured server-side); no longer defaults to 1080."},"trajectory":{"type":"array","maxItems":19,"description":"Up to 19 prior screenshots; the current screenshot is the 20th provider image. Prior action coordinates use each step's declared dimensions or decoded image dimensions and are normalized server-side. All frames and JSON share the 15 MiB aggregate request cap, so compress or downscale history.","items":{"$ref":"#/components/schemas/TrajectoryStep"}},"max_actions":{"type":"integer","minimum":1,"maximum":10,"default":5},"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"]}},"action_policy":{"$ref":"#/components/schemas/ActionPolicy"},"include_reasoning":{"type":"boolean","default":true},"include_raw_code":{"type":"boolean","default":true},"llm":{"$ref":"#/components/schemas/LlmConfig"}}},"PredictResponse":{"type":"object","required":["request_id","actions","status","usage"],"properties":{"request_id":{"type":"string"},"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"],"description":"Authoritative model loop-control claim. done means the model believes the observed state or the proposed step outcome satisfies the instruction; it may coexist with mutating actions and is not proof of persistence. Execute only admitted actions, capture a fresh post-action screenshot, and verify application state before accepting business completion. fail ends the ordinary loop for this response."},"cua_version":{"type":["string","null"],"description":"Echo: the CUA engine version that actually served this call (e.g. \"v5\")."},"screen_width":{"type":"integer","description":"Echo: the width the server actually used — the coordinate space the returned (x, y) are in."},"screen_height":{"type":"integer","description":"Echo: the height the server actually used — the coordinate space the returned (x, y) are in."},"usage":{"$ref":"#/components/schemas/UsageInfo"}}},"CreateSessionRequest":{"type":"object","additionalProperties":false,"properties":{"cua_version":{"type":"string","enum":["v1","v3","v4","v5"],"default":"v5"},"model":{"type":["string","null"],"enum":["default"],"description":"Managed model alias. For BYOK model selection use llm.model."},"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,"description":"Server-side retained-history ceiling. At prediction time provider image 20 is reserved for the current screenshot, so at most the newest 19 prior screenshots are sent. The trajectory surcharge uses the exact prior screenshots actually included after compaction, not this configured ceiling."},"system_prompt":{"type":["string","null"],"maxLength":16000,"description":"Persisted custom prompt. Its full length plus trimmed instructions determines each Session Predict custom-prompt surcharge."},"instructions":{"type":["string","null"],"maxLength":16000,"description":"Persisted appended guidance. Its trimmed length plus system_prompt determines each Session Predict custom-prompt surcharge."},"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"]}},"action_policy":{"$ref":"#/components/schemas/ActionPolicy"},"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"}}},"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"}}},"SessionPredictRequest":{"type":"object","required":["screenshot","instruction"],"additionalProperties":false,"properties":{"screenshot":{"$ref":"#/components/schemas/ScreenshotBase64"},"instruction":{"type":"string","minLength":1,"maxLength":32000},"include_reasoning":{"type":"boolean","default":true},"include_raw_code":{"type":"boolean","default":true}}},"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"],"description":"Authoritative model loop-control claim for this session step. done may describe the observed state or the proposed step outcome and may coexist with mutating actions; it is not proof of persistence and does not close the session. Execute only admitted actions, capture a fresh post-action screenshot, verify application state, then DELETE or reset the session at the intended flow boundary."},"cua_version":{"type":["string","null"],"description":"Echo: the CUA engine version that actually served this step (e.g. \"v5\")."},"usage":{"$ref":"#/components/schemas/UsageInfo"}}},"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}}},"GroundRequest":{"type":"object","required":["screenshot","element"],"additionalProperties":false,"properties":{"screenshot":{"$ref":"#/components/schemas/ScreenshotBase64"},"element":{"type":"string","minLength":1,"maxLength":32000,"description":"Natural-language description of the UI element."},"screen_width":{"type":["integer","null"],"minimum":320,"maximum":3840,"description":"Omit to use the screenshot's true size (measured server-side); no longer defaults to 1920."},"screen_height":{"type":["integer","null"],"minimum":240,"maximum":2160,"description":"Omit to use the screenshot's true size (measured server-side); no longer defaults to 1080."},"llm":{"$ref":"#/components/schemas/LlmConfig"}}},"GroundResponse":{"type":"object","required":["request_id","x","y","screen_width","screen_height","usage"],"properties":{"request_id":{"type":"string"},"x":{"type":"integer"},"y":{"type":"integer"},"screen_width":{"type":"integer","description":"Echo: the width the server actually used — the coordinate space the returned (x, y) are in."},"screen_height":{"type":"integer","description":"Echo: the height the server actually used — the coordinate space the returned (x, y) are in."},"usage":{"$ref":"#/components/schemas/UsageInfo"}}},"ParseRequest":{"type":"object","required":["code"],"additionalProperties":false,"properties":{"code":{"type":"string","minLength":1,"maxLength":50000,"description":"Raw pyautogui code."},"action_policy":{"$ref":"#/components/schemas/ActionPolicy"}}},"ParseResponse":{"type":"object","required":["actions"],"properties":{"actions":{"type":"array","items":{"$ref":"#/components/schemas/ActionResponse"}}}},"ModelInfo":{"type":"object","required":["id","description"],"properties":{"id":{"type":"string"},"description":{"type":"string"}}},"CUAVersionInfo":{"type":"object","required":["id","description","avg_step_time","features","managed_stateless_predict_mode","latest"],"properties":{"id":{"type":"string"},"description":{"type":"string"},"avg_step_time":{"type":"string"},"features":{"type":"array","items":{"type":"string"}},"managed_stateless_predict_mode":{"type":"string","enum":["full_pipeline","shared_fast_planner"],"description":"Managed-key POST /predict execution path. v3/v4/v5 share the low-latency one-call planner; sessions, runs, workflows, and BYOK predictions use the selected full engine."},"latest":{"type":"boolean","default":false}}},"CreditsByCuaVersion":{"type":"object","additionalProperties":false,"required":["v1","v3","v4","v5"],"properties":{"v1":{"type":"integer","minimum":0},"v3":{"type":"integer","minimum":0},"v4":{"type":"integer","minimum":0},"v5":{"type":"integer","minimum":0}}},"ScheduleExecutionPricingInfo":{"type":"object","additionalProperties":false,"required":["balance_source","credits_per_minute","minimum_balance_credits","billing_rounding","billing_session_max_duration_seconds","scheduler_timeout_seconds","credit_meter_applies_to","unlimited_credit_meter_bypass"],"properties":{"balance_source":{"type":"string","const":"subscription_credits","description":"Live scheduled execution uses the account's subscription-credit balance, not the separate API wallet."},"credits_per_minute":{"type":"integer","minimum":1},"minimum_balance_credits":{"type":"integer","minimum":0},"billing_rounding":{"type":"string","const":"ceil_billable_minutes","description":"Elapsed billable time is rounded up to a whole minute."},"billing_session_max_duration_seconds":{"type":"integer","minimum":1,"description":"Agent-billing safety ceiling; startup rejects a scheduler timeout above it."},"scheduler_timeout_seconds":{"type":"integer","minimum":1,"description":"Effective wall-clock timeout for one scheduled firing."},"credit_meter_applies_to":{"type":"string","const":"non_unlimited_accounts","description":"The subscription-credit tariff and start-balance gate apply to accounts that are not on Unlimited."},"unlimited_credit_meter_bypass":{"type":"boolean","const":true,"description":"Unlimited skips the subscription-credit start gate and deductions; its separate token throttle still applies."}}},"SchedulePricingInfo":{"type":"object","additionalProperties":false,"required":["per_fire_credits","minimum_wallet_balance_cents","webhook_minimum_wallet_balance_cents","webhook_default_rate_limit_per_minute","webhook_replay_window_seconds","webhook_dedup_window_seconds","webhook_max_body_bytes","execution"],"properties":{"per_fire_credits":{"type":"integer","const":0,"description":"Schedule dispatch itself is free."},"minimum_wallet_balance_cents":{"type":"integer","minimum":0,"description":"Managed-model API-wallet gate for schedule creation and run-now; no amount is deducted. BYOK schedules bypass this gate."},"webhook_minimum_wallet_balance_cents":{"type":"integer","minimum":0,"description":"Independently configurable managed-model API-wallet gate for HMAC webhook dispatch; no amount is deducted. BYOK schedules bypass this gate."},"webhook_default_rate_limit_per_minute":{"type":"integer","minimum":1,"description":"Effective default per-webhook fire limit; a trigger may publish a narrower configured limit."},"webhook_replay_window_seconds":{"type":"integer","minimum":1,"description":"Effective allowed absolute clock skew for Coasty-Signature timestamps."},"webhook_dedup_window_seconds":{"type":"integer","minimum":1,"description":"Effective identical webhook-id plus raw-body deduplication window."},"webhook_max_body_bytes":{"type":"integer","minimum":1,"description":"Effective maximum raw webhook request-body size."},"execution":{"$ref":"#/components/schemas/ScheduleExecutionPricingInfo"}}},"RuntimePricingInfo":{"type":"object","additionalProperties":false,"required":["value_kind","published_defaults_path","currency","credit_usd_cents","base_fees_credits","surcharges_credits","long_system_prompt_threshold_chars","run_step_credits","workflow_task_step_credits","schedules","test_keys_bill"],"properties":{"value_kind":{"type":"string","const":"effective_runtime"},"published_defaults_path":{"type":"string","const":"/api/pricing"},"currency":{"type":"string","const":"usd"},"credit_usd_cents":{"type":"integer","const":1},"base_fees_credits":{"type":"object","additionalProperties":false,"required":["predict","session_create","session_predict","ground","parse"],"properties":{"predict":{"type":"integer","minimum":0},"session_create":{"type":"integer","minimum":0},"session_predict":{"type":"integer","minimum":0},"ground":{"type":"integer","minimum":0},"parse":{"type":"integer","minimum":0}}},"surcharges_credits":{"type":"object","additionalProperties":false,"required":["trajectory_screenshot_each","high_resolution_image_each","v1_engine_per_request","long_system_prompt_per_request"],"properties":{"trajectory_screenshot_each":{"type":"integer","minimum":0},"high_resolution_image_each":{"type":"integer","minimum":0},"v1_engine_per_request":{"type":"integer","minimum":0},"long_system_prompt_per_request":{"type":"integer","minimum":0,"description":"Legacy name: Predict/Session Predict fee when combined system_prompt plus trimmed instructions exceeds the threshold; task instruction is excluded."}}},"long_system_prompt_threshold_chars":{"type":"integer","minimum":0,"description":"Legacy name: threshold for combined system_prompt plus trimmed instructions on Predict/Session Predict. Exactly this value is free; task instruction is excluded."},"run_step_credits":{"$ref":"#/components/schemas/CreditsByCuaVersion"},"workflow_task_step_credits":{"$ref":"#/components/schemas/CreditsByCuaVersion"},"schedules":{"$ref":"#/components/schemas/SchedulePricingInfo"},"test_keys_bill":{"type":"boolean","const":false}}},"ModelsResponse":{"type":"object","required":["models","cua_versions","action_types","machine_action_commands","pricing"],"properties":{"models":{"type":"array","items":{"$ref":"#/components/schemas/ModelInfo"}},"cua_versions":{"type":"array","items":{"$ref":"#/components/schemas/CUAVersionInfo"}},"action_types":{"type":"array","items":{"type":"string"}},"machine_action_commands":{"type":"array","minItems":50,"maxItems":50,"uniqueItems":true,"items":{"type":"string","enum":["screenshot","click","double_click","click_with_modifiers","type","key_press","key_combo","scroll","drag","move","list_windows","switch_to_window","close_window","minimize_window","maximize_window","restore_window","arrange_windows","move_window","terminal_connect","terminal_execute","terminal_read","terminal_clear","terminal_close","file_read","file_exists","directory_list","file_write","file_edit","file_append","file_delete","directory_delete","file_download","file_list_downloads","browser_open","browser_navigate","browser_click","browser_type","browser_get_dom","browser_get_clickables","browser_state","browser_info","browser_scroll","browser_close","browser_screenshot","browser_wait","browser_list_tabs","browser_open_tab","browser_close_tab","browser_switch_tab","browser_execute"]},"description":"Exact sorted runtime allowlist for POST /v1/machines/{machine_id}/actions and each batch step. Parameter shapes are discriminated in ActionRequest.oneOf."},"pricing":{"$ref":"#/components/schemas/RuntimePricingInfo","description":"Effective runtime CUA, task-step, and scheduled-execution prices. Compare against /api/pricing defaults before sending billable work."}}},"EndpointUsage":{"type":"object","properties":{"requests":{"type":"integer","default":0},"credits":{"type":"integer","default":0}}},"UsageSummaryResponse":{"type":"object","required":["period"],"properties":{"period":{"type":"string"},"total_requests":{"type":"integer","default":0},"total_credits":{"type":"integer","default":0},"total_cost_cents":{"type":"integer","default":0},"breakdown":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/EndpointUsage"}},"balance":{"type":"integer","default":0},"wallet_balance_cents":{"type":"integer","default":0},"wallet_balance_usd":{"type":"number","default":0}}},"CreateAPIKeyRequest":{"type":"object","required":["name"],"additionalProperties":false,"properties":{"name":{"type":"string","minLength":1,"maxLength":100,"pattern":".*\\S.*"},"scopes":{"type":"array","maxItems":23,"uniqueItems":true,"items":{"type":"string","enum":["predict","session","ground","parse","keys","usage","machines:read","machines:write","actions:exec","terminal:exec","files:read","files:write","browser:execute","snapshots:write","connection:read","schedules:read","schedules:write","triggers:write","runs:read","runs:write","workflows:read","workflows:write","llm_keys"]},"default":["predict","session","ground","parse","usage","machines:read","machines:write","actions:exec","terminal:exec","files:read","files:write","snapshots:write","schedules:read","schedules:write","triggers:write","runs:read","runs:write","workflows:read","workflows:write","llm_keys"],"description":"Omit or send [] for the server default shown here: 20 of the 23 scopes, covering every ordinary product surface (including terminal:exec, files:write, snapshots:write, machines:write, schedules and triggers) so you do not have to discover a scope list before your first call.\n\nExactly THREE scopes are always opt-in, because each is a privilege escalation rather than a product tier and must be requested explicitly:\n- `keys` — mints AND revokes further Coasty API keys (POST /v1/keys, GET /v1/keys, DELETE /v1/keys/{key_id}).\n- `browser:execute` — runs arbitrary JavaScript in the machine's browser session.\n- `connection:read` — returns plaintext connection secrets such as SSH keys.\n\nRequesting a narrower set than the default is supported and recommended for keys you hand to a single service."}}},"APIKeyResponse":{"type":"object","required":["key","key_id","name","tier","scopes","created_at"],"properties":{"key":{"type":"string","description":"The raw API key. Returned ONCE only."},"key_id":{"type":"string"},"name":{"type":"string"},"tier":{"type":"string","enum":["free","starter","professional","enterprise"]},"scopes":{"type":"array","items":{"type":"string"}},"created_at":{"type":"string","format":"date-time"}}},"APIKeyListItem":{"type":"object","required":["key_id","name","tier","scopes","created_at","key_prefix"],"properties":{"key_id":{"type":"string"},"name":{"type":"string"},"tier":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}},"created_at":{"type":"string","format":"date-time"},"last_used_at":{"type":["string","null"],"format":"date-time"},"key_prefix":{"type":"string","description":"Stored 16-character identification prefix; never the full secret."},"key_kind":{"type":["string","null"],"enum":["live","test","legacy"],"description":"Which prefix family this key belongs to: `live` (sk-coasty-live-*), `test` (sk-coasty-test-*, sandbox, never bills), or `legacy` (minted before the split; behaves as live). The listing is scoped to the CALLING key's own mode, so a sandbox key only ever sees sandbox keys and a live key sees live plus legacy."}}},"SessionMutationResponse":{"type":"object","required":["status","session_id"],"properties":{"status":{"type":"string","enum":["ok"]},"session_id":{"type":"string"}}},"RevokeAPIKeyResponse":{"type":"object","required":["status","key_id"],"properties":{"status":{"type":"string","enum":["ok"]},"key_id":{"type":"string"}}},"MachineCapability":{"type":"string","enum":["screenshot","mouse","keyboard","scroll","terminal","files","browser"],"description":"A capability the machine driver can execute. External-machine runs are dispatched only when the enrolled driver advertises every capability required by the task."},"MachineRecord":{"type":"object","required":["id","display_name","status","kind","capabilities","protocol_version","connection_status","last_seen_at"],"properties":{"proxy":{"$ref":"#/components/schemas/MachineProxyView"},"id":{"type":"string"},"display_name":{"type":"string"},"kind":{"type":"string","enum":["managed","external"],"description":"managed is a Coasty-hosted VM; external is a customer-operated driver that supplies frames and executes typed commands."},"capabilities":{"type":"array","uniqueItems":true,"items":{"$ref":"#/components/schemas/MachineCapability"}},"protocol_version":{"type":["string","null"],"description":"External-driver protocol version. null for managed machines."},"connection_status":{"type":["string","null"],"enum":["connected","disconnected","stale","revoked"],"description":"Liveness of an external driver. null for managed machines; separate from the hosted-VM lifecycle status."},"last_seen_at":{"type":["string","null"],"format":"date-time","description":"Most recent authenticated observation, command poll, result, or heartbeat from an external driver."},"status":{"type":"string","enum":["creating","provisioning","starting","running","stopping","stopped","restarting","suspended","deleting","terminated","error"]},"os_type":{"type":"string","enum":["linux","windows"],"default":"linux","description":"Runtime compatibility family. External-driver platform is supplied at enrollment and may be macOS or other even when this compatibility field is linux."},"desktop_enabled":{"type":"boolean","default":false},"cpu_cores":{"type":"integer","default":1},"memory_gb":{"type":"number","default":2},"storage_gb":{"type":"integer","default":10},"public_ip":{"type":["string","null"]},"is_test":{"type":"boolean","default":false},"created_at":{"type":["string","null"],"format":"date-time"},"started_at":{"type":["string","null"],"format":"date-time"},"auto_destroy_at":{"type":["string","null"],"format":"date-time"},"ttl_minutes":{"type":["integer","null"]},"metadata":{"type":"object","additionalProperties":{"type":"string"}},"billing":{"$ref":"#/components/schemas/MachineBilling","description":"How this API-provisioned machine is metered (omitted for non-API machines)."}}},"ExternalMachineEnrollRequest":{"type":"object","required":["display_name","platform","capabilities"],"additionalProperties":false,"properties":{"display_name":{"type":"string","minLength":1,"maxLength":64},"protocol_version":{"type":"string","const":"1","default":"1","description":"Driver protocol major version. Unsupported major versions fail before enrollment."},"capabilities":{"type":"array","minItems":1,"maxItems":7,"uniqueItems":true,"contains":{"const":"screenshot"},"minContains":1,"maxContains":1,"items":{"$ref":"#/components/schemas/MachineCapability"}},"platform":{"type":"string","enum":["windows","macos","linux","other"]},"screen_width":{"type":["integer","null"],"minimum":320,"maximum":3840},"screen_height":{"type":["integer","null"],"minimum":240,"maximum":2160,"description":"screen_width and screen_height must be supplied together when either is present."},"metadata":{"type":"object","maxProperties":16,"propertyNames":{"maxLength":64},"additionalProperties":{"type":"string","maxLength":256},"description":"Non-secret labels only. Never put device credentials or screenshot data in metadata."}}},"ExternalMachineEnrollResponse":{"type":"object","required":["machine","device_token","fencing_token","request_id"],"additionalProperties":false,"properties":{"machine":{"$ref":"#/components/schemas/MachineRecord"},"device_token":{"type":"string","writeOnly":true,"minLength":32,"description":"Machine-scoped bearer credential. It is returned only by the initial enrollment or an exact Idempotency-Key replay while the 24-hour recovery secret remains available; it is never present in list/get responses and must be stored in the driver's secret store."},"fencing_token":{"type":"integer","minimum":1,"description":"Initial device lease generation. Send it on heartbeat and command-result calls."},"request_id":{"type":"string"}}},"ExternalClickCommand":{"type":"object","required":["action_type","params"],"additionalProperties":false,"properties":{"action_type":{"type":"string","const":"click"},"params":{"$ref":"#/components/schemas/PredictionClickParameters"}}},"ExternalTypeTextCommand":{"type":"object","required":["action_type","params"],"additionalProperties":false,"properties":{"action_type":{"type":"string","const":"type_text"},"params":{"$ref":"#/components/schemas/PredictionTypeTextParameters"}}},"ExternalKeyPressCommand":{"type":"object","required":["action_type","params"],"additionalProperties":false,"properties":{"action_type":{"type":"string","const":"key_press"},"params":{"$ref":"#/components/schemas/PredictionKeyPressParameters"}}},"ExternalKeyComboCommand":{"type":"object","required":["action_type","params"],"additionalProperties":false,"properties":{"action_type":{"type":"string","const":"key_combo"},"params":{"$ref":"#/components/schemas/PredictionKeyComboParameters"}}},"ExternalScrollCommand":{"type":"object","required":["action_type","params"],"additionalProperties":false,"properties":{"action_type":{"type":"string","const":"scroll"},"params":{"$ref":"#/components/schemas/PredictionScrollParameters"}}},"ExternalDragCommand":{"type":"object","required":["action_type","params"],"additionalProperties":false,"properties":{"action_type":{"type":"string","const":"drag"},"params":{"$ref":"#/components/schemas/PredictionDragParameters"}}},"ExternalMoveCommand":{"type":"object","required":["action_type","params"],"additionalProperties":false,"properties":{"action_type":{"type":"string","const":"move"},"params":{"$ref":"#/components/schemas/PredictionMoveParameters"}}},"ExternalWaitCommand":{"type":"object","required":["action_type","params"],"additionalProperties":false,"properties":{"action_type":{"type":"string","const":"wait"},"params":{"$ref":"#/components/schemas/PredictionWaitParameters"}}},"ExternalMachineAction":{"oneOf":[{"$ref":"#/components/schemas/ExternalClickCommand"},{"$ref":"#/components/schemas/ExternalTypeTextCommand"},{"$ref":"#/components/schemas/ExternalKeyPressCommand"},{"$ref":"#/components/schemas/ExternalKeyComboCommand"},{"$ref":"#/components/schemas/ExternalScrollCommand"},{"$ref":"#/components/schemas/ExternalDragCommand"},{"$ref":"#/components/schemas/ExternalMoveCommand"},{"$ref":"#/components/schemas/ExternalWaitCommand"}],"discriminator":{"propertyName":"action_type"},"description":"A typed input action. Terminal done/fail signals and model raw_code are never dispatched to an external driver."},"ExternalMachineCommandEnvelope":{"type":"object","required":["id","cursor","protocol_version","command","parameters","deadline_at","fencing_token","precondition_frame_id"],"additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"cursor":{"type":"integer","minimum":1},"protocol_version":{"type":"string","const":"1"},"command":{"type":"string","enum":["screenshot","detect_elements","ocr","click","double_click","click_with_modifiers","drag","move","list_windows","switch_to_window","close_window","minimize_window","maximize_window","restore_window","arrange_windows","move_window","type","key_press","key_combo","scroll","terminal_connect","terminal_execute","terminal_read","terminal_type","terminal_clear","terminal_close","execute_command","execute_terminal_command","file_read","file_exists","directory_list","file_write","file_edit","file_append","file_delete","directory_delete","file_download","file_list_downloads","file_upload","browser_open","browser_connect","browser_navigate","browser_click","browser_type","browser_get_dom","browser_get_clickables","browser_state","browser_info","browser_get_context","browser_scroll","browser_close","browser_screenshot","browser_wait","browser_list_tabs","browser_open_tab","browser_close_tab","browser_switch_tab","browser_execute"],"description":"Canonical, allowlisted device-plane command. Owner actions and internal Task/Workflow CUA execution share this transport. Drivers must implement only the capabilities they advertise; the bundled reference driver intentionally implements the narrower screenshot/mouse/keyboard/scroll subset. raw_code, done, and fail are never sent to a device."},"parameters":{"type":"object","additionalProperties":true,"description":"Command-specific parameters already validated against the canonical ActionRequest schema before dispatch. Drivers must still validate the shape for command and their advertised capabilities before local execution."},"run_id":{"type":["string","null"]},"deadline_at":{"type":"string","format":"date-time"},"fencing_token":{"type":"integer","minimum":1,"description":"Lease generation. Results with an older or mismatched generation are rejected."},"precondition_frame_id":{"type":["string","null"],"format":"uuid","description":"The exact frame on which the action was planned. Do not execute after the visible screen has changed."}}},"ExternalMachineCommandsResponse":{"type":"object","required":["machine_id","data","next_cursor","fencing_token","request_id"],"additionalProperties":false,"properties":{"machine_id":{"type":"string"},"data":{"type":"array","maxItems":50,"items":{"$ref":"#/components/schemas/ExternalMachineCommandEnvelope"}},"next_cursor":{"type":"integer","minimum":0,"description":"Resume with after=next_cursor after durably processing this batch."},"fencing_token":{"type":"integer","minimum":1},"request_id":{"type":"string"}}},"ExternalMachineObservationRequest":{"type":"object","required":["sequence","screenshot","media_type"],"additionalProperties":false,"allOf":[{"if":{"required":["width"]},"then":{"required":["height"]}},{"if":{"required":["height"]},"then":{"required":["width"]}},{"if":{"required":["media_type"],"properties":{"media_type":{"const":"image/png"}}},"then":{"properties":{"screenshot":{"pattern":"^(?:[A-Za-z0-9+/=]+|data:image/png;base64,[A-Za-z0-9+/=]+)$"}}}},{"if":{"required":["media_type"],"properties":{"media_type":{"const":"image/jpeg"}}},"then":{"properties":{"screenshot":{"pattern":"^(?:[A-Za-z0-9+/=]+|data:image/jpeg;base64,[A-Za-z0-9+/=]+)$"}}}}],"properties":{"sequence":{"type":"integer","minimum":1},"media_type":{"type":"string","enum":["image/png","image/jpeg"]},"screenshot":{"$ref":"#/components/schemas/ScreenshotBase64","description":"Base64 PNG/JPEG bytes, either raw or in a data URI that exactly matches media_type. The 100 through 10,485,760 character bounds apply to the base64 payload after the optional prefix. The server decodes the image, verifies media type/dimensions/digest, strips metadata, and never trusts declarations alone."},"sha256":{"type":["string","null"],"pattern":"^[0-9a-f]{64}$","description":"Optional SHA-256 of the submitted decoded image bytes, before metadata stripping and server normalization."},"width":{"type":["integer","null"],"minimum":320,"maximum":3840},"height":{"type":["integer","null"],"minimum":240,"maximum":2160,"description":"width and height must be supplied together when either is present."}}},"ExternalMachineObservationResponse":{"type":"object","required":["machine_id","frame_id","sequence","sha256","width","height","received_at","fencing_token","request_id"],"additionalProperties":false,"properties":{"machine_id":{"type":"string"},"frame_id":{"type":"string","format":"uuid"},"sequence":{"type":"integer"},"sha256":{"type":"string","pattern":"^[0-9a-f]{64}$","description":"SHA-256 of the server-normalized PNG/JPEG bytes. Metadata removal and re-encoding mean this may differ from the request sha256."},"width":{"type":"integer"},"height":{"type":"integer"},"received_at":{"type":"string","format":"date-time"},"fencing_token":{"type":"integer","minimum":1},"request_id":{"type":"string"}}},"ExternalMachineCommandResultRequest":{"type":"object","required":["fencing_token","precondition_frame_id","success"],"additionalProperties":false,"allOf":[{"if":{"required":["success"],"properties":{"success":{"const":true}}},"then":{"properties":{"error":{"type":"null"}}},"else":{"required":["error"],"properties":{"error":{"type":"string","minLength":1,"maxLength":2048,"pattern":"\\S"}}}}],"properties":{"fencing_token":{"type":"integer","minimum":1},"precondition_frame_id":{"type":["string","null"],"format":"uuid","description":"Must exactly echo the command envelope's precondition_frame_id, including null. A mismatch is 409 FRAME_PRECONDITION_MISMATCH."},"success":{"type":"boolean"},"result":{"type":["object","null"],"additionalProperties":true},"error":{"type":["string","null"],"maxLength":2048},"observation":{"anyOf":[{"allOf":[{"$ref":"#/components/schemas/ExternalMachineObservationRequest"}],"description":"Optional post-action frame, atomically accepted with the command result."},{"type":"null"}]}}},"ExternalMachineCommandResultResponse":{"type":"object","required":["machine_id","command_id","status","replayed","request_id"],"additionalProperties":false,"properties":{"machine_id":{"type":"string"},"command_id":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["completed","failed"]},"replayed":{"type":"boolean","description":"true for a byte-equivalent result replay; a conflicting result returns 409."},"request_id":{"type":"string"}}},"ExternalMachineHeartbeatRequest":{"type":"object","required":["fencing_token"],"additionalProperties":false,"properties":{"protocol_version":{"type":"string","const":"1","default":"1"},"fencing_token":{"type":"integer","minimum":1}}},"ExternalMachineHeartbeatResponse":{"type":"object","required":["machine_id","connection_status","last_seen_at","fencing_token","last_sequence","last_frame_id","request_id"],"additionalProperties":false,"properties":{"machine_id":{"type":"string"},"connection_status":{"type":"string","const":"connected"},"last_seen_at":{"type":"string","format":"date-time"},"fencing_token":{"type":"integer","minimum":1},"last_sequence":{"type":"integer","minimum":0,"description":"Authoritative last accepted observation sequence. A restarted driver submits last_sequence + 1."},"last_frame_id":{"type":["string","null"],"format":"uuid","description":"Authoritative last accepted frame, or null before the first observation."},"request_id":{"type":"string"}}},"MachineBilling":{"type":"object","description":"Per-machine runtime billing state. 1 credit = 1 cent.","properties":{"billed_to":{"type":"string","enum":["api_wallet"],"default":"api_wallet"},"running_credits_per_hour":{"type":"integer","description":"Effective API-wallet rate while this machine is running; discover the deployed rate card at GET /v1/machines/pricing."},"stopped_credits_per_hour":{"type":"integer","description":"Effective API-wallet storage rate while stopped/suspended; discover the deployed rate card at GET /v1/machines/pricing."},"accrued_cents":{"type":"integer","description":"Credits owed for the current metering segment so far."},"projected_daily_cents":{"type":"integer","description":"rate_cents_per_hour * 24 — a full day at the current rate."},"since":{"type":["string","null"],"format":"date-time","description":"When the current metering segment started."},"total_credits_billed":{"type":"integer","description":"Lifetime credits this machine has billed."},"suspended_for_billing":{"type":"boolean","description":"true if stopped because the wallet ran dry."},"auto_destroy_at":{"type":["string","null"],"format":"date-time"},"ttl_minutes":{"type":["integer","null"]}}},"BillingActiveItem":{"type":"object","required":["machine_id","display_name","status","os_type","rate_cents_per_hour","running_credits_per_hour","stopped_credits_per_hour","accrued_cents","total_credits_billed","suspended_for_billing"],"properties":{"machine_id":{"type":"string"},"display_name":{"type":"string"},"status":{"type":"string","enum":["running","starting","stopping","restarting","stopped","suspended"]},"os_type":{"type":"string","enum":["linux","windows"]},"rate_cents_per_hour":{"type":"integer","description":"Hourly rate in this machine's current state."},"running_credits_per_hour":{"type":"integer"},"stopped_credits_per_hour":{"type":"integer"},"accrued_cents":{"type":"integer","description":"Cost of the current metering segment so far."},"since":{"type":["string","null"],"format":"date-time","description":"When the current segment started."},"total_credits_billed":{"type":"integer"},"suspended_for_billing":{"type":"boolean"},"auto_destroy_at":{"type":["string","null"],"format":"date-time"},"ttl_minutes":{"type":["integer","null"]}}},"BillingActiveResponse":{"type":"object","required":["active","current_run_rate_cents_per_hour","request_id"],"properties":{"active":{"type":"array","items":{"$ref":"#/components/schemas/BillingActiveItem"},"description":"Every API-billed machine currently metering (running OR stopped). Empty for test-mode keys."},"current_run_rate_cents_per_hour":{"type":"integer","description":"Summed instantaneous burn rate across the active list — total cents/hour right now."},"request_id":{"type":"string"}}},"ConnectionDetailsRedacted":{"type":"object","properties":{"public_ip":{"type":["string","null"]},"ssh_port":{"type":["integer","null"]},"ssh_username":{"type":["string","null"]},"vnc_port":{"type":["integer","null"]},"websocket_port":{"type":["integer","null"]},"has_ssh_key":{"type":"boolean","default":false},"has_vnc_password":{"type":"boolean","default":false}}},"ConnectionDetailsFull":{"type":"object","required":["machine_id","request_id"],"properties":{"machine_id":{"type":"string"},"public_ip":{"type":["string","null"]},"ssh_port":{"type":["integer","null"]},"ssh_username":{"type":["string","null"]},"ssh_private_key_pem":{"type":["string","null"],"description":"ED25519 (Linux) or RSA (Windows) private key. HIGHLY SENSITIVE — store in a secrets manager."},"vnc_port":{"type":["integer","null"]},"vnc_password":{"type":["string","null"]},"websocket_port":{"type":["integer","null"]},"websocket_url":{"type":["string","null"]},"devtools_url":{"type":["string","null"]},"vnc_url":{"type":["string","null"],"description":"When available, a signed, short-lived, INTERACTIVE noVNC desktop URL (targets /vnc.html?autoconnect=1). Open directly in a browser or iframe to view AND control the desktop — no IP/port/password needed. Null when not available for this machine (use public_ip + vnc_port + vnc_password instead). Expires (~1h); re-fetch from this endpoint to refresh."},"screen_width":{"type":["integer","null"],"description":"Actual desktop width, when reported by the machine."},"screen_height":{"type":["integer","null"],"description":"Actual desktop height, when reported by the machine."},"request_id":{"type":"string"}}},"ProxyRequest":{"type":"object","additionalProperties":false,"description":"Route a machine's outbound traffic through a proxy. 'managed' uses Coasty's residential upstream and takes no other fields; 'custom' requires host and port. Omit the object entirely for no proxy.","properties":{"mode":{"type":"string","enum":["none","managed","custom"],"default":"none"},"session":{"type":["string","null"],"enum":["sticky","rotating"],"description":"Managed mode only. 'sticky' (default) holds one exit IP for the machine's lifetime."},"scheme":{"type":["string","null"],"enum":["http","https","socks5"],"description":"Custom mode only. How to reach YOUR PROXY, not what it can carry: an http proxy serves HTTPS sites fine through CONNECT. Use https only when the proxy itself terminates TLS. Defaults to http."},"host":{"type":["string","null"],"maxLength":253,"description":"Custom mode only. Must be a public address; loopback, link-local and private ranges are refused."},"port":{"type":["integer","null"],"minimum":1,"maximum":65535},"username":{"type":["string","null"],"maxLength":512},"password":{"type":["string","null"],"maxLength":512,"description":"Write-only. Encrypted at rest and never returned by any endpoint."}}},"MachineProxyView":{"type":"object","description":"Read-side proxy state. Never contains the credential -- a masked username and a fingerprint only.","properties":{"mode":{"type":"string","enum":["none","managed","custom"]},"scheme":{"type":["string","null"]},"host":{"type":["string","null"]},"port":{"type":["integer","null"]},"status":{"type":["string","null"],"enum":["pending","applying","active","failed","released"]},"authenticated":{"type":["boolean","null"]},"username_masked":{"type":["string","null"]},"credential_fingerprint":{"type":["string","null"]},"egress_ip":{"type":["string","null"],"description":"The address the machine was observed leaving from, once proven."},"verified_at":{"type":["string","null"],"format":"date-time"},"error":{"type":["string","null"]}}},"ProvisionRequest":{"type":"object","required":["display_name"],"additionalProperties":false,"properties":{"display_name":{"type":"string","minLength":1,"maxLength":64},"os_type":{"type":"string","enum":["linux","windows"],"default":"linux"},"desktop_enabled":{"type":"boolean","default":false},"cpu_cores":{"type":["integer","null"],"minimum":1,"maximum":16},"memory_gb":{"type":["integer","null"],"minimum":1,"maximum":64},"storage_gb":{"type":["integer","null"],"minimum":8,"maximum":500},"restore_from_snapshot":{"type":["boolean","null"],"default":false},"ttl_minutes":{"type":["integer","null"],"minimum":5,"maximum":10080,"description":"Optional auto-destroy lease, measured from creation (5 minutes to 7 days)."},"metadata":{"type":"object","additionalProperties":{"type":"string"},"description":"Max 16 entries; keys ≤64 chars, values ≤256 chars."},"proxy":{"$ref":"#/components/schemas/ProxyRequest"}}},"ProvisionResponse":{"type":"object","required":["machine","connection","request_id"],"properties":{"machine":{"$ref":"#/components/schemas/MachineRecord"},"connection":{"$ref":"#/components/schemas/ConnectionDetailsRedacted"},"request_id":{"type":"string"}}},"ListMachinesResponse":{"type":"object","required":["data","request_id"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/MachineRecord"}},"has_more":{"type":"boolean","default":false},"request_id":{"type":"string"}}},"GetMachineResponse":{"type":"object","required":["machine","request_id"],"properties":{"machine":{"$ref":"#/components/schemas/MachineRecord"},"request_id":{"type":"string"}}},"LifecycleResponse":{"type":"object","required":["machine_id","status","message","request_id"],"properties":{"machine_id":{"type":"string"},"status":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"}}},"UpdateMachineRequest":{"type":"object","required":["ttl_minutes"],"additionalProperties":false,"properties":{"ttl_minutes":{"type":"integer","minimum":0,"maximum":10080,"description":"0 clears resource expiry; otherwise the value must be between 5 and 10080. Managed expiry destroys infrastructure; external expiry only revokes and deletes the Coasty registration, leaving caller-owned host/storage untouched.","oneOf":[{"const":0},{"minimum":5,"maximum":10080}]}}},"UpdateMachineResponse":{"type":"object","required":["machine_id","ttl_minutes","auto_destroy_at","request_id"],"properties":{"machine_id":{"type":"string"},"ttl_minutes":{"type":["integer","null"]},"auto_destroy_at":{"type":["string","null"],"format":"date-time"},"request_id":{"type":"string"}}},"MachinePricingResponse":{"type":"object","required":["pricing","request_id"],"additionalProperties":false,"properties":{"pricing":{"type":"object","required":["currency","credit_usd_cents","runtime","one_time","eligibility_gates","external_machines","billing_granularity","billed_to","model","insufficient_funds_behavior","ttl"],"additionalProperties":false,"description":"The live managed-machine and external-machine rate card.","properties":{"currency":{"type":"string","const":"usd"},"credit_usd_cents":{"type":"integer","minimum":1},"runtime":{"type":"object","additionalProperties":true},"one_time":{"type":"object","additionalProperties":true},"eligibility_gates":{"type":"object","required":["provision_minimum_wallet_balance_credits","provision_minimum_wallet_balance_cents","provision_minimum_wallet_balance_usd","note"],"additionalProperties":false,"properties":{"provision_minimum_wallet_balance_credits":{"type":"integer","minimum":0},"provision_minimum_wallet_balance_cents":{"type":"integer","minimum":0},"provision_minimum_wallet_balance_usd":{"type":"number","minimum":0},"note":{"type":"string","const":"Eligibility check only; provisioning does not debit this amount."}}},"external_machines":{"type":"object","required":["enrollment_credits","runtime_credits_per_hour","direct_action_credits","frame_transport_credits","task_and_workflow_steps","note"],"additionalProperties":false,"properties":{"enrollment_credits":{"type":"integer","const":0},"runtime_credits_per_hour":{"type":"integer","const":0},"direct_action_credits":{"type":"integer","const":0},"frame_transport_credits":{"type":"integer","const":0},"task_and_workflow_steps":{"type":"string","const":"managed key: charged at the selected CUA version's normal per-step rate; BYOK: zero Coasty platform credits"},"note":{"type":"string","description":"Caller-owned compute is not provisioned or metered. Task/Workflow model inference uses the managed step meter only when Coasty supplies the model. BYOK debits zero Coasty platform credits; live-key execution is provider-billed. Managed-mode test execution remains deterministic sandbox and makes no provider call; test-auth BYOK intent returns 422 LLM_PROVIDER_UNSUPPORTED before execution."}}},"billing_granularity":{"type":"string"},"billed_to":{"type":"string"},"model":{"type":"string"},"insufficient_funds_behavior":{"type":"string"},"ttl":{"type":"object","additionalProperties":true}}},"request_id":{"type":"string"}}},"SnapshotResponse":{"type":"object","required":["machine_id","snapshot_id","name","created_at","credits_charged","request_id"],"properties":{"machine_id":{"type":"string"},"snapshot_id":{"type":"string"},"name":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"credits_charged":{"type":"integer"},"request_id":{"type":"string"}}},"ScreenshotResponse":{"type":"object","required":["machine_id","image_b64","mime_type","width","height","captured_at","request_id"],"properties":{"machine_id":{"type":"string"},"image_b64":{"type":"string","description":"Base64-encoded screenshot (no data: prefix)."},"mime_type":{"type":"string","default":"image/jpeg"},"width":{"type":"integer"},"height":{"type":"integer"},"captured_at":{"type":"string","format":"date-time"},"frame_id":{"type":["string","null"],"format":"uuid","description":"Opaque external-machine observation identity. Bind the next external action to this value with precondition_frame_id; null for managed machines."},"request_id":{"type":"string"}}},"ActionRequest":{"type":"object","required":["command"],"additionalProperties":false,"oneOf":[{"type":"object","properties":{"command":{"type":"string","const":"screenshot"},"parameters":{"$ref":"#/components/schemas/DirectEmptyParameters"}}},{"type":"object","required":["parameters"],"properties":{"command":{"type":"string","const":"click"},"parameters":{"$ref":"#/components/schemas/DirectClickParameters"}}},{"type":"object","required":["parameters"],"properties":{"command":{"type":"string","const":"double_click"},"parameters":{"$ref":"#/components/schemas/DirectDoubleClickParameters"}}},{"type":"object","required":["parameters"],"properties":{"command":{"type":"string","const":"click_with_modifiers"},"parameters":{"$ref":"#/components/schemas/DirectModifiedClickParameters"}}},{"type":"object","required":["parameters"],"properties":{"command":{"type":"string","const":"type"},"parameters":{"$ref":"#/components/schemas/DirectTypeParameters"}}},{"type":"object","required":["parameters"],"properties":{"command":{"type":"string","const":"key_press"},"parameters":{"$ref":"#/components/schemas/DirectKeyPressParameters"}}},{"type":"object","required":["parameters"],"properties":{"command":{"type":"string","const":"key_combo"},"parameters":{"$ref":"#/components/schemas/DirectKeyComboParameters"}}},{"type":"object","required":["parameters"],"properties":{"command":{"type":"string","const":"scroll"},"parameters":{"$ref":"#/components/schemas/DirectScrollParameters"}}},{"type":"object","required":["parameters"],"properties":{"command":{"type":"string","const":"drag"},"parameters":{"$ref":"#/components/schemas/DirectDragParameters"}}},{"type":"object","required":["parameters"],"properties":{"command":{"type":"string","const":"move"},"parameters":{"$ref":"#/components/schemas/DirectMoveParameters"}}},{"type":"object","properties":{"command":{"type":"string","const":"list_windows"},"parameters":{"$ref":"#/components/schemas/DirectEmptyParameters"}}},{"type":"object","required":["parameters"],"properties":{"command":{"type":"string","const":"switch_to_window"},"parameters":{"$ref":"#/components/schemas/DirectSwitchWindowParameters"}}},{"type":"object","properties":{"command":{"type":"string","const":"close_window"},"parameters":{"$ref":"#/components/schemas/DirectWindowTargetParameters"}}},{"type":"object","properties":{"command":{"type":"string","const":"minimize_window"},"parameters":{"$ref":"#/components/schemas/DirectWindowTargetParameters"}}},{"type":"object","properties":{"command":{"type":"string","const":"maximize_window"},"parameters":{"$ref":"#/components/schemas/DirectWindowTargetParameters"}}},{"type":"object","properties":{"command":{"type":"string","const":"restore_window"},"parameters":{"$ref":"#/components/schemas/DirectWindowTargetParameters"}}},{"type":"object","properties":{"command":{"type":"string","const":"arrange_windows"},"parameters":{"$ref":"#/components/schemas/DirectArrangeWindowsParameters"}}},{"type":"object","required":["parameters"],"properties":{"command":{"type":"string","const":"move_window"},"parameters":{"$ref":"#/components/schemas/DirectMoveWindowParameters"}}},{"type":"object","properties":{"command":{"type":"string","const":"terminal_connect"},"parameters":{"$ref":"#/components/schemas/DirectTerminalConnectParameters"}}},{"type":"object","required":["parameters"],"properties":{"command":{"type":"string","const":"terminal_execute"},"parameters":{"$ref":"#/components/schemas/DirectTerminalExecuteParameters"}}},{"type":"object","properties":{"command":{"type":"string","const":"terminal_read"},"parameters":{"$ref":"#/components/schemas/DirectTerminalSessionParameters"}}},{"type":"object","properties":{"command":{"type":"string","const":"terminal_clear"},"parameters":{"$ref":"#/components/schemas/DirectTerminalSessionParameters"}}},{"type":"object","properties":{"command":{"type":"string","const":"terminal_close"},"parameters":{"$ref":"#/components/schemas/DirectTerminalSessionParameters"}}},{"type":"object","required":["parameters"],"properties":{"command":{"type":"string","const":"file_read"},"parameters":{"$ref":"#/components/schemas/DirectFileReadParameters"}}},{"type":"object","required":["parameters"],"properties":{"command":{"type":"string","const":"file_exists"},"parameters":{"$ref":"#/components/schemas/DirectPathParameters"}}},{"type":"object","properties":{"command":{"type":"string","const":"directory_list"},"parameters":{"$ref":"#/components/schemas/DirectDirectoryParameters"}}},{"type":"object","required":["parameters"],"properties":{"command":{"type":"string","const":"file_write"},"parameters":{"$ref":"#/components/schemas/DirectFileContentParameters"}}},{"type":"object","required":["parameters"],"properties":{"command":{"type":"string","const":"file_edit"},"parameters":{"$ref":"#/components/schemas/DirectFileEditParameters"}}},{"type":"object","required":["parameters"],"properties":{"command":{"type":"string","const":"file_append"},"parameters":{"$ref":"#/components/schemas/DirectFileContentParameters"}}},{"type":"object","required":["parameters"],"properties":{"command":{"type":"string","const":"file_delete"},"parameters":{"$ref":"#/components/schemas/DirectPathParameters"}}},{"type":"object","required":["parameters"],"properties":{"command":{"type":"string","const":"directory_delete"},"parameters":{"$ref":"#/components/schemas/DirectRequiredDirectoryParameters"}}},{"type":"object","required":["parameters"],"properties":{"command":{"type":"string","const":"file_download"},"parameters":{"$ref":"#/components/schemas/DirectFileReadParameters"}}},{"type":"object","properties":{"command":{"type":"string","const":"file_list_downloads"},"parameters":{"$ref":"#/components/schemas/DirectListDownloadsParameters"}}},{"type":"object","properties":{"command":{"type":"string","const":"browser_open"},"parameters":{"$ref":"#/components/schemas/DirectBrowserOptionalUrlParameters"}}},{"type":"object","required":["parameters"],"properties":{"command":{"type":"string","const":"browser_navigate"},"parameters":{"$ref":"#/components/schemas/DirectBrowserUrlParameters"}}},{"type":"object","required":["parameters"],"properties":{"command":{"type":"string","const":"browser_click"},"parameters":{"$ref":"#/components/schemas/DirectBrowserClickParameters"}}},{"type":"object","required":["parameters"],"properties":{"command":{"type":"string","const":"browser_type"},"parameters":{"$ref":"#/components/schemas/DirectBrowserTypeParameters"}}},{"type":"object","properties":{"command":{"type":"string","const":"browser_get_dom"},"parameters":{"$ref":"#/components/schemas/DirectEmptyParameters"}}},{"type":"object","properties":{"command":{"type":"string","const":"browser_get_clickables"},"parameters":{"$ref":"#/components/schemas/DirectEmptyParameters"}}},{"type":"object","properties":{"command":{"type":"string","const":"browser_state"},"parameters":{"$ref":"#/components/schemas/DirectEmptyParameters"}}},{"type":"object","properties":{"command":{"type":"string","const":"browser_info"},"parameters":{"$ref":"#/components/schemas/DirectEmptyParameters"}}},{"type":"object","properties":{"command":{"type":"string","const":"browser_scroll"},"parameters":{"$ref":"#/components/schemas/DirectBrowserScrollParameters"}}},{"type":"object","properties":{"command":{"type":"string","const":"browser_close"},"parameters":{"$ref":"#/components/schemas/DirectEmptyParameters"}}},{"type":"object","properties":{"command":{"type":"string","const":"browser_screenshot"},"parameters":{"$ref":"#/components/schemas/DirectBrowserScreenshotParameters"}}},{"type":"object","properties":{"command":{"type":"string","const":"browser_wait"},"parameters":{"$ref":"#/components/schemas/DirectBrowserWaitParameters"}}},{"type":"object","properties":{"command":{"type":"string","const":"browser_list_tabs"},"parameters":{"$ref":"#/components/schemas/DirectEmptyParameters"}}},{"type":"object","properties":{"command":{"type":"string","const":"browser_open_tab"},"parameters":{"$ref":"#/components/schemas/DirectBrowserOptionalUrlParameters"}}},{"type":"object","properties":{"command":{"type":"string","const":"browser_close_tab"},"parameters":{"$ref":"#/components/schemas/DirectTabIndexParameters"}}},{"type":"object","required":["parameters"],"properties":{"command":{"type":"string","const":"browser_switch_tab"},"parameters":{"$ref":"#/components/schemas/DirectRequiredTabIndexParameters"}}},{"type":"object","required":["parameters"],"properties":{"command":{"type":"string","const":"browser_execute"},"parameters":{"$ref":"#/components/schemas/DirectBrowserExecuteParameters"}}}],"discriminator":{"propertyName":"command"},"description":"A discriminated direct-machine command. parameters is strictly selected by command; unknown keys are rejected before dispatch.","properties":{"command":{"type":"string","enum":["screenshot","click","double_click","click_with_modifiers","type","key_press","key_combo","scroll","drag","move","list_windows","switch_to_window","close_window","minimize_window","maximize_window","restore_window","arrange_windows","move_window","terminal_connect","terminal_execute","terminal_read","terminal_clear","terminal_close","file_read","file_exists","directory_list","file_write","file_edit","file_append","file_delete","directory_delete","file_download","file_list_downloads","browser_open","browser_navigate","browser_click","browser_type","browser_get_dom","browser_get_clickables","browser_state","browser_info","browser_scroll","browser_close","browser_screenshot","browser_wait","browser_list_tabs","browser_open_tab","browser_close_tab","browser_switch_tab","browser_execute"],"description":"Canonical command name. GET /v1/models returns the same list in machine_action_commands for runtime discovery."},"parameters":{"type":"object","description":"Command-specific strict object selected by the command discriminator. Max 1,000,000 serialized UTF-8 JSON bytes."},"timeout_ms":{"type":["integer","null"],"minimum":1000,"maximum":120000},"action_policy":{"$ref":"#/components/schemas/ActionPolicy"},"precondition_frame_id":{"type":["string","null"],"format":"uuid","description":"Required for every mutating external-machine action: the frame_id on which it was planned. A missing or stale frame is rejected instead of executing against changed pixels. Obtain it from GET /screenshot or the preceding action response. Read-only external commands may omit it; managed-machine transports ignore it."}}},"ActionResultResponse":{"type":"object","required":["machine_id","command","success","duration_ms","request_id"],"properties":{"machine_id":{"type":"string"},"command":{"type":"string"},"success":{"type":"boolean"},"result":{"type":["object","null"],"additionalProperties":true},"error":{"type":["string","null"]},"duration_ms":{"type":"integer"},"screenshot":{"type":["string","null"],"description":"Typed post-action screenshot when the transport returns one. External-machine mutations commit this observation atomically with their result. Data URI or raw base64; never duplicated inside result. Screenshot pixels are not persisted in idempotency replay records."},"frame_id":{"type":["string","null"],"format":"uuid","description":"Accepted post-action external observation identity. Use it as the next action's precondition_frame_id."},"observation_available":{"type":["boolean","null"],"description":"Whether screenshot pixels are present in this response. An idempotent replay may retain frame_id while returning screenshot=null and observation_available=false."},"request_id":{"type":"string"}}},"BatchActionRequest":{"type":"object","required":["steps"],"additionalProperties":false,"properties":{"steps":{"type":"array","minItems":1,"maxItems":50,"items":{"$ref":"#/components/schemas/ActionRequest"}},"stop_on_error":{"type":"boolean","default":true},"action_policy":{"$ref":"#/components/schemas/ActionPolicy","description":"Checked atomically against the complete batch before step one. Individual steps may also carry their own action_policy."}}},"BatchActionResponse":{"type":"object","required":["machine_id","results","completed_count","failed_count","request_id"],"properties":{"machine_id":{"type":"string"},"results":{"type":"array","items":{"$ref":"#/components/schemas/ActionResultResponse"}},"completed_count":{"type":"integer"},"failed_count":{"type":"integer"},"aborted":{"type":"boolean","default":false},"request_id":{"type":"string"}}},"BrowserOpRequest":{"type":"object","additionalProperties":false,"properties":{"parameters":{"type":"object","additionalProperties":true},"timeout_ms":{"type":["integer","null"],"minimum":1000,"maximum":120000},"precondition_frame_id":{"type":["string","null"],"format":"uuid","description":"Required when this convenience operation mutates an external machine."}}},"TerminalRequest":{"type":"object","required":["command"],"additionalProperties":false,"properties":{"command":{"type":"string","minLength":1,"maxLength":8192},"timeout_ms":{"type":"integer","minimum":1000,"maximum":120000,"default":30000},"session_id":{"type":["string","null"],"maxLength":128},"cwd":{"type":["string","null"],"maxLength":512},"precondition_frame_id":{"type":["string","null"],"format":"uuid","description":"Required when executing this mutating terminal command on an external machine."}}},"FilesOpRequest":{"type":"object","additionalProperties":false,"properties":{"parameters":{"type":"object","additionalProperties":true,"description":"Op-specific params: {path} for read; {path, content} for write; etc."},"precondition_frame_id":{"type":["string","null"],"format":"uuid","description":"Required for mutating external-machine file operations; optional for reads."}}},"ScheduleResponse":{"type":"object","required":["id","name","machine_id","task_prompt","enabled","frequency","cron","timezone","request_id"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"machine_id":{"type":"string"},"task_prompt":{"type":"string"},"enabled":{"type":"boolean"},"frequency":{"type":"string"},"cron":{"type":"string"},"timezone":{"type":"string"},"next_run_at":{"type":["string","null"],"format":"date-time"},"last_run_at":{"type":["string","null"],"format":"date-time"},"run_count":{"type":"integer","default":0},"consecutive_failures":{"type":"integer","default":0},"paused_reason":{"type":["string","null"]},"is_test":{"type":"boolean","default":false},"created_at":{"type":["string","null"],"format":"date-time"},"metadata":{"type":"object","additionalProperties":{"type":"string"}},"llm":{"description":"Non-secret BYOK schedule preference returned by create/get/list/PATCH/pause/resume, but not by run-history records. Contains provider/model-role selections and the 12-lowercase-hex key fingerprint validated at creation. It never contains a key, ciphertext, or key_source. The preference is immutable through PATCH; each fire resolves the current stored key again, so rotation takes effect on the next fire without recreating the schedule.","oneOf":[{"$ref":"#/components/schemas/ScheduleLlmPreference"},{"type":"null"}]},"request_id":{"type":"string"}}},"ScheduleCronExpression":{"type":"string","maxLength":128,"pattern":"^\\S+(?:\\s+\\S+){4,5}$","description":"A 5- or 6-field cron expression. The server performs full cron parser validation before saving or firing the schedule."},"ScheduleMetadata":{"type":"object","maxProperties":16,"propertyNames":{"maxLength":64},"additionalProperties":{"type":"string","maxLength":256},"description":"Free-form string tags: at most 16 entries, with keys up to 64 characters and values up to 256 characters."},"ScheduleCreateRequest":{"type":"object","required":["name","machine_id","task_prompt"],"additionalProperties":false,"description":"Create exactly one timing mode: a non-custom frequency preset, custom plus a cron expression, or a one-shot run_at date-time.\n\nThe timing refinements (`time`, `day_of_week`, `day_of_month`) are only accepted where the chosen frequency can actually express them. A refinement the frequency cannot carry is a 422 VALIDATION_ERROR, never a silent no-op or a silent reinterpretation. See each field.","properties":{"name":{"type":"string","minLength":1,"maxLength":128},"machine_id":{"type":"string","minLength":1,"maxLength":64},"task_prompt":{"type":"string","minLength":1,"maxLength":8000},"frequency":{"type":["string","null"],"enum":["every_15_minutes","every_30_minutes","hourly","every_6_hours","every_12_hours","daily","weekly","monthly","custom",null]},"cron":{"oneOf":[{"$ref":"#/components/schemas/ScheduleCronExpression"},{"type":"null"}],"description":"Required when frequency is custom; otherwise omit it or use null."},"timezone":{"type":"string","maxLength":64,"default":"UTC","description":"IANA timezone name used for cron evaluation, for example America/Los_Angeles. The server validates it against the runtime IANA timezone database."},"time":{"type":["string","null"],"maxLength":5,"pattern":"^([01]\\d|2[0-3]):[0-5]\\d$","description":"HH:MM 24-hour, evaluated in `timezone`. Valid ONLY for the daily-or-slower presets: daily, weekly, monthly.\n\nSending it with a sub-daily frequency (every_15_minutes, every_30_minutes, hourly, every_6_hours, every_12_hours) returns 422 VALIDATION_ERROR, because applying a time-of-day overwrites the recurrence's minute and hour fields and collapses it into a single daily run. For example {\"frequency\":\"hourly\",\"time\":\"09:30\"} would turn \"0 * * * *\" into \"30 09 * * *\". Use a daily-or-slower preset, or frequency='custom' with an explicit cron.\n\nAlso 422 when combined with frequency='custom': the cron IS the schedule, so encode the timing in the cron expression itself."},"day_of_week":{"type":["integer","null"],"minimum":0,"maximum":6,"description":"0=Monday .. 6=Sunday. Valid ONLY with frequency='weekly'; any other frequency (including 'custom') returns 422 VALIDATION_ERROR. It was previously accepted and silently ignored."},"day_of_month":{"type":["integer","null"],"minimum":1,"maximum":28,"description":"Valid ONLY with frequency='monthly'; any other frequency (including 'custom') returns 422 VALIDATION_ERROR. It was previously accepted and silently ignored. Capped at 28 so a schedule fires in every month."},"run_at":{"oneOf":[{"type":"string","format":"date-time","maxLength":64},{"type":"null"}],"description":"ISO 8601 date-time for a one-shot schedule. At runtime it must be in the future or no more than 60 seconds in the past; a missing timezone offset is interpreted as UTC."},"max_consecutive_failures":{"type":"integer","minimum":1,"maximum":50,"default":5},"metadata":{"oneOf":[{"$ref":"#/components/schemas/ScheduleMetadata"},{"type":"null"}]},"llm":{"$ref":"#/components/schemas/LlmConfig"},"action_policy":{"$ref":"#/components/schemas/ActionPolicy","description":"Immutable policy inherited by every schedule firing, retry, recovery, and nested CUA delegation."}},"oneOf":[{"title":"Recurring preset","required":["frequency"],"properties":{"frequency":{"enum":["every_15_minutes","every_30_minutes","hourly","every_6_hours","every_12_hours","daily","weekly","monthly"]},"cron":{"type":"null"},"run_at":{"type":"null"}}},{"title":"Recurring custom cron","required":["frequency","cron"],"properties":{"frequency":{"const":"custom"},"cron":{"$ref":"#/components/schemas/ScheduleCronExpression"},"run_at":{"type":"null"}}},{"title":"One-shot date-time","required":["run_at"],"properties":{"frequency":{"type":"null"},"cron":{"type":"null"},"run_at":{"type":"string","format":"date-time","maxLength":64}}}]},"ScheduleUpdateRequest":{"type":"object","additionalProperties":false,"description":"Partial schedule update. Supplying cron alone promotes the schedule to frequency=custom; cron with an explicit non-custom frequency is rejected. llm, machine_id, and run_at are intentionally immutable through PATCH; delete and recreate the schedule to change them.\n\nTiming fields are MERGED over stored state, not reset. A PATCH that does not restate `time`, `day_of_week` or `day_of_month` inherits the stored value, so changing only the timezone on a \"daily at 14:30\" job leaves it at 14:30 rather than falling back to the preset default of 09:00. Each selector is inherited only where the target frequency accepts it: `time` for daily/weekly/monthly, `day_of_week` for weekly, `day_of_month` for monthly. Switching frequency therefore drops a selector the new frequency cannot express instead of turning a harmless PATCH into a 422.\n\nThe same acceptance rules as create apply to values you DO send: see each field.","properties":{"name":{"type":"string","minLength":1,"maxLength":128},"task_prompt":{"type":"string","minLength":1,"maxLength":8000},"frequency":{"type":["string","null"],"enum":["every_15_minutes","every_30_minutes","hourly","every_6_hours","every_12_hours","daily","weekly","monthly","custom",null]},"cron":{"oneOf":[{"$ref":"#/components/schemas/ScheduleCronExpression"},{"type":"null"}],"description":"A cron supplied without frequency implies frequency=custom."},"timezone":{"type":["string","null"],"maxLength":64,"description":"IANA timezone name. Non-null values are validated against the runtime IANA timezone database."},"time":{"type":["string","null"],"maxLength":5,"pattern":"^([01]\\d|2[0-3]):[0-5]\\d$","description":"HH:MM in 24-hour format. Accepted only when the effective frequency is daily, weekly or monthly; sending it against a sub-daily preset (every_15_minutes, every_30_minutes, hourly, every_6_hours, every_12_hours) or against frequency='custom' returns 422 VALIDATION_ERROR. Omit it to keep the stored time-of-day."},"day_of_week":{"type":["integer","null"],"minimum":0,"maximum":6,"description":"0=Monday .. 6=Sunday. Accepted only when the effective frequency is 'weekly'; otherwise 422 VALIDATION_ERROR. Omit it to keep the stored day."},"day_of_month":{"type":["integer","null"],"minimum":1,"maximum":28,"description":"Accepted only when the effective frequency is 'monthly'; otherwise 422 VALIDATION_ERROR. Omit it to keep the stored day."},"max_consecutive_failures":{"type":"integer","minimum":1,"maximum":50},"enabled":{"type":"boolean"},"metadata":{"oneOf":[{"$ref":"#/components/schemas/ScheduleMetadata"},{"type":"null"}]}},"not":{"required":["frequency","cron"],"properties":{"frequency":{"enum":["every_15_minutes","every_30_minutes","hourly","every_6_hours","every_12_hours","daily","weekly","monthly"]},"cron":{"$ref":"#/components/schemas/ScheduleCronExpression"}}}},"ListSchedulesResponse":{"type":"object","required":["data","request_id"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ScheduleResponse"}},"has_more":{"type":"boolean","default":false},"request_id":{"type":"string"}}},"ScheduleRunRecord":{"type":"object","description":"Durable execution history. It deliberately omits the schedule llm preference, provider credentials, prompts, screenshots, and provider-token totals; read the ScheduleResponse for its non-secret configured preference.","required":["id","schedule_id","status","trigger","executed_at"],"properties":{"id":{"type":"string"},"schedule_id":{"type":"string"},"status":{"type":"string","enum":["queued","running","completed","failed","skipped","cancelled","insufficient_credits"]},"trigger":{"type":"string","enum":["cron","manual","triggered","webhook","email","run_at"]},"duration_seconds":{"type":["integer","null"]},"credits_charged":{"type":["integer","null"],"minimum":0,"description":"Consumer subscription-credit quota units charged for scheduled execution, not Developer API wallet cents. Zero for test, Unlimited-bypass, and other non-billable runs; no fixed USD conversion."},"error":{"type":["string","null"]},"executed_at":{"type":"string","format":"date-time"}}},"ListScheduleRunsResponse":{"type":"object","required":["data","request_id"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ScheduleRunRecord"}},"next_cursor":{"type":["string","null"]},"has_more":{"type":"boolean","default":false},"request_id":{"type":"string"}}},"RunScheduleRequest":{"type":"object","additionalProperties":false,"properties":{"task_prompt_override":{"type":["string","null"],"maxLength":8000},"triggered_context":{"type":["object","null"],"additionalProperties":true,"description":"Free-form context injected into the agent's prompt. Max 1 MB serialized."}}},"RunScheduleResponse":{"type":"object","required":["schedule_id","run_id","status","message","request_id"],"properties":{"schedule_id":{"type":"string"},"run_id":{"type":"string"},"status":{"type":"string","enum":["running","queued","skipped","completed"]},"message":{"type":"string"},"request_id":{"type":"string"}}},"TriggerCreateRequest":{"type":"object","required":["kind"],"additionalProperties":false,"properties":{"kind":{"type":"string","enum":["webhook","chain"]},"source_schedule_id":{"type":["string","null"],"maxLength":64},"event":{"type":"string","enum":["on_complete","on_failure","on_any"],"default":"on_complete"},"pass_output":{"type":"boolean","default":true},"rate_limit_per_minute":{"type":"integer","minimum":1,"maximum":600,"default":60},"enabled":{"type":"boolean","default":true}}},"TriggerResponse":{"type":"object","required":["id","schedule_id","kind","enabled","created_at"],"properties":{"id":{"type":"string"},"schedule_id":{"type":"string"},"kind":{"type":"string"},"enabled":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"},"webhook_url":{"type":["string","null"]},"webhook_secret":{"type":["string","null"],"description":"HMAC secret. Returned on creation and identical idempotent replays. Stored only as versioned AES-GCM ciphertext."},"email_address":{"type":["string","null"]},"source_schedule_id":{"type":["string","null"]},"event":{"type":["string","null"]}}},"TriggerListItem":{"type":"object","required":["id","schedule_id","kind","enabled","created_at"],"description":"Persisted trigger view. webhook_secret is returned only by creation or its exact bounded Idempotency-Key replay and is deliberately absent from GET/list views.","properties":{"id":{"type":"string"},"schedule_id":{"type":"string"},"kind":{"type":"string"},"enabled":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"},"webhook_url":{"type":["string","null"]},"email_address":{"type":["string","null"]},"source_schedule_id":{"type":["string","null"]},"event":{"type":["string","null"]}}},"ListTriggersResponse":{"type":"object","required":["data","request_id"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/TriggerListItem"}},"request_id":{"type":"string"}}},"WebhookFireResponse":{"type":"object","required":["received","schedule_id","message","request_id"],"properties":{"received":{"type":"boolean"},"schedule_id":{"type":"string"},"run_id":{"type":["string","null"]},"deduplicated":{"type":"boolean","default":false},"message":{"type":"string"},"request_id":{"type":"string"}}},"HealthResponse":{"type":"object","required":["status"],"properties":{"status":{"type":"string","enum":["ok"]},"api_version":{"type":"string"},"service":{"type":"string"}}},"AutonomousMachineRequest":{"type":"object","additionalProperties":false,"properties":{"provider":{"type":"string","enum":["auto","aws","daytona","azure"],"default":"auto","description":"Which backend runs this task's machine. 'auto' (default) lets Coasty choose: a desktop or Windows task goes to Daytona, falling back to AWS when Daytona is disabled; a headless task goes to Azure. Pin 'aws' or 'daytona' to force one. The choice is part of the run's idempotency identity, so a replay lands on the same backend rather than silently migrating."},"os_type":{"type":"string","enum":["linux","windows"],"default":"linux"},"desktop_enabled":{"type":"boolean","default":true},"cpu_cores":{"type":"integer","minimum":1,"maximum":16},"memory_gb":{"type":"integer","minimum":1,"maximum":64},"storage_gb":{"type":"integer","minimum":8,"maximum":500},"restore_from_snapshot":{"type":"boolean","default":false},"proxy":{"$ref":"#/components/schemas/ProxyRequest"}},"description":"Optional workload preferences. Coasty creates the machine, assigns a fail-safe TTL, and destroys it after any terminal outcome. Leave `provider` unset to let Coasty choose the backend, or pin one."},"AutonomousTaskRequest":{"type":"object","required":["task"],"additionalProperties":false,"properties":{"task":{"type":"string","minLength":1,"maxLength":16000},"cua_version":{"type":"string","enum":["v1","v3","v4","v5"],"default":"v5"},"instructions":{"type":["string","null"],"maxLength":16000},"system_prompt":{"type":["string","null"],"maxLength":32000},"model":{"type":["string","null"],"minLength":1,"maxLength":256,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:/+@-]{0,255}$"},"max_steps":{"type":"integer","minimum":1,"maximum":1000,"default":150},"action_policy":{"$ref":"#/components/schemas/ActionPolicy"},"deadline_seconds":{"type":["integer","null"],"minimum":1,"maximum":86400},"webhook_url":{"type":["string","null"],"maxLength":2048},"metadata":{"type":["object","null"],"additionalProperties":true},"llm":{"$ref":"#/components/schemas/LlmConfig"},"machine":{"$ref":"#/components/schemas/AutonomousMachineRequest"}}},"RunRequest":{"type":"object","required":["machine_id","task"],"additionalProperties":false,"properties":{"machine_id":{"type":"string","minLength":1,"maxLength":128,"description":"Target managed or connected external machine id (must be owned by the key's user)."},"task":{"type":"string","minLength":1,"maxLength":16000,"description":"Natural-language task to drive to completion."},"cua_version":{"type":"string","enum":["v1","v3","v4","v5"],"default":"v5","description":"CUA engine version. Defaults to the latest (v5); available on all tiers."},"instructions":{"type":["string","null"],"maxLength":16000,"description":"Appended to the base agent prompt."},"system_prompt":{"type":["string","null"],"maxLength":32000,"description":"Custom preamble prepended to the task; it does not replace the built-in tool-aware agent system prompt. Shares the tier custom-prompt budget with instructions."},"model":{"type":["string","null"],"minLength":1,"maxLength":256,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:/+@-]{0,255}$","description":"Legacy top-level model selection (prefer llm.model for BYOK). Model ids are 1-256 characters, begin with a letter or number, and then use only letters, numbers, dot, underscore, colon, slash, plus, at-sign, or hyphen. Secret-shaped values such as sk-* keys, bearer credentials, authorization values, or API-key/secret assignments are rejected without reflection as 422 LLM_MODEL_INVALID; provider credentials belong only in X-LLM-Api-Key."},"max_steps":{"type":"integer","minimum":1,"maximum":1000,"default":150,"description":"Hard cap on agent steps (clamped to the server ceiling)."},"action_policy":{"$ref":"#/components/schemas/ActionPolicy","description":"Immutable policy inherited by the complete task execution tree, including nested delegation and worker recovery."},"deadline_seconds":{"type":["integer","null"],"minimum":1,"maximum":86400,"description":"Wall-clock budget in seconds (clamped)."},"on_awaiting_human":{"type":"string","enum":["pause","fail","cancel"],"default":"pause","description":"Behaviour when the agent needs a human."},"awaiting_human_timeout_seconds":{"type":["integer","null"],"minimum":1,"maximum":86400},"webhook_url":{"type":["string","null"],"maxLength":2048,"description":"HTTPS URL for HMAC-signed run-event deliveries."},"metadata":{"type":["object","null"],"additionalProperties":true,"description":"Opaque key/value map echoed back (≤50 keys)."},"llm":{"$ref":"#/components/schemas/LlmConfig"}}},"RunResponse":{"type":"object","required":["id","object","status"],"properties":{"id":{"type":"string"},"object":{"type":"string","enum":["agent.run"]},"status":{"type":"string","enum":["queued","running","awaiting_human","succeeded","failed","cancelled","timed_out"]},"machine_id":{"type":["string","null"]},"machine":{"type":["object","null"],"additionalProperties":false,"properties":{"mode":{"type":"string","enum":["automatic"]},"status":{"type":"string","enum":["provisioning","starting","reconciling","ready","terminated","cleanup_failed"],"description":"Lifecycle of the ephemeral machine Coasty created for this run. `starting` means the provider handle and billing record are durable but the desktop may still be booting; execution readiness is verified separately before the agent is allowed to start. `reconciling` means a provisioning outcome is being recovered from the provider journal, and the run keeps its lease while that resolves. `cleanup_failed` means the run reached a terminal outcome but teardown did not confirm."},"id":{"type":["string","null"]},"cleanup":{"type":"string","enum":["always"]},"cleanup_status":{"type":"string","enum":["pending","terminating","retrying","terminated"]},"error":{"type":"object","additionalProperties":true}}},"task":{"type":"string"},"cua_version":{"type":"string"},"instructions":{"type":["string","null"]},"max_steps":{"type":"integer"},"deadline_seconds":{"type":"integer","description":"EFFECTIVE wall-clock budget after the server applied its ceiling. Echoed back so a clamp is never silent: request 86400 against a lower server ceiling and you see the value the run is actually held to, instead of discovering it as a surprise DEADLINE_EXCEEDED."},"awaiting_human_timeout_seconds":{"type":"integer","description":"EFFECTIVE awaiting-human timeout after the server applied its ceiling, echoed back for the same reason as deadline_seconds."},"on_awaiting_human":{"type":"string"},"steps_completed":{"type":"integer"},"credits_charged":{"type":"integer"},"cost_cents":{"type":"integer"},"result":{"type":["object","null"],"additionalProperties":true,"description":"Terminal outcome envelope: `passed` (boolean), `status`, `summary`, `usage`, and `verdict` only when a verifier pass ran. `summary` is the LAST 2000 characters of the trajectory, so it carries the agent's final answer; it is not the full trajectory and there is no `output` field. To read a complete trajectory, or a final answer you intend to parse, use GET /v1/runs/{run_id}/log."},"error":{"type":["object","null"],"additionalProperties":true},"awaiting_human_reason":{"type":["string","null"]},"metadata":{"type":["object","null"],"additionalProperties":true},"llm":{"description":"Non-secret BYOK echo when the run opted into the caller's own key: {provider, model, key_fingerprint, key_source, key_scrubbed}. key_source is 'stored' or 'header'; key_scrubbed flips to true when the encrypted snapshot is destroyed at terminal state. Never contains the key.","oneOf":[{"$ref":"#/components/schemas/RunLlmInfo"},{"type":"null"}]},"webhook_url":{"type":["string","null"],"description":"Lifecycle callback destination. Agent Run terminal callbacks are transactionally queued in a durable outbox and delivered at least once, with at most 3 durably recorded delivery attempts. A crash after HTTP send but before durable acknowledgement can add duplicate physical sends. Stable Coasty-Delivery equals body id and logical delivered_at survives retries; receivers must deduplicate it. The non-terminal awaiting-human callback is best-effort in-process, can be missed on a worker failure, and uses (run.id, event, run.awaiting_human_since) for deduplication. GET the run for authoritative state."},"webhook_secret":{"type":["string","null"],"description":"Returned by create and its exact bounded Idempotency-Key replay; null on get/list. The pinned per-run secret is encrypted at rest through delivery/replay recovery and later scrubbed. Verify raw-body deliveries with HMAC-SHA256 before accepting the Coasty-Delivery deduplication key."},"created_at":{"type":["string","null"]},"started_at":{"type":["string","null"]},"awaiting_human_since":{"type":["string","null"]},"finished_at":{"type":["string","null"]},"request_id":{"type":["string","null"]}}},"ListRunsResponse":{"type":"object","required":["object","data"],"properties":{"object":{"type":"string","enum":["list"]},"data":{"type":"array","items":{"$ref":"#/components/schemas/RunResponse"}},"has_more":{"type":"boolean","default":false},"request_id":{"type":"string"}}},"RunScreenshot":{"type":"object","required":["index","attempt","step"],"properties":{"index":{"type":"integer","description":"Flat, monotonic position across the whole run. The stable address for a frame: `step` restarts at 1 on a retried attempt, so it is not unique on its own."},"attempt":{"type":"integer","description":"Which execution attempt produced this frame (1, 2, 3…). A run that was reaped and reclaimed has more than one."},"step":{"type":"integer","description":"Step number within that attempt."},"taken_at":{"type":["string","null"],"format":"date-time"},"width":{"type":"integer","description":"Model coordinate-space width — what the agent's clicks were computed against, not necessarily the machine's physical resolution."},"height":{"type":"integer"},"mime_type":{"type":"string","default":"image/png"},"size_bytes":{"type":"integer","description":"Plaintext frame size."},"sha256":{"type":["string","null"],"description":"SHA-256 of the plaintext frame, for dedup and integrity."},"degraded":{"type":"boolean","default":false,"description":"True when capture failed and the agent had to act on a reused or placeholder frame."},"encrypted_at_rest":{"type":"boolean","default":false},"image_b64":{"type":["string","null"],"description":"Base64 PNG. Present only with include_image=true."},"image_unavailable":{"type":["boolean","null"],"description":"Set instead of image_b64 when a stored frame could not be decoded. One bad frame never fails the page."}}},"ListRunScreenshotsResponse":{"type":"object","required":["object","data"],"properties":{"object":{"type":"string","enum":["list"]},"data":{"type":"array","items":{"$ref":"#/components/schemas/RunScreenshot"}},"has_more":{"type":"boolean","default":false},"request_id":{"type":"string"}}},"ResumeRunRequest":{"type":"object","additionalProperties":false,"properties":{"note":{"type":["string","null"],"maxLength":2000,"description":"Recorded on the run timeline."}}},"RunEvent":{"type":"object","description":"One entry from a run's append-only event log, as returned in JSON by GET /v1/runs/{run_id}/log.\n\nOver SSE the same entry is split across the frame rather than sent as this object: `id:` carries `seq`, the event name carries `type`, and the `data:` field carries ONLY the inner `data` payload. Do not expect `seq` or `type` inside a parsed SSE `data:` body.","properties":{"seq":{"type":"integer","description":"Monotonic cursor; pass via Last-Event-ID or ?after= to resume an SSE stream."},"type":{"type":"string","description":"Event type (e.g. status, step, awaiting_human, done)."},"data":{"type":"object","additionalProperties":true},"created_at":{"type":["string","null"],"format":"date-time"}}},"RunAction":{"type":"object","required":["seq","tool"],"description":"One thing the agent did to the machine, and whether it worked.","properties":{"seq":{"type":"integer"},"tool":{"type":"string","description":"The action/tool name invoked."},"args":{"type":"object","additionalProperties":true,"description":"Arguments as executed, including coordinates."},"ok":{"type":["boolean","null"],"description":"The outcome the agent observed. null when the run ended before the result was recorded: a step cut off by a deadline or a crash has a call with no result, and reporting that as a failure would be a guess. An action in flight is genuinely different from one that failed."},"error":{"type":["string","null"],"description":"Present only when the agent reported a failure reason."}}},"RunStepDetail":{"type":"object","description":"Everything that happened in one agent step, already assembled. The underlying store is a flat event log; the reasoning text in particular arrives wrapped in <cua-section> markup, and this view has already unwrapped it.","properties":{"step":{"type":"integer"},"attempt":{"type":"integer","default":1,"description":"A run that was reaped and re-claimed restarts its step counter at 1, so `step` alone is not a unique address within a run. Pair it with `attempt`."},"started_at":{"type":["string","null"],"format":"date-time"},"ended_at":{"type":["string","null"],"format":"date-time"},"analysis":{"type":["string","null"],"description":"The model's own account of what it was looking at, unwrapped from its <cua-section> markup. Any reasoning section may be absent."},"next_action":{"type":["string","null"]},"grounded_action":{"type":["string","null"]},"action_result":{"type":["string","null"],"description":"What the screen actually did in response, as the agent recorded it (e.g. \"Double-clicked at (70, 527)\" or \"no screen change detected\"). The most useful field for diagnosing a stuck run: it is where \"the click landed but nothing happened\" becomes visible."},"actions":{"type":"array","items":{"$ref":"#/components/schemas/RunAction"},"description":"Every tool call in this step, in order, with coordinates and outcome."},"credits_charged":{"type":"integer","default":0},"cost_cents":{"type":"integer","default":0},"screenshot_index":{"type":["integer","null"],"description":"Flat index into GET /v1/runs/{run_id}/screenshots for the frame the agent saw BEFORE acting, when one was captured for this step."},"error":{"type":["string","null"]},"events":{"type":["array","null"],"items":{"$ref":"#/components/schemas/RunEvent"},"description":"The raw events this step was folded from. Present only with include_events=true. Nested under the step rather than returned as a parallel array, so a page boundary can never split a step from its events."}}},"ListRunLogResponse":{"type":"object","required":["object","data"],"description":"The assembled log for one run: one record per agent step, plus the run-level events that belong to no step.","properties":{"object":{"type":"string","enum":["list"]},"data":{"type":"array","items":{"$ref":"#/components/schemas/RunStepDetail"}},"lifecycle":{"type":"array","items":{"$ref":"#/components/schemas/RunEvent"},"description":"Events that belong to the run rather than to any step: queued/running/done transitions, run-level errors, awaiting-human pauses. A step-shaped view would silently drop these, and they are usually the ones that explain why a run stopped. Returned whole on every page because it is small."},"has_more":{"type":"boolean","default":false},"next_after_step":{"type":["integer","null"],"description":"Cursor: pass as after_step to continue. null when the log is complete."},"live":{"type":"boolean","default":false,"description":"True when the run is still going, so the log will grow."},"steps_completed":{"type":"integer","default":0,"description":"Authoritative count from the run record: how many steps actually ran. Trust this over the length of `data`."},"steps_logged":{"type":"integer","default":0,"description":"How many steps this log could reconstruct any evidence for."},"log_complete":{"type":"boolean","default":true,"description":"False when the log is missing steps the run is known to have executed. The event log is BEST EFFORT: appends are not part of the run's transaction, so a step can execute and be billed while its log rows are lost. When this is false, `steps_completed` is authoritative and the absence of a step here is NOT evidence that it did not happen."},"request_id":{"type":"string"}}},"WorkflowBinaryCondition":{"type":"object","required":["op","left","right"],"additionalProperties":false,"properties":{"op":{"type":"string","enum":["eq","ne","lt","gt","lte","gte","contains"]},"left":{"description":"A finite JSON literal or a {{dotted.path}} variable reference."},"right":{"description":"A finite JSON literal or a {{dotted.path}} variable reference."}}},"WorkflowUnaryCondition":{"type":"object","required":["op","value"],"additionalProperties":false,"properties":{"op":{"type":"string","enum":["truthy","falsy","exists"]},"value":{"description":"A finite JSON literal or a {{dotted.path}} variable reference."}}},"WorkflowLogicalCondition":{"type":"object","required":["op","conditions"],"additionalProperties":false,"properties":{"op":{"type":"string","enum":["and","or"]},"conditions":{"type":"array","minItems":1,"items":{"$ref":"#/components/schemas/WorkflowCondition"}}}},"WorkflowNotCondition":{"type":"object","required":["op","condition"],"additionalProperties":false,"properties":{"op":{"type":"string","const":"not"},"condition":{"$ref":"#/components/schemas/WorkflowCondition"}}},"WorkflowCondition":{"description":"Injection-safe structured condition. Free-text expressions and executable code are not accepted. The server also enforces the configured recursive condition-depth ceiling.","oneOf":[{"$ref":"#/components/schemas/WorkflowBinaryCondition"},{"$ref":"#/components/schemas/WorkflowUnaryCondition"},{"$ref":"#/components/schemas/WorkflowLogicalCondition"},{"$ref":"#/components/schemas/WorkflowNotCondition"}],"discriminator":{"propertyName":"op","mapping":{"eq":"#/components/schemas/WorkflowBinaryCondition","ne":"#/components/schemas/WorkflowBinaryCondition","lt":"#/components/schemas/WorkflowBinaryCondition","gt":"#/components/schemas/WorkflowBinaryCondition","lte":"#/components/schemas/WorkflowBinaryCondition","gte":"#/components/schemas/WorkflowBinaryCondition","contains":"#/components/schemas/WorkflowBinaryCondition","truthy":"#/components/schemas/WorkflowUnaryCondition","falsy":"#/components/schemas/WorkflowUnaryCondition","exists":"#/components/schemas/WorkflowUnaryCondition","and":"#/components/schemas/WorkflowLogicalCondition","or":"#/components/schemas/WorkflowLogicalCondition","not":"#/components/schemas/WorkflowNotCondition"}}},"WorkflowTaskStep":{"type":"object","required":["id","type","task"],"additionalProperties":false,"properties":{"id":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,64}$"},"type":{"type":"string","const":"task"},"task":{"type":"string","minLength":1,"maxLength":20000,"pattern":"\\S","description":"Non-blank task text. Supports {{dotted.path}} substitutions."},"machine_id":{"type":["string","null"],"minLength":1,"maxLength":128,"pattern":"\\S","description":"Optional per-step managed or connected external machine override."},"cua_version":{"type":["string","null"],"enum":["v1","v3","v4","v5",null],"description":"Omit or use null for the latest version (v5)."},"instructions":{"type":["string","null"],"maxLength":20000},"system_prompt":{"type":["string","null"],"maxLength":20000},"max_steps":{"type":["integer","null"],"minimum":1,"maximum":1000},"save_as":{"type":["string","null"],"pattern":"^[A-Za-z_][A-Za-z0-9_]{0,63}$","not":{"enum":["inputs","vars"]},"description":"Result binding name; inputs and vars are reserved namespaces."},"on_awaiting_human":{"type":["string","null"],"enum":["pause","fail","cancel",null]},"continue_on_failure":{"type":["boolean","null"]}}},"WorkflowAssertStep":{"type":"object","required":["id","type","condition"],"additionalProperties":false,"properties":{"id":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,64}$"},"type":{"type":"string","const":"assert"},"condition":{"$ref":"#/components/schemas/WorkflowCondition"},"message":{"type":["string","null"],"maxLength":4000}}},"WorkflowIfStep":{"type":"object","required":["id","type","condition","then"],"additionalProperties":false,"properties":{"id":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,64}$"},"type":{"type":"string","const":"if"},"condition":{"$ref":"#/components/schemas/WorkflowCondition"},"then":{"$ref":"#/components/schemas/WorkflowStepList"},"else":{"oneOf":[{"$ref":"#/components/schemas/WorkflowStepList"},{"type":"null"}]}}},"WorkflowLoopStep":{"type":"object","required":["id","type","body"],"additionalProperties":false,"properties":{"id":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,64}$"},"type":{"type":"string","const":"loop"},"count":{"type":["integer","null"],"minimum":0},"while":{"oneOf":[{"$ref":"#/components/schemas/WorkflowCondition"},{"type":"null"}]},"body":{"$ref":"#/components/schemas/WorkflowStepList"},"max_iterations":{"type":["integer","null"],"minimum":1}},"oneOf":[{"required":["count"],"properties":{"count":{"type":"integer"},"while":{"type":"null"}}},{"required":["while"],"properties":{"count":{"type":"null"},"while":{"$ref":"#/components/schemas/WorkflowCondition"}}}]},"WorkflowParallelStep":{"type":"object","required":["id","type","branches"],"additionalProperties":false,"properties":{"id":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,64}$"},"type":{"type":"string","const":"parallel"},"branches":{"type":"array","minItems":1,"maxItems":16,"items":{"$ref":"#/components/schemas/WorkflowParallelBranchStepList"}}}},"WorkflowHumanApprovalStep":{"type":"object","required":["id","type"],"additionalProperties":false,"properties":{"id":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,64}$"},"type":{"type":"string","const":"human_approval"},"message":{"type":["string","null"],"maxLength":4000},"timeout_seconds":{"type":["integer","null"],"minimum":1,"maximum":86400}}},"WorkflowRetryStep":{"type":"object","required":["id","type","body","max_attempts"],"additionalProperties":false,"properties":{"id":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,64}$"},"type":{"type":"string","const":"retry"},"body":{"$ref":"#/components/schemas/WorkflowStepList"},"max_attempts":{"type":"integer","minimum":1,"maximum":20}}},"WorkflowSucceedStep":{"type":"object","required":["id","type"],"additionalProperties":false,"properties":{"id":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,64}$"},"type":{"type":"string","const":"succeed"},"output":{"type":["object","null"],"additionalProperties":true}}},"WorkflowFailStep":{"type":"object","required":["id","type"],"additionalProperties":false,"properties":{"id":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,64}$"},"type":{"type":"string","const":"fail"},"message":{"type":["string","null"],"maxLength":4000}}},"WorkflowStep":{"oneOf":[{"$ref":"#/components/schemas/WorkflowTaskStep"},{"$ref":"#/components/schemas/WorkflowAssertStep"},{"$ref":"#/components/schemas/WorkflowIfStep"},{"$ref":"#/components/schemas/WorkflowLoopStep"},{"$ref":"#/components/schemas/WorkflowParallelStep"},{"$ref":"#/components/schemas/WorkflowHumanApprovalStep"},{"$ref":"#/components/schemas/WorkflowRetryStep"},{"$ref":"#/components/schemas/WorkflowSucceedStep"},{"$ref":"#/components/schemas/WorkflowFailStep"}],"discriminator":{"propertyName":"type","mapping":{"task":"#/components/schemas/WorkflowTaskStep","assert":"#/components/schemas/WorkflowAssertStep","if":"#/components/schemas/WorkflowIfStep","loop":"#/components/schemas/WorkflowLoopStep","parallel":"#/components/schemas/WorkflowParallelStep","human_approval":"#/components/schemas/WorkflowHumanApprovalStep","retry":"#/components/schemas/WorkflowRetryStep","succeed":"#/components/schemas/WorkflowSucceedStep","fail":"#/components/schemas/WorkflowFailStep"}}},"WorkflowStepList":{"type":"array","minItems":1,"maxItems":200,"items":{"$ref":"#/components/schemas/WorkflowStep"}},"WorkflowParallelBranchIfStep":{"type":"object","required":["id","type","condition","then"],"additionalProperties":false,"properties":{"id":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,64}$"},"type":{"type":"string","const":"if"},"condition":{"$ref":"#/components/schemas/WorkflowCondition"},"then":{"$ref":"#/components/schemas/WorkflowParallelBranchStepList"},"else":{"oneOf":[{"$ref":"#/components/schemas/WorkflowParallelBranchStepList"},{"type":"null"}]}}},"WorkflowParallelBranchLoopStep":{"type":"object","required":["id","type","body"],"additionalProperties":false,"properties":{"id":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,64}$"},"type":{"type":"string","const":"loop"},"count":{"type":["integer","null"],"minimum":0},"while":{"oneOf":[{"$ref":"#/components/schemas/WorkflowCondition"},{"type":"null"}]},"body":{"$ref":"#/components/schemas/WorkflowParallelBranchStepList"},"max_iterations":{"type":["integer","null"],"minimum":1}},"oneOf":[{"required":["count"],"properties":{"count":{"type":"integer"},"while":{"type":"null"}}},{"required":["while"],"properties":{"count":{"type":"null"},"while":{"$ref":"#/components/schemas/WorkflowCondition"}}}]},"WorkflowParallelBranchRetryStep":{"type":"object","required":["id","type","body","max_attempts"],"additionalProperties":false,"properties":{"id":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,64}$"},"type":{"type":"string","const":"retry"},"body":{"$ref":"#/components/schemas/WorkflowParallelBranchStepList"},"max_attempts":{"type":"integer","minimum":1,"maximum":20}}},"WorkflowParallelBranchStep":{"description":"Parallel-safe step. human_approval, succeed, and fail are forbidden at every depth inside a parallel branch because they mutate the whole workflow state.","oneOf":[{"$ref":"#/components/schemas/WorkflowTaskStep"},{"$ref":"#/components/schemas/WorkflowAssertStep"},{"$ref":"#/components/schemas/WorkflowParallelBranchIfStep"},{"$ref":"#/components/schemas/WorkflowParallelBranchLoopStep"},{"$ref":"#/components/schemas/WorkflowParallelStep"},{"$ref":"#/components/schemas/WorkflowParallelBranchRetryStep"}],"discriminator":{"propertyName":"type","mapping":{"task":"#/components/schemas/WorkflowTaskStep","assert":"#/components/schemas/WorkflowAssertStep","if":"#/components/schemas/WorkflowParallelBranchIfStep","loop":"#/components/schemas/WorkflowParallelBranchLoopStep","parallel":"#/components/schemas/WorkflowParallelStep","retry":"#/components/schemas/WorkflowParallelBranchRetryStep"}}},"WorkflowParallelBranchStepList":{"type":"array","minItems":1,"maxItems":200,"items":{"$ref":"#/components/schemas/WorkflowParallelBranchStep"}},"WorkflowDefinition":{"type":"object","required":["steps"],"additionalProperties":false,"description":"Workflow DSL version 2026-06-01. The schema encodes each strict step shape and recursive body. The server additionally enforces globally unique step ids, a configurable aggregate step count, definition byte size, and recursive workflow/output depth.","properties":{"steps":{"$ref":"#/components/schemas/WorkflowStepList"},"output":{"type":["object","null"],"additionalProperties":true}}},"WorkflowInputDeclaration":{"type":"object","additionalProperties":false,"properties":{"type":{"type":"string","enum":["any","string","integer","number","boolean","object","array","null"],"default":"any"},"required":{"type":"boolean","default":false},"default":{"description":"Finite JSON default; when type is present this must match it."},"description":{"type":"string","maxLength":2000}},"allOf":[{"if":{"required":["type"],"properties":{"type":{"const":"string"}}},"then":{"properties":{"default":{"type":"string"}}}},{"if":{"required":["type"],"properties":{"type":{"const":"integer"}}},"then":{"properties":{"default":{"type":"integer"}}}},{"if":{"required":["type"],"properties":{"type":{"const":"number"}}},"then":{"properties":{"default":{"type":"number"}}}},{"if":{"required":["type"],"properties":{"type":{"const":"boolean"}}},"then":{"properties":{"default":{"type":"boolean"}}}},{"if":{"required":["type"],"properties":{"type":{"const":"object"}}},"then":{"properties":{"default":{"type":"object"}}}},{"if":{"required":["type"],"properties":{"type":{"const":"array"}}},"then":{"properties":{"default":{"type":"array"}}}},{"if":{"required":["type"],"properties":{"type":{"const":"null"}}},"then":{"properties":{"default":{"type":"null"}}}}]},"WorkflowInputsSchema":{"type":"object","propertyNames":{"pattern":"^[A-Za-z_][A-Za-z0-9_]{0,63}$"},"additionalProperties":{"$ref":"#/components/schemas/WorkflowInputDeclaration"},"description":"Typed input declarations. The server also enforces the configured serialized byte ceiling."},"WorkflowCreateRequest":{"type":"object","required":["name","slug","definition"],"additionalProperties":false,"properties":{"name":{"type":"string","minLength":1,"maxLength":128},"slug":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-z0-9][a-z0-9_-]{0,62}$","description":"Stable handle."},"definition":{"$ref":"#/components/schemas/WorkflowDefinition"},"inputs_schema":{"oneOf":[{"$ref":"#/components/schemas/WorkflowInputsSchema"},{"type":"null"}]},"description":{"type":["string","null"],"maxLength":2000},"metadata":{"type":["object","null"],"additionalProperties":true}}},"WorkflowUpdateRequest":{"type":"object","minProperties":1,"additionalProperties":false,"anyOf":[{"required":["name"],"properties":{"name":{"not":{"type":"null"}}}},{"required":["definition"],"properties":{"definition":{"not":{"type":"null"}}}},{"required":["inputs_schema"],"properties":{"inputs_schema":{"not":{"type":"null"}}}},{"required":["description"],"properties":{"description":{"not":{"type":"null"}}}},{"required":["status"],"properties":{"status":{"not":{"type":"null"}}}},{"required":["metadata"],"properties":{"metadata":{"not":{"type":"null"}}}}],"properties":{"name":{"type":["string","null"],"minLength":1,"maxLength":128},"definition":{"oneOf":[{"$ref":"#/components/schemas/WorkflowDefinition"},{"type":"null"}]},"inputs_schema":{"oneOf":[{"$ref":"#/components/schemas/WorkflowInputsSchema"},{"type":"null"}]},"description":{"type":["string","null"],"maxLength":2000},"status":{"type":["string","null"],"enum":["active","archived",null]},"metadata":{"type":["object","null"],"additionalProperties":true}}},"DeleteTriggerResponse":{"type":"object","required":["deleted","trigger_id","request_id"],"properties":{"deleted":{"type":"boolean"},"trigger_id":{"type":"string"},"request_id":{"type":"string"}}},"DeleteScheduleResponse":{"type":"object","required":["deleted","schedule_id","request_id"],"properties":{"deleted":{"type":"boolean"},"schedule_id":{"type":"string"},"request_id":{"type":"string"}}},"WorkflowResponse":{"type":"object","required":["id","object","name","slug","version"],"properties":{"id":{"type":"string"},"object":{"type":"string","enum":["workflow"]},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"integer"},"dsl_version":{"type":"string","default":"2026-06-01"},"definition":{"$ref":"#/components/schemas/WorkflowDefinition"},"inputs_schema":{"$ref":"#/components/schemas/WorkflowInputsSchema"},"description":{"type":["string","null"]},"status":{"type":"string","enum":["active","archived"],"default":"active"},"metadata":{"type":["object","null"],"additionalProperties":true},"created_at":{"type":["string","null"]},"updated_at":{"type":["string","null"]},"request_id":{"type":["string","null"]}}},"ListWorkflowsResponse":{"type":"object","required":["object","data"],"properties":{"object":{"type":"string","enum":["list"]},"data":{"type":"array","items":{"$ref":"#/components/schemas/WorkflowResponse"}},"has_more":{"type":"boolean","default":false},"request_id":{"type":"string"}}},"StartWorkflowRunRequest":{"type":"object","additionalProperties":false,"properties":{"inputs":{"type":["object","null"],"additionalProperties":true,"description":"Bound input values."},"machine_id":{"type":["string","null"],"maxLength":128,"description":"Default managed or connected external machine for task steps."},"budget_cents":{"type":["integer","null"],"minimum":0,"maximum":10000000,"description":"Hard spend cap across all task steps; 0 or null = unlimited."},"max_iterations":{"type":["integer","null"],"minimum":1,"maximum":100000},"deadline_seconds":{"type":["integer","null"],"minimum":1,"maximum":86400},"webhook_url":{"type":["string","null"],"maxLength":2048},"metadata":{"type":["object","null"],"additionalProperties":true},"definition":{"description":"Inline DSL for an ad-hoc run (POST /v1/workflows/runs). Omit when running a saved workflow.","oneOf":[{"$ref":"#/components/schemas/WorkflowDefinition"},{"type":"null"}]},"inputs_schema":{"description":"Ad-hoc runs only.","oneOf":[{"$ref":"#/components/schemas/WorkflowInputsSchema"},{"type":"null"}]},"llm":{"$ref":"#/components/schemas/LlmConfig"},"action_policy":{"$ref":"#/components/schemas/ActionPolicy","description":"Create-time policy inherited by every workflow task step, retry, recovery, and nested CUA delegation."}}},"StartAdhocWorkflowRunRequest":{"allOf":[{"$ref":"#/components/schemas/StartWorkflowRunRequest"},{"required":["definition"],"properties":{"definition":{"$ref":"#/components/schemas/WorkflowDefinition"}}}]},"WorkflowRunResponse":{"type":"object","required":["id","object","status"],"properties":{"id":{"type":"string"},"object":{"type":"string","enum":["workflow.run"]},"status":{"type":"string","enum":["queued","running","awaiting_human","succeeded","failed","cancelled","timed_out"]},"workflow_id":{"type":["string","null"]},"workflow_version":{"type":["integer","null"]},"machine_id":{"type":["string","null"]},"inputs":{"type":"object","additionalProperties":true},"output":{"type":["object","null"],"additionalProperties":true},"error":{"type":["object","null"],"additionalProperties":true},"awaiting_human_reason":{"type":["string","null"]},"awaiting_step_id":{"type":["string","null"]},"iterations_used":{"type":"integer"},"spent_cents":{"type":"integer"},"budget_cents":{"type":["integer","null"]},"llm":{"description":"Non-secret BYOK echo for the workflow-run snapshot. It contains only provider, model, a 12-lowercase-hex key fingerprint, key source, and terminal scrub state. It never contains the key or ciphertext.","oneOf":[{"$ref":"#/components/schemas/RunLlmInfo"},{"type":"null"}]},"webhook_url":{"type":["string","null"],"description":"Workflow lifecycle callback destination. Workflow callbacks are best-effort in-process notifications (up to 3 attempts), have no durable delivery UUID/outbox, and can be missed if the worker fails. Reconcile with GET /v1/workflows/runs/{run_id}."},"webhook_secret":{"type":["string","null"],"description":"Returned by create and its exact bounded Idempotency-Key replay; null on get/list. The pinned per-run secret is encrypted at rest through delivery/replay recovery and later scrubbed."},"metadata":{"type":["object","null"],"additionalProperties":true},"created_at":{"type":["string","null"]},"started_at":{"type":["string","null"]},"finished_at":{"type":["string","null"]},"request_id":{"type":["string","null"]}}},"ListWorkflowRunsResponse":{"type":"object","required":["object","data"],"properties":{"object":{"type":"string","enum":["list"]},"data":{"type":"array","items":{"$ref":"#/components/schemas/WorkflowRunResponse"}},"has_more":{"type":"boolean","default":false},"request_id":{"type":"string"}}},"ResumeWorkflowRunRequest":{"type":"object","additionalProperties":false,"properties":{"approved":{"type":"boolean","default":true,"description":"Approve (continue) or reject (fail) the pending human_approval step."},"note":{"type":["string","null"],"maxLength":2000}}},"WorkflowDeleteResponse":{"type":"object","required":["id","object","deleted"],"properties":{"id":{"type":"string"},"object":{"type":"string","enum":["workflow"]},"deleted":{"type":"boolean","enum":[true]},"request_id":{"type":"string"}}},"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":256,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:/+@-]{0,255}$","description":"Main worker model. Defaults: claude-sonnet-5 (anthropic), gpt-5.6-sol (openai). Model ids are 1-256 characters, begin with a letter or number, and then use only letters, numbers, dot, underscore, colon, slash, plus, at-sign, or hyphen; invalid ids return 422 LLM_MODEL_INVALID. The selected provider can still reject an unknown or inaccessible model. It must be vision-capable."},"grounding_model":{"type":["string","null"],"minLength":1,"maxLength":256,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:/+@-]{0,255}$","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":256,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:/+@-]{0,255}$","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":256,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:/+@-]{0,255}$","description":"Override for the code agent. Defaults to model."}}},"RunLlmInfo":{"type":"object","additionalProperties":false,"required":["provider","model","key_fingerprint","key_source","key_scrubbed"],"properties":{"provider":{"type":"string","enum":["anthropic","openai"]},"model":{"type":"string","minLength":1,"maxLength":256,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:/+@-]{0,255}$"},"key_fingerprint":{"type":"string","minLength":12,"maxLength":12,"pattern":"^[0-9a-f]{12}$"},"key_source":{"type":"string","enum":["header","stored"]},"key_scrubbed":{"type":"boolean"}},"description":"Credential-free BYOK attribution returned by agent runs and workflow runs. Only these allowlisted fields are public."},"ScheduleLlmPreference":{"type":"object","additionalProperties":false,"required":["provider","model","key_fingerprint"],"properties":{"provider":{"type":"string","enum":["anthropic","openai"]},"model":{"type":"string","minLength":1,"maxLength":256,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:/+@-]{0,255}$"},"grounding_model":{"type":["string","null"],"minLength":1,"maxLength":256,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:/+@-]{0,255}$"},"compaction_model":{"type":["string","null"],"minLength":1,"maxLength":256,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:/+@-]{0,255}$"},"code_agent_model":{"type":["string","null"],"minLength":1,"maxLength":256,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:/+@-]{0,255}$"},"key_fingerprint":{"type":"string","minLength":12,"maxLength":12,"pattern":"^[0-9a-f]{12}$"}},"description":"Credential-free schedule preference. The schedule never stores a provider key or ciphertext; the current stored key is resolved at every fire."},"StoreLlmKeyRequest":{"type":"object","required":["api_key"],"additionalProperties":false,"properties":{"api_key":{"type":"string","minLength":16,"maxLength":512,"description":"Your own provider API key (sk-ant-... for anthropic, sk-... for openai). AES-256-GCM encrypted at rest; never returned or logged."}}},"StoreLlmKeyResponse":{"type":"object","required":["provider","key_fingerprint","stored"],"properties":{"provider":{"type":"string","enum":["anthropic","openai"]},"key_fingerprint":{"type":"string","minLength":12,"maxLength":12,"pattern":"^[0-9a-f]{12}$","description":"Non-secret 12-lowercase-hex SHA-256 prefix fingerprint of the stored key. The key itself is never returned again."},"stored":{"type":"boolean","enum":[true]}}},"LlmKeyListItem":{"type":"object","required":["provider","key_fingerprint"],"properties":{"provider":{"type":"string","enum":["anthropic","openai"]},"key_fingerprint":{"type":"string","minLength":12,"maxLength":12,"pattern":"^[0-9a-f]{12}$"},"created_at":{"type":["string","null"]},"updated_at":{"type":["string","null"]}}},"ListLlmKeysResponse":{"type":"object","required":["keys"],"properties":{"keys":{"type":"array","items":{"$ref":"#/components/schemas/LlmKeyListItem"}}}},"DeleteLlmKeyResponse":{"type":"object","required":["deleted"],"properties":{"deleted":{"type":"boolean","enum":[true]}}}},"responses":{"BadRequest":{"description":"Invalid request body or parameters.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"},"X-Credits-Charged":{"$ref":"#/components/headers/CreditsCharged"},"X-Credits-Refunded":{"$ref":"#/components/headers/CreditsRefunded"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"VALIDATION_ERROR","message":"An error occurred. See `code` for details.","type":"validation_error","request_id":"req_a1b2c3d4e5f6","retryable":false,"retry_with_same_idempotency_key":false}}}}},"Unauthorized":{"description":"Missing, invalid, or revoked API key. Pass `X-API-Key: sk-coasty-live-...` (or test).","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"},"X-Credits-Charged":{"$ref":"#/components/headers/CreditsCharged"},"X-Credits-Refunded":{"$ref":"#/components/headers/CreditsRefunded"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"INVALID_API_KEY","message":"An error occurred. See `code` for details.","type":"validation_error","request_id":"req_a1b2c3d4e5f6","retryable":false,"retry_with_same_idempotency_key":false}}}}},"DeviceUnauthorized":{"description":"Missing, malformed, revoked, or machine-mismatched external device token. Pass the one-time machine token as `Authorization: Bearer <device_token>`; owner API keys are not accepted on device-plane routes. Revoked tokens may return DEVICE_REVOKED.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"},"X-Credits-Charged":{"$ref":"#/components/headers/CreditsCharged"},"X-Credits-Refunded":{"$ref":"#/components/headers/CreditsRefunded"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"INVALID_DEVICE_TOKEN","message":"An error occurred. See `code` for details.","type":"validation_error","request_id":"req_a1b2c3d4e5f6","retryable":false,"retry_with_same_idempotency_key":false}}}}},"WebhookUnauthorized":{"description":"Missing, malformed, stale, or invalid Coasty-Signature HMAC for this webhook payload.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"},"X-Credits-Charged":{"$ref":"#/components/headers/CreditsCharged"},"X-Credits-Refunded":{"$ref":"#/components/headers/CreditsRefunded"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"INVALID_SIGNATURE","message":"An error occurred. See `code` for details.","type":"validation_error","request_id":"req_a1b2c3d4e5f6","retryable":false,"retry_with_same_idempotency_key":false}}}}},"Forbidden":{"description":"API key lacks the required scope or tier-feature is unavailable on the caller's plan.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"},"X-Credits-Charged":{"$ref":"#/components/headers/CreditsCharged"},"X-Credits-Refunded":{"$ref":"#/components/headers/CreditsRefunded"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"INSUFFICIENT_SCOPE","message":"An error occurred. See `code` for details.","type":"validation_error","request_id":"req_a1b2c3d4e5f6","retryable":false,"retry_with_same_idempotency_key":false}}}}},"NotFound":{"description":"Resource not found in this key's namespace.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"},"X-Credits-Charged":{"$ref":"#/components/headers/CreditsCharged"},"X-Credits-Refunded":{"$ref":"#/components/headers/CreditsRefunded"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"NOT_FOUND","message":"An error occurred. See `code` for details.","type":"validation_error","request_id":"req_a1b2c3d4e5f6","retryable":false,"retry_with_same_idempotency_key":false}}}}},"PaymentRequired":{"description":"Insufficient balance for this operation. Direct metered API calls and managed-machine runtime use the prepaid Developer API wallet; scheduled execution is the documented consumer subscription-credit exception. Follow the operation's billing fields and top up the matching balance in the dashboard.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"},"X-Credits-Charged":{"$ref":"#/components/headers/CreditsCharged"},"X-Credits-Refunded":{"$ref":"#/components/headers/CreditsRefunded"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"INSUFFICIENT_CREDITS","message":"An error occurred. See `code` for details.","type":"validation_error","request_id":"req_a1b2c3d4e5f6","retryable":false,"retry_with_same_idempotency_key":false}}}}},"Conflict":{"description":"The resource state conflicts with this operation.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"},"X-Credits-Charged":{"$ref":"#/components/headers/CreditsCharged"},"X-Credits-Refunded":{"$ref":"#/components/headers/CreditsRefunded"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"CONFLICT","message":"An error occurred. See `code` for details.","type":"validation_error","request_id":"req_a1b2c3d4e5f6","retryable":false,"retry_with_same_idempotency_key":false}}}}},"PayloadTooLarge":{"description":"The request body exceeds the endpoint limit.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"},"X-Credits-Charged":{"$ref":"#/components/headers/CreditsCharged"},"X-Credits-Refunded":{"$ref":"#/components/headers/CreditsRefunded"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"PAYLOAD_TOO_LARGE","message":"An error occurred. See `code` for details.","type":"validation_error","request_id":"req_a1b2c3d4e5f6","retryable":false,"retry_with_same_idempotency_key":false}}}}},"UnprocessableEntity":{"description":"The JSON shape is valid but one or more values violate the endpoint contract.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"},"X-Credits-Charged":{"$ref":"#/components/headers/CreditsCharged"},"X-Credits-Refunded":{"$ref":"#/components/headers/CreditsRefunded"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"VALIDATION_ERROR","message":"An error occurred. See `code` for details.","type":"validation_error","request_id":"req_a1b2c3d4e5f6","retryable":false,"retry_with_same_idempotency_key":false}}}}},"RateLimited":{"description":"Rate or concurrency limit exceeded.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"},"X-Credits-Charged":{"$ref":"#/components/headers/CreditsCharged"},"X-Credits-Refunded":{"$ref":"#/components/headers/CreditsRefunded"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"RATE_LIMIT_EXCEEDED","message":"An error occurred. See `code` for details.","type":"validation_error","request_id":"req_a1b2c3d4e5f6","retryable":false,"retry_with_same_idempotency_key":false}}}}},"BadGateway":{"description":"An upstream dependency returned an invalid response.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"},"X-Credits-Charged":{"$ref":"#/components/headers/CreditsCharged"},"X-Credits-Refunded":{"$ref":"#/components/headers/CreditsRefunded"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"UPSTREAM_ERROR","message":"An error occurred. See `code` for details.","type":"validation_error","request_id":"req_a1b2c3d4e5f6","retryable":false,"retry_with_same_idempotency_key":false}}}}},"ServiceUnavailable":{"description":"A required service is temporarily unavailable.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"},"X-Credits-Charged":{"$ref":"#/components/headers/CreditsCharged"},"X-Credits-Refunded":{"$ref":"#/components/headers/CreditsRefunded"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"SERVICE_UNAVAILABLE","message":"An error occurred. See `code` for details.","type":"validation_error","request_id":"req_a1b2c3d4e5f6","retryable":false,"retry_with_same_idempotency_key":false}}}}},"GatewayTimeout":{"description":"An upstream dependency timed out.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"},"X-Credits-Charged":{"$ref":"#/components/headers/CreditsCharged"},"X-Credits-Refunded":{"$ref":"#/components/headers/CreditsRefunded"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"UPSTREAM_TIMEOUT","message":"An error occurred. See `code` for details.","type":"validation_error","request_id":"req_a1b2c3d4e5f6","retryable":false,"retry_with_same_idempotency_key":false}}}}},"ServerError":{"description":"Unexpected server error. Retry with exponential backoff.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-Coasty-Request-Id":{"$ref":"#/components/headers/CoastyRequestId"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"},"X-Credits-Charged":{"$ref":"#/components/headers/CreditsCharged"},"X-Credits-Refunded":{"$ref":"#/components/headers/CreditsRefunded"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"INTERNAL_ERROR","message":"An error occurred. See `code` for details.","type":"validation_error","request_id":"req_a1b2c3d4e5f6","retryable":false,"retry_with_same_idempotency_key":false}}}}}},"parameters":{"IdempotencyKey":{"name":"Idempotency-Key","in":"header","required":false,"description":"Optional client-supplied key (≤128 chars, [A-Za-z0-9_-:]) for safe retries. Keys are global within one concrete API-key credential plus live/test mode; never reuse one on another endpoint. 'Same request' = a SHA-256 of an explicit operation discriminator plus the canonical (sorted-key) JSON body (session_id is folded in for /sessions/{id}/predict). LLM-capable operations also bind the non-secret effective provider, role models, and one-way provider-key fingerprint; plaintext provider keys never enter the hash or replay record. Replays the response for 24 h when operation, body, and effective execution identity match (X-Coasty-Idempotent-Replay: true and X-Credits-Charged: 0). Action screenshot pixels are response-only and deliberately omitted from replay storage; a replay retains frame_id but returns screenshot=null and observation_available=false. Inference replays also set body usage.credits_charged=0 and usage.billed=false; machine-snapshot bodies retain the original gross charge for auditability. A retry while the original is still running waits up to ~25 s then returns the result, otherwise 409 IDEMPOTENCY_IN_FLIGHT (retry with the SAME key). Returns 422 IDEMPOTENCY_KEY_REUSED if any bound input differs. Rotating the API key starts a new replay namespace. Collect a lost result via GET /v1/idempotency/{key} using the original credential.","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9_\\-:]+$"},"examples":{"uuid":{"value":"550e8400-e29b-41d4-a716-446655440000"}}},"RequiredIdempotencyKey":{"name":"Idempotency-Key","in":"header","required":true,"description":"Required for external-machine enrollment. Reuse the same key with the identical canonical body to recover the committed 201 response without creating another machine. Reuse with a different body is rejected.","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9_\\-:]+$"},"examples":{"uuid":{"value":"550e8400-e29b-41d4-a716-446655440000"}}},"XLLMProvider":{"name":"X-LLM-Provider","in":"header","required":false,"description":"BYOK: which provider the X-LLM-Api-Key belongs to (anthropic | openai). Required whenever X-LLM-Api-Key is sent — a key without a provider is a 422 LLM_PROVIDER_UNSUPPORTED. With a live Coasty key, selecting BYOK runs the entire harness on your provider account with no platform fallback and zero Coasty inference credits. Under test auth, predict, ground, and session create require an explicit per-request X-LLM-Api-Key; a body provider without that header fails with 422 LLM_KEY_NOT_CONFIGURED because test auth never reads a stored live provider key. Session create fixes the explicit key for inherited predicts without inference. Managed-mode Tasks, Workflows, and schedules remain deterministic sandbox executions; BYOK intent on them fails before execution with 422 LLM_PROVIDER_UNSUPPORTED. They never decrypt or require a stored provider key and make no provider call.","schema":{"type":"string","enum":["anthropic","openai"]}},"XLLMApiKey":{"name":"X-LLM-Api-Key","in":"header","required":false,"description":"BYOK provider credential supplied on this request. Lifecycle depends on the operation: predict/ground use it for that call; session create retains a fixed owner-process copy for inherited predicts; Run/Workflow creation snapshots it encrypted until terminal state; schedule create uses it only to validate the current stored key and persists no credential. It requires an effective anthropic/openai provider; combining it with body llm.provider='managed' is 422. Under live auth, immediate operations prefer this header over a stored key. Schedules fire without headers, so the header key must match the stored key and each fire resolves the current stored key. Never logged or echoed. With a test Coasty key, explicit BYOK is provider-direct only for the direct CUA flow: POST /v1/predict, POST /v1/ground, POST /v1/sessions, and POST /v1/sessions/{id}/predict. Predict, ground, and session create require this explicit per-request header plus X-LLM-Provider; body llm.provider without it returns 422 LLM_KEY_NOT_CONFIGURED (Stored provider keys are unavailable for test API keys. Send X-LLM-Api-Key explicitly for direct BYOK.) and test auth never reads or uses a stored live provider key. Session create fixes the explicit key for inherited session predicts but makes no inference call; predict, ground, and session predict can call and bill Anthropic/OpenAI. Managed-mode test Tasks, Workflows, and schedules remain deterministic sandbox. Supplying BYOK headers or provider metadata to them returns 422 LLM_PROVIDER_UNSUPPORTED (BYOK is unavailable for synthetic test runs, workflows, and schedules. Use managed mode or a live Coasty API key.) before execution. They never decrypt or require a stored provider key and do not call or bill Anthropic/OpenAI. Keep provider secrets out of sandbox and CI requests; use a live Coasty key for real asynchronous execution.","schema":{"type":"string","minLength":16,"maxLength":512}},"XLLMModel":{"name":"X-LLM-Model","in":"header","required":false,"description":"BYOK model selection for this operation (equivalent to body llm.model). Sessions retain it for inherited predicts, Runs/Workflows snapshot it, and schedules persist the non-secret selection for later fires. Defaults: claude-sonnet-5 (anthropic), gpt-5.6-sol (openai). The same 1-256-character model-id syntax applies; invalid ids return 422 LLM_MODEL_INVALID. The provider can still reject an unknown or inaccessible model; it must be vision-capable.","schema":{"type":"string","minLength":1,"maxLength":256,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:/+@-]{0,255}$"}},"MachineId":{"name":"machine_id","in":"path","required":true,"description":"Machine UUID, or `mch_test_<8-32 lowercase hex>` for sandbox/test-mode keys.","schema":{"type":"string","pattern":"^(?:[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}|mch_test_[0-9a-f]{8,32})$"}},"ExternalCommandId":{"name":"command_id","in":"path","required":true,"description":"Command id returned by GET /commands. Use it verbatim; it is scoped to this machine.","schema":{"type":"string","format":"uuid"}},"ExternalCommandAfter":{"name":"after","in":"query","required":false,"description":"Exclusive durable cursor. Use the previous response's next_cursor to resume without gaps.","schema":{"type":"integer","minimum":0,"default":0}},"ExternalCommandLimit":{"name":"limit","in":"query","required":false,"description":"Maximum queued commands returned in one batch.","schema":{"type":"integer","minimum":1,"maximum":50,"default":10}},"ExternalCommandWaitSeconds":{"name":"wait_seconds","in":"query","required":false,"description":"Long-poll duration. A timeout is a 200 response with data=[] and a resumable next_cursor.","schema":{"type":"number","minimum":0,"maximum":25,"default":20}},"ScheduleId":{"name":"schedule_id","in":"path","required":true,"description":"Schedule UUID, or `sch_test_<8-32 lowercase hex>` for sandbox keys.","schema":{"type":"string","pattern":"^(?:[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}|sch_test_[0-9a-f]{8,32})$"}},"TriggerId":{"name":"trigger_id","in":"path","required":true,"schema":{"type":"string","pattern":"^trg_[0-9a-f]{8,32}$"}},"WebhookId":{"name":"webhook_id","in":"path","required":true,"schema":{"type":"string","pattern":"^whk_[0-9a-f]{8,48}$"}},"SessionId":{"name":"session_id","in":"path","required":true,"description":"Stateful CUA session identifier (1-128 URL-safe characters).","schema":{"type":"string","minLength":1,"maxLength":128,"pattern":"^[A-Za-z0-9_-]+$"}},"IdempotencyKeyPath":{"name":"key","in":"path","required":true,"description":"The Idempotency-Key whose result you want to collect (≤128 chars, [A-Za-z0-9_-:]).","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9_\\-:]+$"}},"RunId":{"name":"run_id","in":"path","required":true,"description":"Run UUID (also used for workflow runs).","schema":{"type":"string","format":"uuid"}},"LastEventId":{"name":"Last-Event-ID","in":"header","required":false,"description":"Last processed SSE sequence number. Reconnect with this value to resume without gaps.","schema":{"type":"integer","minimum":0}},"WorkflowId":{"name":"workflow_id","in":"path","required":true,"description":"Workflow UUID.","schema":{"type":"string","format":"uuid"}}},"headers":{"RequestId":{"description":"Conventional correlation-ID alias for the current HTTP attempt. It normally matches X-Coasty-Request-Id; log both when an exact replay preserves an earlier logical-operation id.","schema":{"type":"string"}},"CoastyRequestId":{"description":"Coasty correlation identifier for this request.","schema":{"type":"string"}},"RetryAfter":{"description":"Seconds to wait before retrying. Present on retryable back-pressure and transient failures.","schema":{"type":"integer","minimum":0}},"KeyKind":{"description":"Whether the authenticated key is live or test.","schema":{"type":"string","enum":["live","test","legacy"]}},"TestMode":{"description":"true when the request executed against the sandbox namespace.","schema":{"type":"boolean"}},"IdempotentReplay":{"description":"true when this is a stored response replay rather than a new execution.","schema":{"type":"boolean"}},"IdempotencyReplayed":{"description":"true when this response replays a completed attempt; false for a fresh execution.","schema":{"type":"boolean"}},"IdempotencyStatus":{"description":"Lifecycle status of the canonical idempotent attempt when applicable.","schema":{"type":"string","enum":["processing","completed"]}},"CreditsCharged":{"description":"Coasty credits charged by this response (zero for BYOK, sandbox keys, and stored replays).","schema":{"type":"integer","minimum":0}},"CreditsRemaining":{"description":"Authoritative post-charge API-wallet balance in USD cents, when available.","schema":{"type":"integer","minimum":0}},"CreditsRefunded":{"description":"Credits durably returned to the wallet after a failed billed operation.","schema":{"type":"integer","minimum":1}},"RateLimit":{"description":"Effective request limit for the current window.","schema":{"type":"integer","minimum":0}},"RateRemaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer","minimum":0}},"RateReset":{"description":"Unix timestamp when the current rate window resets.","schema":{"type":"integer","minimum":0}}}},"x-logo":{"url":"https://coasty.ai/logo_dark.svg","altText":"Coasty","backgroundColor":"#FFFFFF"},"x-mcp-server":{"name":"@coasty/mcp","install":"npx -y @coasty/mcp","description":"Coasty's Model Context Protocol server. Wires the /v1/* surface plus pricing into any MCP-compatible client (Claude Desktop, Cursor, etc.).","homepage":"https://coasty.ai/mcp"}}