Developer documentation

Rivetplane API

A single authenticated surface for machines, harness capabilities, sessions, transcripts, approvals, questions, events, and MCP.

Quick start

Create an API token in the dashboard. Use it as a bearer token on every REST and MCP request.

export RIVETPLANE_TOKEN="your-api-token"

curl -s https://rivetplane.com/v1/sessions \
  -H "Authorization: Bearer $RIVETPLANE_TOKEN"

The server accepts a command with HTTP 202. Completion arrives later through session state, transcript events, or the global WebSocket stream.

Authentication

Supabase Auth owns browser signup, login, email confirmation, password recovery, and user sessions. Rivetplane issues separate hashed bearer tokens for remote consumers and paired runners.

TokenPurposeScope
API tokenREST, WebSocket, and MCP consumersAccount read/write policy
Machine tokenLocal runner relayOne paired machine
Authorization: Bearer YOUR_API_TOKEN

Session identifiers

Remote IDs are namespaced so routing remains unambiguous across machines:

{machine_id}/{harness_type}/{local_session_id}

Percent-encode the complete value when it appears in a REST path or MCP transcript resource URI.

Machines, capabilities, and models

GET/v1/machines
POST/v1/machines/{machine_id}/retire
GET/v1/harness-capabilities?machine={machine_id}
GET/v1/machines/{machine_id}/harnesses/{harness}/capabilities
POST/v1/machines/{machine_id}/harnesses/{harness}/sessions

Normal re-pairing keeps one stable machine identity. Retire a stale runner to remove it and its sessions from list views. Direct transcript access remains available.

Read capabilities before creating a session. The selected directory and model must be present in the runner report.

curl -X POST "https://rivetplane.com/v1/machines/$MACHINE/harnesses/opencode/sessions" \
  -H "Authorization: Bearer $RIVETPLANE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "cwd": "/workspace/project",
    "title": "Android bring-up",
    "model": {
      "provider_id": "peakflo",
      "model_id": "Deepseek v4 Flash"
    }
  }'

Sessions and actions

GET/v1/sessions?machine=&harness=&status=&cwd=
GET/v1/sessions/{session_id}
GET/v1/sessions/{session_id}/transcript?cursor=&since=&limit=
GET/v1/sessions/{session_id}/pending
POST/v1/sessions/{session_id}/messages
POST/v1/sessions/{session_id}/pending/respond
POST/v1/sessions/{session_id}/interrupt
POST /v1/sessions/{session_id}/messages
{"text":"Continue with the migration plan."}

POST /v1/sessions/{session_id}/pending/respond
{"pending_id":"per_01J...","response":"deny","scope":"once"}

An interrupt can be a no-op when the session is already idle. In that case, the harness does not add a transcript event.

Streaming and events

GET /v1/sessions/{session_id}/transcript/stream returns SSE transcript events. WS /v1/events/stream returns machine, session, command, approval, and transcript activity across the caller’s account.

WebSocket clients can use the normal Authorization header. Browser clients can use the bearer.<base64url-token> subprotocol.

MCP

Connect a Streamable HTTP MCP client to https://rivetplane.com/mcp.

{
  "mcpServers": {
    "rivetplane": {
      "url": "https://rivetplane.com/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_API_TOKEN"
      }
    }
  }
}

Tools: list_sessions, get_session, get_transcript, send_message, get_pending, respond_to_pending, interrupt_session, list_machines, list_harness_capabilities, and create_session.

Transcript resource: session://{percent-encoded-session-id}/transcript.

Hosted billing

Hosted accounts use Stripe Checkout for subscription purchase and the Stripe customer portal for plan, payment-method, and invoice management. The dashboard creates both sessions on the server.

POST/v1/billing/webhook

Stripe calls this public endpoint. The server verifies Stripe-Signature against the raw request body before it stores customer, subscription, plan, or status changes. Community self-hosted mode works without Stripe configuration.

Errors and safe control

StatusMeaning
400Invalid body, cursor, model, or working directory
401Missing or invalid bearer token
403Token cannot access this account, machine, or session
404Resource not found
409Runner offline, no active pending request, or stale pending ID

Always fetch the current pending interaction and respond with its exact pending_id. The local harness remains the permission authority.