Coasty machines API

Provision and control managed VMs.

OpenAPI Specification

coasty-machines-api-openapi.yml Raw ↑
openapi: 3.1.0
info:
  title: Coasty Public keys machines API
  version: 1.0.0
  summary: Computer Use Agents, scheduled automation, and managed VMs.
  description: "# Coasty Public API\n\nCoasty is a Computer Use Agent (CUA) platform: predict actions from screenshots,\nprovision managed VMs, and run scheduled automation against them.\n\n## Authentication\n\nAll endpoints (except `/v1/triggers/webhook/{webhook_id}` and health checks) require an API key.\nPass it as either:\n\n- `X-API-Key: sk-coasty-live-...` (or `sk-coasty-test-...` for sandbox)\n- `Authorization: Bearer sk-coasty-live-...`\n\nThe external webhook endpoint does not use an API key, but it is authenticated:\nsend the HMAC-SHA256 `Coasty-Signature` credential documented on that operation.\n\nTest-mode keys (`sk-coasty-test-*`) hit the same validation paths as live keys but\nreturn mock VMs / mock action results and never bill credits — ideal for CI.\n\n## Pricing & budgeting\n\nPer-call rates (subject to change — see `lib/pricing/tiers.ts METERED_RATES`):\n\n| Endpoint | Credits |\n|---|---|\n| `POST /v1/predict` | ~5 |\n| `POST /v1/sessions` | 10 |\n| `POST /v1/sessions/{id}/predict` | ~4 |\n| `POST /v1/ground` | ~3 |\n| `POST /v1/parse` | 0 (free) |\n\nLong-running CUA jobs orchestrated through the dashboard (not this API) bill at\n10 credits/minute with a 20-credit minimum. Subscription tiers (`free | starter |\nprofessional | enterprise`) gate feature availability (e.g. custom system prompts),\nschedule counts, and the maximum trajectory length.\n\n## Errors\n\nEvery error response uses the same envelope:\n\n```json\n{\n  \"error\": {\n    \"code\": \"INSUFFICIENT_CREDITS\",\n    \"message\": \"Need 5, have 2.\",\n    \"type\": \"billing_error\",\n    \"request_id\": \"req_a1b2c3d4e5f6\",\n    \"retryable\": false,\n    \"retry_with_same_idempotency_key\": false\n  }\n}\n```\n\nInclude the `request_id` in support requests.\n\n## Idempotency\n\nOperations marked `x-idempotency: reserve-and-replay` accept `Idempotency-Key:\n<≤128 chars of [A-Za-z0-9_-:]>`. Replays\nof the same key + identical body return the original response (with\n`X-Coasty-Idempotent-Replay: true`) for 24 h. Reusing the key with a different body\nis a 422 `IDEMPOTENCY_KEY_REUSED`.\nOperations marked `x-idempotency: webhook-payload-dedup` instead deduplicate the\nsame webhook id + identical raw body for 60 seconds; they do not accept an\nIdempotency-Key.\n\n## Clients & MCP\n\nUse the HTTP API directly from any language. Official TypeScript and Python SDKs\nare not currently published; generate a client from this OpenAPI document if needed.\n- MCP server: `npx -y @coasty/mcp` (see `x-mcp-server`)\n\n## Reference\n\nComplete (machine-readable) spec is hosted at `/.well-known/openapi.json` and\n`/openapi.json` (Stripe / Vercel conventions)."
  contact:
    name: Coasty Developer Support
    url: https://coasty.ai/support
    email: founders@coasty.ai
  license:
    name: MIT
    identifier: MIT
  termsOfService: https://coasty.ai/terms
servers:
- url: https://coasty.ai
  description: Production
- url: https://coasty.ai
  description: Sandbox — use sk-coasty-test-* keys against the same host. No billing, mock VMs.
security:
- apiKey: []
- bearerAuth: []
tags:
- name: machines
  description: Provision and control managed VMs.
paths:
  /v1/machines:
    post:
      tags:
      - machines
      operationId: provisionMachine
      summary: Provision a new VM
      description: Managed VM provisioning. Linux defaults are cheap (1 cpu / 2 GB / 10 GB) and bill at agent-minute rates. 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-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-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-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/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 runtime rates, one-time charges, 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-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-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-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 a machine
      description: Irreversible. Stops billing the agent-minute rate.
      security:
      - apiKey: []
      - bearerAuth: []
      responses:
        '200':
          description: Termination requested.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LifecycleResponse'
          headers:
            X-Coasty-Request-Id:
              $ref: '#/components/headers/CoastyRequestId'
            X-Coasty-Key-Kind:
              $ref: '#/components/headers/KeyKind'
            X-Coasty-Test-Mode:
              $ref: '#/components/headers/TestMode'
        '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 auto-destroy lease
      description: 'Scope: `machines:write`. `ttl_minutes=0` clears auto-destroy; values 5..10080 schedule termination from now.'
      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-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}/start:
    parameters:
    - $ref: '#/components/parameters/MachineId'
    post:
      tags:
      - machines
      operationId: startMachine
      summary: Start a stopped machine
      security:
      - apiKey: []
      - bearerAuth: []
      responses:
        '200':
          description: Started.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LifecycleResponse'
          headers:
            X-Coasty-Request-Id:
              $ref: '#/components/headers/CoastyRequestId'
            X-Coasty-Key-Kind:
              $ref: '#/components/headers/KeyKind'
            X-Coasty-Test-Mode:
              $ref: '#/components/headers/TestMode'
        '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
      security:
      - apiKey: []
      - bearerAuth: []
      responses:
        '200':
          description: Stopped.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LifecycleResponse'
          headers:
            X-Coasty-Request-Id:
              $ref: '#/components/headers/CoastyRequestId'
            X-Coasty-Key-Kind:
              $ref: '#/components/headers/KeyKind'
            X-Coasty-Test-Mode:
              $ref: '#/components/headers/TestMode'
        '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
      security:
      - apiKey: []
      - bearerAuth: []
      responses:
        '200':
          description: Restart requested.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LifecycleResponse'
          headers:
            X-Coasty-Request-Id:
              $ref: '#/components/headers/CoastyRequestId'
            X-Coasty-Key-Kind:
              $ref: '#/components/headers/KeyKind'
            X-Coasty-Test-Mode:
              $ref: '#/components/headers/TestMode'
        '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: Captures a restorable machine image. 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-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-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
      security:
      - apiKey: []
      - bearerAuth: []
      responses:
        '200':
          description: Screenshot.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ScreenshotResponse'
          headers:
            X-Coasty-Request-Id:
              $ref: '#/components/headers/CoastyRequestId'
            X-Coasty-Key-Kind:
              $ref: '#/components/headers/KeyKind'
            X-Coasty-Test-Mode:
              $ref: '#/components/headers/TestMode'
        '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: 'Returns plaintext credentials. Gated by `connection:read` scope. 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-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.'
      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-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-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-re

# --- truncated at 32 KB (77 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/coasty/refs/heads/main/openapi/coasty-machines-api-openapi.yml