Skip to content
Browse docs

Panes docs

HTTP API

Full machine-readable contract: OpenAPI 3.1. All URLs use https://api.usepanes.com.

Examples show response shapes, not a promise that every template is currently Office-ready. Read live catalog readiness before paying.

API keys use Authorization: Bearer pk_…. File bodies and screenshots are raw bytes. Dashboard-only routes are explicitly labeled.

Every endpoint can also return a documented JSON error. See Errors for recovery; pending writes require reconciliation.

GET /v1/health

Control-plane health

Authentication: public or signed token as stated above.

Request body: none.

Response 200: Success


{
  "ok": true
}

Request/response field schemas and all error responses: OpenAPI.

GET /v1/catalog

Public prices, payment methods and template readiness

Authentication: public or signed token as stated above.

Request body: none.

Response 200: Success


{
  "product": "Panes",
  "operator": "Renaissance Superintelligence Corporation",
  "templates": [
    {
      "id": "windows-16gb",
      "name": "windows-16gb",
      "private": false,
      "vcpus": 4,
      "memory_mb": 16384,
      "hourly_usd": 0.75,
      "apps": [
        "powershell",
        "edge",
        "excel",
        "word",
        "powerpoint"
      ],
      "office_ready": false,
      "office_status": "sign_in_required"
    }
  ],
  "prices": {
    "stopped_machine_hour": 0.002,
    "machine_4gb_hour": 0.33,
    "machine_8gb_hour": 0.4,
    "machine_16gb_hour": 0.75,
    "backup_gb_month": 0.018,
    "backup_copy_gb": 0.00035,
    "backup_restore_gb": 0.0003
  },
  "payment_methods": [
    "stripe_mpp",
    "usdc_x402",
    "checkout"
  ],
  "signup_url": "https://api.usepanes.com/v1/signup",
  "docs_url": "https://usepanes.com/docs.md",
  "openapi_url": "https://usepanes.com/openapi.json"
}

Request/response field schemas and all error responses: OpenAPI.

GET /v1/payment-methods

Available prepayment methods and amount bounds

Authentication: public or signed token as stated above.

Request body: none.

Response 200: Success


{
  "currency": "usd",
  "minimum_cents": 1000,
  "maximum_cents": 1000000,
  "methods": [
    "stripe_mpp",
    "usdc_x402",
    "checkout"
  ],
  "docs_url": "https://usepanes.com/docs#funding"
}

Request/response field schemas and all error responses: OpenAPI.

POST /v1/signup

Creates an account or recovers access through an API-readable inbox. Codes expire in 10 minutes, with five attempts. The provider code is never returned. Limit: three requests per address, replenishing one per minute.

Authentication: public or signed token as stated above.

Request (application/json):


{
  "email": "agent@example.com",
  "key_name": "Office agent"
}

Response 202: Success


{
  "challenge_id": "signup_example",
  "expires_at": "2026-11-15T12:10:00Z",
  "next_action": "read_email_code",
  "verify_url": "https://api.usepanes.com/v1/signup/verify"
}

Request/response field schemas and all error responses: OpenAPI.

POST /v1/signup/verify

Consumes one email code. Only an active single-organization administrator may recover an account key. The key is shown once; a lost reply requires another email challenge. No free credit.

Authentication: public or signed token as stated above.

Request (application/json):


{
  "challenge_id": "signup_example",
  "code": "123456"
}

Response 201: Success


{
  "key": "pk_EXAMPLE_STORE_IN_SECRET_MANAGER",
  "info": {
    "id": "key_example",
    "name": "Agent",
    "hint": "abcd",
    "created": "2026-11-15T12:00:00Z"
  },
  "org": "org_example",
  "balance_usd": 0,
  "next_action": "prepay",
  "account_url": "https://api.usepanes.com/v1/account",
  "topups_url": "https://api.usepanes.com/v1/topups"
}

Request/response field schemas and all error responses: OpenAPI.

GET /v1/account

Balance, prices, counts and limits

Authentication: Panes API key.

Request body: none.

Response 200: Success


