Skip to content

Concepts

Worlds

A simulation is a world you can copy, save, bend and measure. Forks isolate each test run, snapshots let you assert what changed, scenarios stage bad days, and sessions tell you what an agent actually did.

Forks

A fork is an isolated copy of a simulation: its own records, its own URL at <slug>--<name>, the same keys and IP allow-list as its parent. Writes to a fork never touch the parent. Forks expire after ttlHours (default 24, up to 168), or delete them with DELETE /v1/simulations/{forkId}.

create a fork
curl -X POST https://api.slurry.io/v1/simulations/acme-projects/forks \
  -H "Authorization: Bearer $SLURRY_ACCOUNT_KEY" -H "Content-Type: application/json" \
  -d '{ "name": "pr-123", "ttlHours": 24 }'

# 201
{
  "id": "9b2e...",
  "slug": "acme-projects--pr-123",
  "url": "https://acme-projects--pr-123.slurry.io",
  "expiresAt": "2026-09-26T10:00:00Z",
  "note": "Forks accept the parent simulation API keys and IP allow-list."
}
  • Pass fromSnapshot to start the fork from a saved snapshot instead of the live state.
  • Every fork gets a fork-origin snapshot at creation, so you can diff a fork without setting anything up.
  • Fork names are 2 to 20 characters. You cannot fork a fork.
  • Forks have their own limit per plan: 3 concurrent on Starter, 20 on Team, 100 on Scale. They do not count towards your simulation limit.
One fork per pull request or agent run is the pattern this is built for: create it at the start of the job, delete it at the end.

Snapshots and diffs

A snapshot saves every record in a simulation under a name. Diff the live state against it to assert exactly what a test or agent changed, and restore it to go back.

snapshot, diff, restore
# Save the current state
curl -X POST https://api.slurry.io/v1/simulations/acme-projects/snapshots \
  -H "Authorization: Bearer $SLURRY_ACCOUNT_KEY" -H "Content-Type: application/json" -d '{ "name": "baseline" }'

# ...run your tests...

# What changed since?
curl https://api.slurry.io/v1/simulations/acme-projects/snapshots/baseline/diff -H "Authorization: Bearer $SLURRY_ACCOUNT_KEY"

# Put it back
curl -X POST https://api.slurry.io/v1/simulations/acme-projects/snapshots/baseline/restore -H "Authorization: Bearer $SLURRY_ACCOUNT_KEY"
diff response
{
  "snapshot": "baseline",
  "collections": [
    { "collection": "tasks", "added": 3, "removed": 1, "changed": 12 },
    { "collection": "projects", "added": 0, "removed": 0, "changed": 2 }
  ]
}

Restoring replaces the live data. Rules, behaviour and webhooks are not part of a snapshot and stay as they are.

Scenarios

Scenario packs stage a bad day in one call. GET /v1/scenarios lists them with their parameters.

ScenarioWhat happensParameters
bulk-growthA burst of new records, as if a big customer onboarded.count (max 500), collection
status-churnA share of records move along their status workflow at once.fraction, collection
partner-outageThe API returns 503s for a period, then recovers by itself.minutes (max 240)
rate-limit-stormA share of requests get 429 with Retry-After for a period.minutes, probability
slow-networkEvery response is delayed by 1.5 to 3 seconds for a period.minutes
data-purgeA share of records disappear, as if deleted in the vendor UI. Destructive: take a snapshot first.fraction (max 0.5), collection
run a scenario
curl -X POST https://api.slurry.io/v1/simulations/acme-projects/scenarios/partner-outage \
  -H "Authorization: Bearer $SLURRY_ACCOUNT_KEY" -H "Content-Type: application/json" -d '{ "minutes": 15 }'

Plain-English rules

Describe a rule in a sentence and Slurry compiles it into either a response rule (for example a conditional error) or a behaviour rule (for example a scheduled transition). Compiling returns the rule for review and saves nothing: add it with POST /rules or merge it into the behaviour plan. Compiling uses your AI allowance.

