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.