{
  "org": "org_example",
  "name": "agent@example.com",
  "balance_usd": 10,
  "running": 0,
  "max_running": 1000000,
  "prices": {
    "stopped_machine_hour": 0.002,
    "machine_4gb_hour": 0.33,
    "machine_8gb_hour": 0.4,
    "machine_16gb_hour": 0.75,
    "backup_gb_month": 0.018,
    "backup_copy_gb": 0.00035,
    "backup_restore_gb": 0.0003
  },
  "machines": 0,
  "max_machines": 1000000,
  "snapshots": 0,
  "max_snapshots": 1000000,
  "templates": 0,
  "max_templates": 1000000,
  "admission_runway_minutes": 15,
  "limits_mode": "prepaid_and_capacity",
  "topups_url": "https://api.usepanes.com/v1/topups",
  "payment_methods": [
    "stripe_mpp",
    "usdc_x402",
    "checkout"
  ],
  "limits_rise_on_first_payment": false,
  "support_email": "support@usepanes.com",
  "auto_stop_minutes": 15,
  "billing_required": false
}

Request/response field schemas and all error responses: OpenAPI.

GET /v1/account/keys

List API keys

Authentication: Panes API key.

Request body: none.

Response 200: Success


[
  {
    "id": "key_example",
    "name": "Agent",
    "hint": "abcd",
    "created": "2026-11-15T12:00:00Z"
  }
]

Request/response field schemas and all error responses: OpenAPI.

POST /v1/account/keys

Returns key plaintext once. Store it securely.

Authentication: Panes API key.

Request (application/json):


{
  "name": "worker"
}

Response 201: Success


{
  "key": "pk_EXAMPLE_STORE_IN_SECRET_MANAGER",
  "info": {
    "id": "key_example",
    "name": "Agent",
    "hint": "abcd",
    "created": "2026-11-15T12:00:00Z"
  }
}

Request/response field schemas and all error responses: OpenAPI.

DELETE /v1/account/keys/{id}

Revoke an API key

Authentication: Panes API key.

| Parameter | Location | Required | Example |

| --- | --- | --- | --- |

| id | path | true | key_example |

Request body: none.

Response 204: Success; empty body

Request/response field schemas and all error responses: OpenAPI.

GET /v1/keys

List API keys Dashboard only. API keys cannot authenticate this route.

Authentication: browser session/redirect flow.

Request body: none.

Response 200: Success


[
  {
    "id": "key_example",
    "name": "Agent",
    "hint": "abcd",
    "created": "2026-11-15T12:00:00Z"
  }
]

Request/response field schemas and all error responses: OpenAPI.

POST /v1/keys

Returns key plaintext once. Store it securely. Dashboard only. API keys cannot authenticate this route.

Authentication: browser session/redirect flow.

| Parameter | Location | Required | Example |

| --- | --- | --- | --- |

| X-Panes-Csrf | header | true | 1 |

Request (application/json):


{
  "name": "worker"
}

Response 201: Success


{
  "key": "pk_EXAMPLE_STORE_IN_SECRET_MANAGER",
  "info": {
    "id": "key_example",
    "name": "Agent",
    "hint": "abcd",
    "created": "2026-11-15T12:00:00Z"
  }
}

Request/response field schemas and all error responses: OpenAPI.

DELETE /v1/keys/{id}

Revoke an API key Dashboard only. API keys cannot authenticate this route.

Authentication: browser session/redirect flow.

| Parameter | Location | Required | Example |

| --- | --- | --- | --- |

| id | path | true | key_example |

| X-Panes-Csrf | header | true | 1 |

Request body: none.

Response 204: Success; empty body

Request/response field schemas and all error responses: OpenAPI.

POST /v1/topups

Reusing a key returns the original quote (HTTP 200); a changed amount/method returns 409. Quote expires in 30 minutes. No charge until authorized. Check /v1/payment-methods before choosing a method.

Authentication: Panes API key.

| Parameter | Location | Required | Example |

| --- | --- | --- | --- |

| Idempotency-Key | header | true | office-credit-20261115-01 |

Request (application/json):


{
  "amount_cents": 1000,
  "method": "stripe_mpp"
}

Response 201: Success


{
  "id": "top_agent_example",
  "amount_cents": 1000,
  "currency": "usd",
  "method": "stripe_mpp",
  "status": "quoted",
  "expires_at": "2026-11-15T12:30:00Z",
  "refunded_cents": 0,
  "status_url": "https://api.usepanes.com/v1/topups/top_agent_example",
  "pay_url": "https://api.usepanes.com/v1/topups/top_agent_example/pay",
  "balance_usd": 0,
  "next_action": "authorize_payment",
  "payment": {
    "id": "challenge_example",
    "realm": "api.usepanes.com",
    "method": "stripe",
    "intent": "charge",
    "request": {
      "amount": "1000",
      "currency": "usd",
      "externalId": "top_agent_example",
      "methodDetails": {
        "networkId": "profile_example",
        "paymentMethodTypes": [
          "card"
        ]
      }
    },
    "expires": "2026-11-15T12:30:00Z",
    "opaque": "eyJ0b3B1cCI6InRvcF9hZ2VudF9leGFtcGxlIn0",
    "header": "Payment-Authorization",
    "description": "Panes prepaid credit"
  }
}

