Skip to content

Public API

SnapBench exposes a stable, versioned REST API at /api/v1 so external scripts and integrations can launch scenario runs and retrieve their public interfaces.

Common use cases:

  • Automated training sessions (launch N runs at once from a script)
  • CI pipelines that need isolated environments
  • Custom dashboards that monitor active runs
  • Integrations with external tools (Kafka clients, data pipelines, etc.)

OpenAPI Specification

The full machine-readable spec is served at /api/v1/openapi.yaml and can be imported into Swagger UI, Postman, or any OpenAPI-compatible codegen tool.

Authentication

Every endpoint requires authentication. Two methods are supported:

Personal API keys are created from your Account Settings page.

PropertyDetails
Formatsb_live_ followed by 43 base64url characters
ScopeTied to your user identity; inherits your organization's quotas and permissions
StorageOnly a SHA-256 hash is stored; the plaintext key is shown once at creation
LifecycleCan be named, expire, or be revoked at any time

Pass the key in the Authorization header:

Authorization: Bearer sb_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Save Your Key

API keys are shown only once when created. Copy and store them in a secure location (password manager, secret store, CI variables). If lost, revoke the key and create a new one.

If you are already logged in to the SnapBench app in your browser, the session cookie is accepted as a fallback auth method. This is useful for quick manual tests from the browser console but not recommended for scripts.

Managing API Keys

  1. Open your Account Settings page
  2. Go to the API Keys section
  3. Click Create API Key
  4. Give it a descriptive name (e.g., kafka-training-runner, ci-pipeline)
  5. Optionally set an expiration date
  6. Copy the key immediately - it will not be shown again
  7. Revoke keys you no longer need

Endpoints

All endpoints are under /api/v1.

Launch Runs

POST /api/v1/scenarios/{id}/runs

Creates and provisions count independent runs of a scenario. Each run lives in its own isolated namespace.

Path parameters:

NameDescription
idScenario ID (UUID)

Request body:

FieldTypeDescription
countintegerNumber of runs to launch (default 1, subject to platform and per-org limits)
ttlMinutesintegerOptional TTL override. Falls back to scenario TTL, then org default, then 60

Example:

bash
curl -X POST https://app.snapbench.io/api/v1/scenarios/$SCENARIO_ID/runs \
  -H "Authorization: Bearer $SB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"count": 3, "ttlMinutes": 120}'

Responses:

StatusMeaning
201 CreatedAll runs were created; provisioning runs asynchronously
207 Multi-StatusPartial success; some runs were created before an error occurred
400 Bad RequestInvalid scenario ID or count exceeds the per-request limit
404 Not FoundScenario not found or has no published version
429 Too Many RequestsPlatform concurrent-run cap would be exceeded

Response body:

json
{
  "runs": [
    {
      "id": "uuid",
      "scenarioId": "uuid",
      "status": "PROVISIONING",
      "namespace": "snapbench-run-xxxxx",
      "createdAt": "2026-04-16T12:00:00Z",
      "startedAt": "2026-04-16T12:00:00Z",
      "expiresAt": "2026-04-16T14:00:00Z",
      "provisionedAt": null,
      "endedAt": null
    }
  ]
}

List Runs

GET /api/v1/runs

Returns up to 100 of the caller's most recent runs, newest first.

Query parameters:

NameDescription
statusFilter by status: PENDING, PROVISIONING, RUNNING, ENDING, ENDED, FAILED
scenarioIdFilter to runs of a single scenario (UUID)

Example:

bash
curl https://app.snapbench.io/api/v1/runs?status=RUNNING \
  -H "Authorization: Bearer $SB_API_KEY"

Get a Run

GET /api/v1/runs/{id}

Returns a single run's current status.

Responses:

StatusMeaning
200 OKReturns the run object
403 ForbiddenYou do not own this run
404 Not FoundRun does not exist

List Run Interfaces

GET /api/v1/runs/{id}/interfaces

Returns every externally reachable interface exposed by a run.

TypeDescription
tcpRaw host:port pairs reachable from the public internet, one per published public TCP port
webFull HTTPS URLs for ingress-backed services (dashboards, consoles, etc.)

Example:

bash
curl https://app.snapbench.io/api/v1/runs/$RUN_ID/interfaces \
  -H "Authorization: Bearer $SB_API_KEY"

Response body:

json
{
  "interfaces": [
    {
      "type": "tcp",
      "component": "kafka",
      "name": "external",
      "protocol": "tcp",
      "host": "tcp.snapbench.io",
      "port": 30001
    },
    {
      "type": "web",
      "component": "grafana",
      "name": "http",
      "url": "https://grafana-abc123.snapbench.io"
    }
  ]
}

Web UIs May Lag

The web interfaces list is built from a cache refreshed every few seconds. Right after provisioning, it may briefly lag behind the TCP list. Poll /interfaces until the expected URLs appear.

Run Status Values

StatusMeaning
PENDINGRun created, not yet picked up by the orchestrator
PROVISIONINGNamespace created, components being deployed
RUNNINGAll components ready, run is live
ENDINGCleanup in progress
ENDEDRun terminated cleanly; all resources deleted
FAILEDProvisioning or runtime error

Quotas & Limits

API usage is subject to the same quotas as the SnapBench UI, plus a few API-specific caps:

LimitScopeConfigurable by
Max runs per POST /scenarios/{id}/runs requestPer requestPlatform default (apiMaxRunsPerRequest), overridable per-org
Max concurrent runs cluster-widePlatformPlatform admin (maxConcurrentRuns)
Organization quotas (CPU, memory, credits)Per orgOrg admin / platform admin

If a request exceeds the concurrent-run cap, the API returns 429 Too Many Requests. Retry after some runs end.

End-to-End Example

A typical script that launches a run and prints its public Kafka endpoint:

bash
#!/bin/bash
set -e

SB_API_KEY="sb_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
SCENARIO_ID="your-scenario-uuid"
BASE_URL="https://app.snapbench.io/api/v1"

# 1. Launch a run
RUN=$(curl -sS -X POST "$BASE_URL/scenarios/$SCENARIO_ID/runs" \
  -H "Authorization: Bearer $SB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"count": 1, "ttlMinutes": 60}')

RUN_ID=$(echo "$RUN" | jq -r '.runs[0].id')
echo "Launched run: $RUN_ID"

# 2. Wait until it's RUNNING
while true; do
  STATUS=$(curl -sS "$BASE_URL/runs/$RUN_ID" \
    -H "Authorization: Bearer $SB_API_KEY" | jq -r '.status')
  echo "Status: $STATUS"
  [ "$STATUS" = "RUNNING" ] && break
  [ "$STATUS" = "FAILED" ] && { echo "Run failed"; exit 1; }
  sleep 5
done

# 3. Fetch public interfaces
curl -sS "$BASE_URL/runs/$RUN_ID/interfaces" \
  -H "Authorization: Bearer $SB_API_KEY" | jq

Finding IDs

  • Scenario ID: Visible in the Studio header next to the scenario name, and via the Copy Scenario ID action in the Scenarios Library.
  • Run ID: Returned in the response of POST /scenarios/{id}/runs, or listed by GET /runs.

Released under the MIT License.