compile a rule
curl -X POST https://api.slurry.io/v1/simulations/acme-projects/rules/compile \
  -H "Authorization: Bearer $SLURRY_ACCOUNT_KEY" -H "Content-Type: application/json" \
  -d '{ "description": "POST /refunds fails with 402 when amount is over 500" }'

Agent sessions

Send Slurry-Session: <name> (up to 100 characters) on requests to a simulation and they are grouped into a session. The session report gives the blast radius: calls, writes, destructive calls, errors, retries, records created, updated and deleted, and a recent journal.

tag and report
# Tag every request your agent or test makes
curl https://acme-projects--pr-123.slurry.io/tasks \
  -H "Authorization: Bearer $SLURRY_SIM_KEY" \
  -H "Slurry-Session: pr-123-run-1"

# Then ask what that session did
curl https://api.slurry.io/v1/simulations/acme-projects--pr-123/sessions/pr-123-run-1 -H "Authorization: Bearer $SLURRY_ACCOUNT_KEY"

Request and response headers

Headers you send

HeaderEffect
Authorization: Bearer slurry_sim_...Simulation key. X-API-Key and HTTP Basic (key as the username or password) also work, so vendor SDKs can be pointed at Slurry unchanged.
Slurry-SessionGroups requests into a session for the session report.
Slurry-ForceOne-shot fault for this request only: an HTTP status such as 503, 500 or 429, timeout (504 after a long wait) or slow (3 seconds of extra latency). Ignored when a rule already applies.
Slurry-Force
# One request, one fault: nothing else changes
curl https://acme-projects.slurry.io/tasks -H "Authorization: Bearer $SLURRY_SIM_KEY" -H "Slurry-Force: 503"
curl https://acme-projects.slurry.io/tasks -H "Authorization: Bearer $SLURRY_SIM_KEY" -H "Slurry-Force: timeout"
curl https://acme-projects.slurry.io/tasks -H "Authorization: Bearer $SLURRY_SIM_KEY" -H "Slurry-Force: slow"

Headers you get back

HeaderMeaning
x-slurry-simulated: trueAlways present: this response came from a simulation.
x-slurry-operationThe spec operation the request matched, or none.
x-slurry-duration-msTime spent in the engine.
x-slurry-errorPresent when Slurry itself refused the request (not the simulated API). Same value as error.code.
x-total-count, linkPagination on list operations.
x-ratelimit-limit, x-ratelimit-remainingYour per-minute budget for this simulation.
retry-afterOn 429 responses.

Addresses

Each simulation has its own hostname, https://<slug>.slurry.io. The same simulation is also reachable in path mode at https://api.slurry.io/s/<slug>/..., which is handy where wildcard DNS or certificates are awkward. Paths after the prefix are the spec's own paths.

To fill in an IP allow-list, ask Slurry what it sees: curl https://api.slurry.io/ip returns { "ip": "203.0.113.9" } for the machine you run it on. For CI runners with changing addresses, add a temporary entry with POST /v1/simulations/{id}/access/entries (no body allows the caller for 60 minutes); entries are additive and expire on their own, so parallel jobs never overwrite each other.

Endpoints

GET/v1/simulations/{id}/forks
POST/v1/simulations/{id}/forks
GET/v1/simulations/{id}/snapshots
POST/v1/simulations/{id}/snapshots
POST/v1/simulations/{id}/snapshots/{snapshot}/restore
GET/v1/simulations/{id}/snapshots/{snapshot}/diff
DELETE/v1/simulations/{id}/snapshots/{snapshot}
GET/v1/scenarios
POST/v1/simulations/{id}/scenarios/{scenario}
POST/v1/simulations/{id}/rules/compile
GET/v1/simulations/{id}/sessions/{session}

All use an account key; writes need the simulations:write scope. Full request and response details are in the Management API reference.