Response 200: Success


{
  "id": "top_agent_example",
  "amount_cents": 1000,
  "currency": "usd",
  "method": "stripe_mpp",
  "status": "quoted",
  "expires_at": "2026-11-15T12:30:00Z",
  "refunded_cents": 0,
  "status_url": "https://api.usepanes.com/v1/topups/top_agent_example",
  "pay_url": "https://api.usepanes.com/v1/topups/top_agent_example/pay",
  "balance_usd": 0,
  "next_action": "authorize_payment",
  "payment": {
    "id": "challenge_example",
    "realm": "api.usepanes.com",
    "method": "stripe",
    "intent": "charge",
    "request": {
      "amount": "1000",
      "currency": "usd",
      "externalId": "top_agent_example",
      "methodDetails": {
        "networkId": "profile_example",
        "paymentMethodTypes": [
          "card"
        ]
      }
    },
    "expires": "2026-11-15T12:30:00Z",
    "opaque": "eyJ0b3B1cCI6InRvcF9hZ2VudF9leGFtcGxlIn0",
    "header": "Payment-Authorization",
    "description": "Panes prepaid credit"
  }
}

Request/response field schemas and all error responses: OpenAPI.

GET /v1/topups/{id}

Resumes the stored payment when pending. Paid credit is granted exactly once. Do not submit a new payment after a lost response; poll this URL. pending recommends three seconds between reads.

Authentication: Panes API key.

| Parameter | Location | Required | Example |

| --- | --- | --- | --- |

| id | path | true | top_agent_example |

Request body: none.

Response 200: Success


{
  "id": "top_agent_example",
  "amount_cents": 1000,
  "currency": "usd",
  "method": "stripe_mpp",
  "status": "paid",
  "expires_at": "2026-11-15T12:30:00Z",
  "refunded_cents": 0,
  "status_url": "https://api.usepanes.com/v1/topups/top_agent_example",
  "pay_url": "https://api.usepanes.com/v1/topups/top_agent_example/pay",
  "balance_usd": 10,
  "payment_intent": "pi_example"
}

Request/response field schemas and all error responses: OpenAPI.

POST /v1/topups/{id}/pay

Use one payment header and keep Authorization for the Panes key. Missing payment returns 402 with WWW-Authenticate (MPP) or PAYMENT-REQUIRED (x402) and payment in the JSON body. Stripe SPT payload is {spt,externalId}; x402 v2 payload includes resource, accepted requirements, signature and EIP-3009 authorization. The exact issued quote must match. A pending or uncertain payment must be polled, never repaid. Checkout returns a browser URL.

Authentication: Panes API key.

| Parameter | Location | Required | Example |

| --- | --- | --- | --- |

| id | path | true | top_agent_example |

| Payment-Authorization | header | false | Payment BASE64URL_MPP_CREDENTIAL |

| PAYMENT-SIGNATURE | header | false | BASE64_X402_PAYMENT_PAYLOAD |

Request body: none.

Response 200: Success


{
  "id": "top_agent_example",
  "amount_cents": 1000,
  "currency": "usd",
  "method": "stripe_mpp",
  "status": "paid",
  "expires_at": "2026-11-15T12:30:00Z",
  "refunded_cents": 0,
  "status_url": "https://api.usepanes.com/v1/topups/top_agent_example",
  "pay_url": "https://api.usepanes.com/v1/topups/top_agent_example/pay",
  "balance_usd": 10,
  "payment_intent": "pi_example"
}

Response 202: Pending or requires reconciliation; do not pay again.


{
  "id": "top_agent_example",
  "status": "pending",
  "status_url": "https://api.usepanes.com/v1/topups/top_agent_example",
  "next_action": "poll_status_do_not_pay_again"
}

Request/response field schemas and all error responses: OpenAPI.

POST /v1/machines

Persist a unique Idempotency-Key and exact body before calling. require_office_ready rejects an unverified template before provisioning. Creation needs 15 minutes of resulting aggregate running credit and capacity. prevent_cloning protects the new identity.

Authentication: Panes API key.

| Parameter | Location | Required | Example |

| --- | --- | --- | --- |

| Idempotency-Key | header | false | office-computer-20261115-01 |

Request (application/json):


