Concepts
Simulations
A simulation is a hosted, stateful copy of an API's behaviour: records in collections, a plan that changes them over time, and rules that bend individual responses.
Lifecycle
When you create a simulation, Slurry parses the spec, works out the data model, generates seed data and starts serving. A model is used for the analysis and seed data; everything after that is deterministic engine work.
| Status | Meaning |
|---|---|
queued | Waiting for a worker. |
analysing | Reading the spec and building the data model. |
seeding | Generating and storing records. |
running | Serving requests and running the behaviour plan. |
paused | Requests return 503 and the schedule stops. Data is kept. |
failed | Set-up could not complete. The status detail says why. |
suspended | Stopped by abuse monitoring or an administrator, pending review. |
Collections
The data model groups records into collections - tasks, projects, users - each with an id style, a schema, field hints for realistic values and, where the API has one, a status field with its states and allowed transitions. Operations in the spec are bound to collections as list, get, create, update, delete or action.
- A
POSTto a create operation inserts a record; later lists and gets include it. - Nested paths such as
/projects/{project_gid}/tasksare scoped to their parent. - References between collections point at records that exist, so joins in your code behave.
- Operations that do not map to data return a schema-valid static response.
The behaviour plan
The behaviour plan is what makes a simulation live. It is a declarative list of rules; each rule runs every everySeconds (never faster than your plan allows) and applies its steps. It is written once, by a model, when the simulation is created, then executed by the engine with no model calls per tick. You can read and replace it at any time.
| Step | What it does |
|---|---|
transition | Moves a fraction of matching records from one state to another, optionally weighted. |
create | Creates between min and max new records, with optional field overrides. |
update | Increments, decrements, touches or regenerates a field on a fraction of records. |
delete | Deletes a fraction of records, optionally filtered. |
{
"rules": [
{
"id": "progress-tasks",
"name": "Tasks move through the board",
"everySeconds": 900,
"enabled": true,
"steps": [
{
"kind": "transition",
"collection": "tasks",
"field": "status",
"from": ["todo", "in_progress"],
"to": ["in_progress", "in_review", "done"],
"weights": [0.5, 0.3, 0.2],
"fraction": 0.1,
"maxPerTick": 25,
"event": "task.updated"
},
{
"kind": "create",
"collection": "tasks",
"count": { "min": 0, "max": 3 },
"event": "task.created"
}
]
}
]
}Fast-forward
POST /v1/simulations/{id}/fast-forward with { "hours": 168 } runs each enabled rule as many times as it would have fired in that window (capped at 200 ticks per rule), then persists the net changes and queues webhooks. The maximum is 720 hours - 30 days - per call. The response tells you how many records changed.
Reset
POST /v1/simulations/{id}/reset regenerates the world from the original seed. Generation is seeded deterministically from the simulation, so a reset puts back the same records every time. It runs in the background: the status goes to queued and back to running.
Pause and resume
Pause a simulation to stop both traffic and schedule without losing data: POST /v1/simulations/{id}/pause and /resume.