Skip to content

Reference

Management API

Create and control simulations from scripts, CI and your own tools. JSON in, JSON out.

Base URL and authentication

All endpoints live under https://api.slurry.io/v1. Authenticate with an account key in the Authorization header. Keys carry scopes (simulations:read, simulations:write), and can be restricted to IP ranges and given an expiry.

authentication
curl https://api.slurry.io/v1/simulations \
  -H "Authorization: Bearer $SLURRY_ACCOUNT_KEY"

Errors

Errors use conventional HTTP status codes and a consistent body.

400 Bad Request
{
  "error": {
    "code": "invalid_request",
    "message": "hours: Too big: expected number to be <=720"
  }
}
StatusCodeWhen
400invalid_requestThe body failed validation.
400bad_requestThe request made sense but cannot be done, for example an invalid CIDR range.
400unsafe_urlA webhook URL points at a private or internal address.
401unauthorisedMissing, invalid, revoked or expired key.
402payment_requiredNo active subscription.
402plan_limitCreating this would exceed your plan.
402no_creditNot enough generation credit for the requested work.
403unauthorisedKey lacks a scope, IP not allowed, or account suspended.
404not_foundNo such simulation or library entry in your account.
422invalid_specThe uploaded spec could not be parsed.

Endpoints

GET/v1/library

Search the library. Query: q, vertical, limit (max 200).

response
{
  "data": [
    { "slug": "asana", "name": "Asana", "provider": "Asana",
      "vertical": "project-management", "description": "...", "operations": 213 }
  ]
}
GET/v1/simulations

List your simulations.

Scope simulations:read

response
{
  "data": [
    { "id": "4f0c2a8e-...", "name": "Acme projects", "slug": "acme-projects",
      "status": "running", "url": "https://acme-projects.slurry.io", ... }
  ]
}
POST/v1/simulations

Create a simulation from library (a slug) or spec (OpenAPI JSON or YAML as a string, up to 5 MB). Optional: name, slug, instructions (up to 2,000 characters), volume, seedRecords, ipAllowlist, ipRestrictionEnabled, useModel. The creating IP is added to the allow-list automatically.

Scope simulations:writeReturns 201

request body
{
  "library": "asana",
  "slug": "acme-projects",
  "volume": { "tasks": 400, "projects": 12 },
  "ipAllowlist": ["203.0.113.0/24"]
}
response
{
  "id": "4f0c2a8e-...",
  "slug": "acme-projects",
  "url": "https://acme-projects.slurry.io",
  "status": "queued",
  "apiKey": "slurry_sim_...",
  "note": "Store the apiKey now: it is shown once. ..."
}
GET/v1/simulations/{id}

Everything about one simulation: status, API summary, collections with record counts, events, behaviour plan, access settings, keys (prefixes only), rules and webhooks. {id} accepts the id or the slug.

response
{
  "id": "4f0c2a8e-...", "slug": "acme-projects", "status": "running",
  "api": { "title": "Asana", "version": "1.0", "basePath": "", "operations": 213 },
  "collections": [ { "name": "tasks", "records": 400, "statusField": "status", ... } ],
  "events": ["task.created", "task.updated", "task.deleted"],
  "access": { "ipRestrictionEnabled": true, "ipAllowlist": ["203.0.113.0/24"] },
  "keys": [...], "rules": [...], "webhooks": [...]
}
DELETE/v1/simulations/{id}

Delete a simulation and all of its data. Irreversible.

Scope simulations:writeReturns 204

POST/v1/simulations/{id}/pause

Pause: requests get 503 and the schedule stops.

Scope simulations:write

response
{ "ok": true }
POST/v1/simulations/{id}/resume

Resume a paused simulation.

Scope simulations:write

response
{ "ok": true }
POST/v1/simulations/{id}/reset

Regenerate the world from its original seed, in the background.

Scope simulations:write

response
{ "ok": true }
POST/v1/simulations/{id}/fast-forward

Run the behaviour plan as if hours passed (0.25 to 720).

Scope simulations:write

request body
{ "hours": 168 }
response
{ "hours": 168, "changes": 412 }
PUT/v1/simulations/{id}/behaviour

Replace the behaviour plan. The plan is validated against the data model and limits; invalid steps are dropped.

Scope simulations:write

request body
{ "rules": [ { "id": "churn", "name": "Weekly churn", "everySeconds": 3600,
  "enabled": true, "steps": [ { "kind": "delete", "collection": "tasks", "fraction": 0.01 } ] } ] }
POST/v1/simulations/{id}/rules

Add a response rule. See Rules.

Scope simulations:writeReturns 201

request body
{
  "name": "Slow search",
  "kind": "latency",
  "method": "GET",
  "pathPattern": "/tasks*",
  "config": { "latencyMs": 1500, "latencyJitterMs": 500 }
}
DELETE/v1/simulations/{id}/rules/{ruleId}

Remove a rule.

Scope simulations:writeReturns 204

POST/v1/simulations/{id}/webhooks

Register a public https endpoint. events accepts exact names, *, or prefixes such as task.*.

Scope simulations:writeReturns 201

request body
{ "url": "https://example.com/hooks/slurry", "events": ["task.*"] }
response
{
  "id": "b7e1...",
  "url": "https://example.com/hooks/slurry",
  "events": ["task.*"],
  "secret": "whsec_...",
  "note": "Verify deliveries with the Slurry-Signature header: ..."
}
PUT/v1/simulations/{id}/access

Change the IP allow-list (up to 50 IPs or CIDR ranges) or switch restriction on or off.

Scope simulations:write

request body
{ "ipRestrictionEnabled": true, "ipAllowlist": ["203.0.113.7", "198.51.100.0/24"] }
response
{ "ok": true }
POST/v1/simulations/{id}/keys

Issue another simulation key, for example one per CI system.

Scope simulations:writeReturns 201

request body
{ "name": "GitHub Actions" }
response
{ "apiKey": "slurry_sim_...", "note": "Shown once." }
GET/v1/simulations/{id}/records/{collection}

Read records directly, bypassing the simulated API. Query: limit, offset.

GET/v1/simulations/{id}/events

The latest 100 data change events.

GET/v1/simulations/{id}/logs

The latest 100 requests: method, path, status, duration, source IP, operation.

GET/v1/usage

Plan, subscription status, credit balance and this month’s usage.

response
{
  "plan": "team", "status": "active", "creditUsd": 7.42,
  "requestsThisMonth": 18230, "requestLimit": 500000,
  "simulations": 4, "simulationLimit": 15
}