{
  "template": "windows-16gb",
  "name": "office-report",
  "auto_stop_minutes": 15,
  "prevent_cloning": true,
  "require_office_ready": true
}

Response 201: Success


{
  "id": "m_example",
  "name": "office-report",
  "template": "windows-16gb",
  "state": "running",
  "vcpus": 4,
  "memory_mb": 16384,
  "created": "2026-11-15T12:00:00Z",
  "updated": "2026-11-15T12:00:00Z",
  "auto_stop_minutes": 15,
  "prevent_cloning": true,
  "require_dedicated": false,
  "stopped_hourly_usd": 0,
  "timings_ms": {
    "total": 60000
  }
}

Request/response field schemas and all error responses: OpenAPI.

GET /v1/machines

List kept computers

Authentication: Panes API key.

Request body: none.

Response 200: Success


[
  {
    "id": "m_example",
    "name": "office-report",
    "template": "windows-16gb",
    "state": "running",
    "vcpus": 4,
    "memory_mb": 16384,
    "created": "2026-11-15T12:00:00Z",
    "updated": "2026-11-15T12:00:00Z",
    "auto_stop_minutes": 15,
    "prevent_cloning": true,
    "require_dedicated": false,
    "stopped_hourly_usd": 0,
    "timings_ms": {
      "total": 60000
    }
  }
]

Request/response field schemas and all error responses: OpenAPI.

GET /v1/machines/{id}

Read a computer

Authentication: Panes API key.

| Parameter | Location | Required | Example |

| --- | --- | --- | --- |

| id | path | true | m_example |

Request body: none.

Response 200: Success


{
  "id": "m_example",
  "name": "office-report",
  "template": "windows-16gb",
  "state": "running",
  "vcpus": 4,
  "memory_mb": 16384,
  "created": "2026-11-15T12:00:00Z",
  "updated": "2026-11-15T12:00:00Z",
  "auto_stop_minutes": 15,
  "prevent_cloning": true,
  "require_dedicated": false,
  "stopped_hourly_usd": 0,
  "timings_ms": {
    "total": 60000
  }
}

Request/response field schemas and all error responses: OpenAPI.

PATCH /v1/machines/{id}

Change auto-stop or backup settings

Authentication: Panes API key.

| Parameter | Location | Required | Example |

| --- | --- | --- | --- |

| id | path | true | m_example |

Request (application/json):


{
  "auto_stop_minutes": 15,
  "backup": false
}

Response 200: Success


{
  "id": "m_example",
  "auto_stop_minutes": 15
}

Request/response field schemas and all error responses: OpenAPI.

DELETE /v1/machines/{id}

Irreversible. Backups are deleted too. Snapshots and forks retain their own state and encryption keys.

Authentication: Panes API key.

| Parameter | Location | Required | Example |

| --- | --- | --- | --- |

| id | path | true | m_example |

Request body: none.

Response 204: Success; empty body

Request/response field schemas and all error responses: OpenAPI.

GET /v1/machine-requests/{key}

Read-only request-key lookup; never creates another computer.

Authentication: Panes API key.

| Parameter | Location | Required | Example |

| --- | --- | --- | --- |

| key | path | true | request-example |

Request body: none.

Response 200: Success


{
  "id": "m_example",
  "name": "office-report",
  "template": "windows-16gb",
  "state": "running",
  "vcpus": 4,
  "memory_mb": 16384,
  "created": "2026-11-15T12:00:00Z",
  "updated": "2026-11-15T12:00:00Z",
  "auto_stop_minutes": 15,
  "prevent_cloning": true,
  "require_dedicated": false,
  "stopped_hourly_usd": 0,
  "timings_ms": {
    "total": 60000
  }
}

Request/response field schemas and all error responses: OpenAPI.

POST /v1/machine-requests/{key}/stop

Cancels the request key before locating/stopping a possibly created computer. A cancelled key cannot be reused.

Authentication: Panes API key.

| Parameter | Location | Required | Example |

| --- | --- | --- | --- |

| key | path | true | request-example |

Request body: none.

Response 200: Success


{
  "state": "stopped",
  "request_canceled": true
}

Request/response field schemas and all error responses: OpenAPI.

POST /v1/machines/{id}/stop

Read stop_warning/resume_warning before continuing work. A cold recovery can preserve disk without unsaved memory. Stop ends running charges; optional stopped storage/backups retain their rates.

Authentication: Panes API key.

| Parameter | Location | Required | Example |

| --- | --- | --- | --- |

| id | path | true | m_example |

Request body: none.

Response 200: Success


