API
Simulations
Run a calibrated workflow against synthetic agents and retrieve per-agent responses. All requests are async per ADR-006 — POST returns 202 immediately; results arrive via webhook (recommended) or polling.
Overview
A simulation runs a calibrated workflow (e.g.
cdc_nhis_smoking
POST returns immediately with a simulation id. Results land either via webhook (push, recommended) or polling (pull, fallback).
Authentication
Bearer token via the
Authorization
simulations:write
simulations:read
POST /v1/simulations
Queue a simulation. Returns 202 with a poll URL and (on the first webhook-enabled POST per organization) a
webhook_signing_secret
Request body
{
"workflow_id": "cdc_nhis_smoking",
"agent_count": 200,
"scenario_context": { "region": "US" },
"callback_url": "https://your-app.com/webhooks/simulix"
}Response — 202
{
"data": {
"id": "0190a8b4-1c34-7d2a-9e87-2c4f3b5a6d8e",
"status": "queued",
"created_at": "2026-05-02T14:30:00Z",
"estimated_completion_time_seconds": 40,
"poll_url": "https://api.simulix.com/v1/simulations/0190a8b4-...",
"webhook_subscribed": true,
"webhook_signing_secret": "ZWZxYjg4...REDACTED-CAPTURE-NOW"
},
"error": null,
"meta": { "correlation_id": "01HX..." }
}Save your webhook signing secret immediately. Your webhook signing secret appears in this response only once, on your first webhook-enabled simulation request. Save it immediately — Simulix does not display it again. If lost, contact support@simulix.com for regeneration. Self-serve rotation API is on the roadmap.
GET /v1/simulations
Cursor-paginated list of your organization's simulations. Query params:
cursor
limit
meta
next_cursor
has_more
GET /v1/simulations/{id}
Status polling endpoint. While
queued
running
Retry-After: 5
results_available=true
GET /v1/simulations/{id}/resultsGET /v1/simulations/{id}/results
Returns full per-agent results when status is
completed
failed
409 simulation_not_complete
results_available=true
Webhook delivery
When you supply
callback_url
simulation.completed
simulation.failed
Payload shape
POST https://your-app.com/webhooks/simulix
Content-Type: application/json
X-Simulix-Signature: t=1714000000,v1=<hmac-sha256-hex>
X-Simulix-Event: simulation.completed
X-Simulix-Delivery-Id: 0190ab4f-...
{
"id": "evt_a1b2c3d4e5f6...",
"type": "simulation.completed",
"created": 1714000000,
"data": {
"simulation_id": "0190a8b4-1c34-7d2a-9e87-2c4f3b5a6d8e",
"workflow_id": "cdc_nhis_smoking",
"status": "completed",
"results": {
"agent_count": 200,
"rounds": 2,
"agent_responses": [ ... ]
}
}
}Verifying the signature (Python)
import hashlib, hmac, time
def verify_simulix_webhook(
payload: bytes,
signature_header: str,
secret: str,
tolerance_seconds: int = 300,
) -> bool:
# Header shape: "t=<unix>,v1=<hex>"
parts = dict(p.split("=", 1) for p in signature_header.split(","))
timestamp = int(parts["t"])
if abs(time.time() - timestamp) > tolerance_seconds:
return False
expected = hmac.new(
secret.encode(),
f"{timestamp}.".encode() + payload,
hashlib.sha256,
).hexdigest()
return hmac.compare_digest(expected, parts["v1"])The 5-minute timestamp tolerance prevents replay attacks. Reject any payload whose
t=
Polling pattern
If you don't use webhooks, poll
GET /v1/simulations/{id}results_available=true
Retry-After
Polling is rate limited per the API key tier (see /docs/api-reference). Long-poll abuse is handled at the per-key level. Customer-tier-aware per-simulation limits are roadmap.
Errors
- — POST: workflow_id doesn't match a published workflow
404 workflow_not_found
- — GET: id doesn't exist or belongs to a different organization
404 simulation_not_found
- — GET
409 simulation_not_complete
while still/results
/queued
running
- — POST: agent_count over your tier ceiling (current v1 ceiling: 10000)
422 agent_count_exceeds_plan
- — too many requests; honor the
429 rate_limited
headerRetry-After