Documentation menu

Account

Usage, budgets, keys, and receipted data deletion.

GET /v1/usage

Get usage for a period

Robot-hours by tier, environment-hours by class, and dollars. Stateless test mode cannot see runs it wasn't shown: pass `run_ids=<id,id,...>` to aggregate them (hours come from each run's result; sandbox episodes cost $0 — usd figures show what live mode would have metered). `period` must be YYYY-MM and defaults to the current month.

ParameterInTypeDescription
periodquerystring
run_idsquerystringComma-separated run ids to aggregate (exact, result-derived hours and cost).

Example response (200)

{
  "object": "usage",
  "period": "2026-09",
  "robot_hours": {
    "verify": 141.2,
    "soak": 2210.5
  },
  "env_hours": {
    "bare": 96,
    "standard": 402.3,
    "replica": 118.9,
    "instrumented-replica": 6.2
  },
  "usd_total": 18940,
  "budget": {
    "monthly_usd": 25000,
    "hard": true,
    "remaining_usd": 6060
  }
}

PUT /v1/budgets

Set the monthly budget

With `hard: true`, new work is rejected and running work is stopped at the cap (`monthly_budget_exceeded`). Metered live.

ParameterInTypeDescription
monthly_usd *bodynumber
hardbodybooleanHard stop: reject new work and stop running work at the cap.
remaining_usdbodynumber

Example request

{
  "monthly_usd": 25000,
  "hard": true
}

Example response (200)

{
  "monthly_usd": 25000,
  "hard": true
}

POST /v1/keys

Create an API key

Keys are scoped (e.g. `runs:write`, `streams:read`, `data:purge`). The secret (`rbr_live_` prefix) is shown once at creation.

ParameterInTypeDescription
scope *bodyarray<runs:read | runs:write | streams:read | data:purge | keys:admin | calibration:export>

Example request

{
  "scope": [
    "runs:write",
    "streams:read"
  ]
}

Example response (201)

{
  "object": "key",
  "id": "key_51ab",
  "scope": [
    "runs:write",
    "streams:read"
  ],
  "secret": "rbr_live_4eC39HqLyjWDarjtT1zdp7dc",
  "created": "2026-09-01T12:00:00Z"
}

GET /v1/keys

List API keys

Lists keys for the account. Secrets are never returned after creation.

Example response (200)

{
  "object": "list",
  "data": [
    {
      "object": "key",
      "id": "key_51ab",
      "scope": [
        "runs:write",
        "streams:read"
      ],
      "created": "2026-09-01T12:00:00Z"
    }
  ]
}

DELETE /v1/data/{run_id}

Purge run data (receipted)

Customer-initiated deletion of all artifacts for a run. Returns a deletion receipt. Requires the `data:purge` scope.

ParameterInTypeDescription
run_id *pathstring

Example response (200)

{
  "object": "purge_receipt",
  "id": "prg_77c2",
  "run_id": "run_8842",
  "status": "completed",
  "purged_at": "2026-09-01T13:14:00Z"
}

POST /v1/webhooks

Register a webhook endpoint

Register a delivery URL for webhook events. Deliveries are signed with a Stripe-style `Roborama-Signature` header (`t=<unix>,v1=<hmac-sha256>`); the test-mode signing secret is `whsec_test`. Pass the returned id as `webhook` on any create.

ParameterInTypeDescription
url *bodystring
eventsbodyarray<string>Event types to deliver; defaults to all.

Example request

{
  "url": "https://ci.example.com/hooks/roborama",
  "events": [
    "run.completed",
    "run.requeued"
  ]
}

Example response (201)

{
  "object": "webhook_endpoint",
  "id": "whk_s...",
  "url": "https://ci.example.com/hooks/roborama",
  "events": [
    "run.completed",
    "run.requeued"
  ],
  "secret": "whsec_test",
  "note": "stateless: pass this id as \"webhook\" on POST /v1/runs; deliveries fire when a GET or POST /poke touches the run."
}

POST /v1/uploads

Create an upload slot (test mode)

Mints a presigned PUT slot for checkpoint or scenario bytes. PUT any bytes to `put_url`; the response carries the real sha256 and an `upl_` id to reference from `policy.checkpoint.upload_id` or `scenarios_upload_id` — the digest appears on the run and its report (custody, testable). Test-mode surface; live mode ingests from your registry/Hub.

ParameterInTypeDescription
filenamebodystring

Example response (201)

{
  "object": "upload",
  "status": "awaiting_bytes",
  "put_url": "https://api.roborama.com/v1/uploads/<token>?e=...&sig=...",
  "expires": "2026-09-12T15:00:00Z"
}

POST /v1/webhook-inbox/{box}

Webhook testing inbox (test mode)

An unauthenticated inbox so the whole webhook loop is provable with nothing but the sandbox: register `{base}/v1/webhook-inbox/<yourbox>` as a webhook URL, then GET the box to see deliveries with their Roborama-Signature headers. Instance-local, like the delivered-set.

GET /v1/webhook-inbox/{box}

Read the webhook testing inbox (test mode)

Deliveries this instance captured for the box (last 50).

Example response (200)

{
  "object": "list",
  "box": "yourbox",
  "data": [
    {
      "received": "2026-09-12T14:00:00Z",
      "roborama_signature": "t=...,v1=...",
      "body": {
        "type": "run.completed"
      }
    }
  ]
}