{
  "id": "m_example",
  "name": "office-report",
  "template": "windows-16gb",
  "state": "stopped",
  "vcpus": 4,
  "memory_mb": 16384,
  "created": "2026-11-15T12:00:00Z",
  "updated": "2026-11-15T12:00:00Z",
  "auto_stop_minutes": 15,
  "prevent_cloning": true,
  "require_dedicated": false,
  "stopped_hourly_usd": 0,
  "timings_ms": {
    "total": 60000
  }
}

Request/response field schemas and all error responses: OpenAPI.

POST /v1/machines/{id}/start

Read stop_warning/resume_warning before continuing work. A cold recovery can preserve disk without unsaved memory. New admission requires prepaid runway and physical capacity.

Authentication: Panes API key.

| Parameter | Location | Required | Example |

| --- | --- | --- | --- |

| id | path | true | m_example |

Request body: none.

Response 200: Success


{
  "id": "m_example",
  "name": "office-report",
  "template": "windows-16gb",
  "state": "running",
  "vcpus": 4,
  "memory_mb": 16384,
  "created": "2026-11-15T12:00:00Z",
  "updated": "2026-11-15T12:00:00Z",
  "auto_stop_minutes": 15,
  "prevent_cloning": true,
  "require_dedicated": false,
  "stopped_hourly_usd": 0,
  "timings_ms": {
    "total": 60000
  }
}

Request/response field schemas and all error responses: OpenAPI.

POST /v1/machines/{id}/exec

Choose script or argv. desktop:true is required for native Office. Default is SYSTEM. HTTP 200 is transport success; inspect exit_code, stderr and timed_out. Never blindly repeat after a lost reply.

Authentication: Panes API key.

| Parameter | Location | Required | Example |

| --- | --- | --- | --- |

| id | path | true | m_example |

Request (application/json):


{
  "script": "Get-Date -Format o",
  "desktop": true,
  "timeout_s": 30
}

Response 200: Success


{
  "exit_code": 0,
  "stdout": "2026-11-15T12:00:00Z\r\n",
  "stderr": "",
  "ms": 125,
  "timed_out": false
}

Request/response field schemas and all error responses: OpenAPI.

GET /v1/machines/{id}/health

Read guest readiness

Authentication: Panes API key.

| Parameter | Location | Required | Example |

| --- | --- | --- | --- |

| id | path | true | m_example |

Request body: none.

Response 200: Success


{
  "ok": true,
  "version": "0.1.0",
  "hostname": "PANES-EXAMPLE",
  "desktop": true,
  "time": "2026-11-15T12:00:00Z",
  "agent_uptime_s": 60
}

Request/response field schemas and all error responses: OpenAPI.

GET /v1/machines/{id}/files

Download a file

Authentication: Panes API key.

| Parameter | Location | Required | Example |

| --- | --- | --- | --- |

| id | path | true | m_example |

| path | query | true | C:/work/report.xlsx |

Request body: none.

Response 200: Success


<raw file bytes>

Request/response field schemas and all error responses: OpenAPI.

PUT /v1/machines/{id}/files

Writes atomically and creates parent directories. URL-encode the absolute Windows path. Body is bytes, not JSON.

Authentication: Panes API key.

| Parameter | Location | Required | Example |

| --- | --- | --- | --- |

| id | path | true | m_example |

| path | query | true | C:/work/report.xlsx |

Request (application/octet-stream):


<raw file bytes>

Response 200: Success


{
  "bytes": 1024
}

Request/response field schemas and all error responses: OpenAPI.

GET /v1/machines/{id}/screenshot

Read a PNG of the desktop

Authentication: Panes API key.

| Parameter | Location | Required | Example |

| --- | --- | --- | --- |

| id | path | true | m_example |

Request body: none.

Response 200: Success


<PNG bytes>

Request/response field schemas and all error responses: OpenAPI.

POST /v1/machines/{id}/input

Coordinates are screenshot pixels. Scroll dy is notches, positive down. Body limit 64 KiB. Inspect the screen before repeating uncertain input.

Authentication: Panes API key.

| Parameter | Location | Required | Example |

| --- | --- | --- | --- |

| id | path | true | m_example |

Request (application/json):


{
  "actions": [
    {
      "type": "click",
      "x": 640,
      "y": 360
    },
    {
      "type": "key",
      "keys": [
        "ctrl",
        "s"
      ]
    }
  ]
}

Response 204: Success; empty body

Request/response field schemas and all error responses: OpenAPI.

POST /v1/machines/{id}/viewer

Create a private one-hour viewer URL

Authentication: Panes API key.

| Parameter | Location | Required | Example |

| --- | --- | --- | --- |

| id | path | true | m_example |

Request body: none.

Response 201: Success


{
  "url": "https://api.usepanes.com/view/m_example?token=EXAMPLE",
  "expires_in": "1h"
}

Request/response field schemas and all error responses: OpenAPI.

POST /v1/machines/{id}/ssh

This URL transports SSH bytes. End-to-end SSH authentication and host-key verification are still required.

Authentication: Panes API key.

| Parameter | Location | Required | Example |

| --- | --- | --- | --- |

| id | path | true | m_example |

Request body: none.

Response 201: Success


{
  "url": "wss://api.usepanes.com/v1/machines/m_example/ssh?token=EXAMPLE",
  "expires_at": "2026-11-15T12:00:00Z"
}

Request/response field schemas and all error responses: OpenAPI.

GET /v1/machines/{id}/ssh

Obtain a short-lived URL through the authenticated viewer or SSH grant endpoint. Treat it as a private bearer credential. VNC and SSH require a WebSocket upgrade.

Authentication: public or signed token as stated above.

| Parameter | Location | Required | Example |

| --- | --- | --- | --- |

| id | path | true | m_example |

| token | query | true | EXAMPLE_SIGNED_TOKEN |

Request body: none.

Response 101: WebSocket upgrade; binary transport stream.

Request/response field schemas and all error responses: OpenAPI.

POST /v1/machines/{id}/snapshot

Snapshot memory and disk

Authentication: Panes API key.

| Parameter | Location | Required | Example |

| --- | --- | --- | --- |

| id | path | true | m_example |

Request body: none.

Response 201: Success


{
  "id": "snap_example",
  "machine": "m_example",
  "vcpus": 4,
  "memory_mb": 16384,
  "created": "2026-11-15T12:00:00Z",
  "bytes": 1048576,
  "ms": 3000
}

Request/response field schemas and all error responses: OpenAPI.

POST /v1/machines/{id}/fork

Protected computers refuse cloning. Partial failures return the snapshot and all copies that started; retain their IDs before retrying.

Authentication: Panes API key.

| Parameter | Location | Required | Example |

| --- | --- | --- | --- |

| id | path | true | m_example |

Request (application/json):


{
  "count": 1
}

Response 201: Success


{
  "snapshot": {
    "id": "snap_example",
    "machine": "m_example",
    "vcpus": 4,
    "memory_mb": 16384,
    "created": "2026-11-15T12:00:00Z",
    "bytes": 1048576,
    "ms": 3000
  },
  "machines": [
    {
      "id": "m_example",
      "name": "office-report",
      "template": "windows-16gb",
      "state": "running",
      "vcpus": 4,
      "memory_mb": 16384,
      "created": "2026-11-15T12:00:00Z",
      "updated": "2026-11-15T12:00:00Z",
      "auto_stop_minutes": 15,
      "prevent_cloning": true,
      "require_dedicated": false,
      "stopped_hourly_usd": 0,
      "timings_ms": {
        "total": 60000
      }
    }
  ],
  "ms": 1200,
  "error": ""
}

Request/response field schemas and all error responses: OpenAPI.

POST /v1/machines/{id}/template

Replaces the source computer. Private templates copy files and signed-in identities; remove credentials before saving. Protected computers refuse this operation.

Authentication: Panes API key.

| Parameter | Location | Required | Example |

| --- | --- | --- | --- |

| id | path | true | m_example |

Request (application/json):


{
  "name": "office-tools"
}

Response 201: Success


{
  "id": "tpl_example",
  "name": "office-tools",
  "private": true,
  "vcpus": 4,
  "memory_mb": 16384,
  "hourly_usd": 0.75,
  "apps": [
    "powershell",
    "edge",
    "excel",
    "word",
    "powerpoint"
  ],
  "office_ready": false,
  "office_status": "unknown"
}

Request/response field schemas and all error responses: OpenAPI.

GET /v1/templates

List shared and private templates

Authentication: Panes API key.

Request body: none.

Response 200: Success


[
  {
    "id": "windows-16gb",
    "name": "windows-16gb",
    "private": false,
    "vcpus": 4,
    "memory_mb": 16384,
    "hourly_usd": 0.75,
    "apps": [
      "powershell",
      "edge",
      "excel",
      "word",
      "powerpoint"
    ],
    "office_ready": false,
    "office_status": "sign_in_required"
  }
]

Request/response field schemas and all error responses: OpenAPI.

DELETE /v1/templates/{id}

Erase a private template

Authentication: Panes API key.

| Parameter | Location | Required | Example |

| --- | --- | --- | --- |

| id | path | true | snap_example |

Request body: none.

Response 204: Success; empty body

Request/response field schemas and all error responses: OpenAPI.

GET /v1/snapshots

List snapshots

Authentication: Panes API key.

Request body: none.

Response 200: Success


[
  {
    "id": "snap_example",
    "machine": "m_example",
    "vcpus": 4,
    "memory_mb": 16384,
    "created": "2026-11-15T12:00:00Z",
    "bytes": 1048576,
    "ms": 3000
  }
]

Request/response field schemas and all error responses: OpenAPI.

DELETE /v1/snapshots/{id}

Erase a snapshot

Authentication: Panes API key.

| Parameter | Location | Required | Example |

| --- | --- | --- | --- |

| id | path | true | snap_example |

Request body: none.

Response 204: Success; empty body

Request/response field schemas and all error responses: OpenAPI.

POST /v1/snapshots/{id}/machines

Start a copy from a snapshot

Authentication: Panes API key.

| Parameter | Location | Required | Example |

| --- | --- | --- | --- |

| id | path | true | snap_example |

Request (application/json):


{
  "name": "snapshot-copy",
  "auto_stop_minutes": 15
}

Response 201: Success


{
  "id": "m_example",
  "name": "office-report",
  "template": "windows-16gb",
  "state": "running",
  "vcpus": 4,
  "memory_mb": 16384,
  "created": "2026-11-15T12:00:00Z",
  "updated": "2026-11-15T12:00:00Z",
  "auto_stop_minutes": 15,
  "prevent_cloning": true,
  "require_dedicated": false,
  "stopped_hourly_usd": 0,
  "timings_ms": {
    "total": 60000
  }
}

Request/response field schemas and all error responses: OpenAPI.

POST /v1/machines/{id}/restore

Requires a stopped computer with this account's backup copy. Poll the machine until backup.restoring clears; inspect backup.restore_error before starting.

Authentication: Panes API key.

| Parameter | Location | Required | Example |

| --- | --- | --- | --- |

| id | path | true | m_example |

Request (application/json):


{
  "copy": "copy_example"
}

Response 202: Success


{
  "id": "m_example",
  "backup": {
    "enabled": true,
    "restoring": "copy_example"
  }
}

Request/response field schemas and all error responses: OpenAPI.

GET /v1/usage

Read spending by computer

Authentication: Panes API key.

| Parameter | Location | Required | Example |

| --- | --- | --- | --- |

| from | query | false | 2026-11-01T00:00:00Z |

| to | query | false | 2026-11-15T12:00:00Z |

Request body: none.

Response 200: Success


{
  "to": "2026-11-15T12:00:00Z",
  "machines": [],
  "usd": 0,
  "balance_usd": 10,
  "prices": {
    "stopped_machine_hour": 0.002,
    "machine_4gb_hour": 0.33,
    "machine_8gb_hour": 0.4,
    "machine_16gb_hour": 0.75,
    "backup_gb_month": 0.018,
    "backup_copy_gb": 0.00035,
    "backup_restore_gb": 0.0003
  },
  "from": "2026-11-15T12:00:00Z"
}

Request/response field schemas and all error responses: OpenAPI.

GET /v1/billing

Read dashboard billing and invoices Dashboard only. API keys cannot authenticate this route.

Authentication: browser session/redirect flow.

| Parameter | Location | Required | Example |

| --- | --- | --- | --- |

| checkout | query | false | cs_example |

Request body: none.

Response 200: Success


{
  "enabled": true,
  "test_mode": false,
  "ready": true,
  "blocked": false,
  "balance_usd": 10,
  "usage_usd": 0,
  "period_start": "2026-11-01T00:00:00Z",
  "prices": {
    "stopped_machine_hour": 0.002,
    "machine_4gb_hour": 0.33,
    "machine_8gb_hour": 0.4,
    "machine_16gb_hour": 0.75,
    "backup_gb_month": 0.018,
    "backup_copy_gb": 0.00035,
    "backup_restore_gb": 0.0003
  },
  "invoices": [],
  "payment_status": ""
}

Request/response field schemas and all error responses: OpenAPI.

POST /v1/billing/checkout

Open dashboard prepaid Checkout Dashboard only. API keys cannot authenticate this route.

Authentication: browser session/redirect flow.

| Parameter | Location | Required | Example |

| --- | --- | --- | --- |

| X-Panes-Csrf | header | true | 1 |

Request (application/json):


{
  "cents": 1000,
  "attempt": "00000000-0000-4000-8000-000000000000"
}

Response 200: Success


{
  "url": "https://checkout.stripe.com/c/pay/EXAMPLE"
}

Request/response field schemas and all error responses: OpenAPI.

POST /v1/billing/portal

Open customer billing portal Dashboard only. API keys cannot authenticate this route.

Authentication: browser session/redirect flow.

| Parameter | Location | Required | Example |

| --- | --- | --- | --- |

| X-Panes-Csrf | header | true | 1 |

Request body: none.

Response 200: Success


{
  "url": "https://billing.stripe.com/p/session/EXAMPLE"
}

Request/response field schemas and all error responses: OpenAPI.

GET /auth/me

Read the current dashboard user Dashboard only. API keys cannot authenticate this route.

Authentication: browser session/redirect flow.

Request body: none.

Response 200: Success


{
  "id": "user_example",
  "email": "agent@example.com",
  "name": "Agent",
  "org": "org_example"
}

Request/response field schemas and all error responses: OpenAPI.

POST /logout

End dashboard and WorkOS sign-in

Authentication: public or signed token as stated above.

Request body: none.

Response 200: Success


{
  "url": "/"
}

Request/response field schemas and all error responses: OpenAPI.

GET /login

Browser redirect flow. API signup uses /v1/signup instead. Callback parameters state and code come from WorkOS.

Authentication: browser session/redirect flow.

Request body: none.

Response 302: Browser redirect

Request/response field schemas and all error responses: OpenAPI.

GET /auth/callback

Browser redirect flow. API signup uses /v1/signup instead. Callback parameters state and code come from WorkOS.

Authentication: browser session/redirect flow.

Request body: none.

Response 302: Browser redirect

Request/response field schemas and all error responses: OpenAPI.

GET /view/{id}

Obtain a short-lived URL through the authenticated viewer or SSH grant endpoint. Treat it as a private bearer credential. VNC and SSH require a WebSocket upgrade.

Authentication: public or signed token as stated above.

| Parameter | Location | Required | Example |

| --- | --- | --- | --- |

| id | path | true | snap_example |

| token | query | true | EXAMPLE_SIGNED_TOKEN |

Request body: none.

Response 200: Success


<browser HTML>

Request/response field schemas and all error responses: OpenAPI.

GET /v1/machines/{id}/vnc

Obtain a short-lived URL through the authenticated viewer or SSH grant endpoint. Treat it as a private bearer credential. VNC and SSH require a WebSocket upgrade.

Authentication: public or signed token as stated above.

| Parameter | Location | Required | Example |

| --- | --- | --- | --- |

| id | path | true | m_example |

| token | query | true | EXAMPLE_SIGNED_TOKEN |

Request body: none.

Response 101: WebSocket upgrade; binary transport stream.

Request/response field schemas and all error responses: OpenAPI.

GET /.well-known/panes.json

Panes-specific discovery metadata. This well-known file is supplemental, not an MCP protocol standard.

Authentication: public or signed token as stated above.

Request body: none.

Response 200: Success


{
  "name": "Panes",
  "operator": "Renaissance Superintelligence Corporation",
  "docs": "https://usepanes.com/docs.md",
  "openapi": "https://usepanes.com/openapi.json",
  "llms": "https://usepanes.com/llms.txt",
  "mcp": {
    "url": "https://api.usepanes.com/mcp/agent",
    "transport": "streamable-http",
    "authentication": "Discovery and signup are public. Account tools require Authorization: Bearer <Panes API key>."
  }
}

Request/response field schemas and all error responses: OpenAPI.

POST /mcp/agent

Standard MCP JSON-RPC over Streamable HTTP. Discovery/signup are public. Account tools require a Panes bearer API key on each HTTP request; cookies cannot authorize tools. Use an MCP client for initialization, protocol negotiation and cancellation. Tool parameters mirror REST, with JSON request payload nested under body. The separate ChatGPT endpoint is /mcp with OAuth and per-action approvals.

Authentication: public or signed token as stated above.

| Parameter | Location | Required | Example |

| --- | --- | --- | --- |

| Accept | header | true | application/json, text/event-stream |

| Authorization | header | false | Bearer pk_EXAMPLE |

Request (application/json):


{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/list",
  "params": {}
}

Response 200: Success


{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "tools": []
  }
}

Response 202: Notification accepted; no response body.

Request/response field schemas and all error responses: OpenAPI.