Skip to content

Simulations

Simulations are the core resource of the Kairos Nexus REST API. Kairos Nexus is the hosted service that runs the engine. You can create them from pre-built scenarios or custom configurations. You can advance them tick-by-tick or in bulk and retrieve their full execution trace. You can control agent policies and playback in real time.

All simulation endpoints require authentication. API keys need simulation:write for writes and simulation:read for reads. Scope checks do not apply to JWT callers.

API keys access their own organization’s simulations. JWT callers need organization membership or ownership of a personal simulation. All endpoints can return 401, 403, 429, or 500. See HTTP Status Codes for shared errors. Schema-invalid JSON bodies return 400 VALIDATION_ERROR. Unknown top-level body fields are rejected.

Replace <api-key>, <organization-id>, and <simulation-id> in the examples with your key and resource UUIDs. Responses containing comments are abbreviated examples. State objects, agent snapshots, and additional rows or steps are omitted, rather than empty.

POST /v1/simulations

Creates a new simulation instance. Provide either a scenarioId (to use a pre-built scenario) or an inline scenario object. Do not provide both.

FieldTypeRequiredDescription
scenarioIdstringOne ofID of a pre-built scenario
scenarioobjectOne ofInline scenario configuration
scenario.seednumberYesRandom seed
scenario.agentsAgent[]NoAgent configurations (1 to 64 entries if supplied)
scenario.initialStateanyNoStarting state overrides, without REST structure validation
organizationIduuidFor API keysKey’s organization UUID. Optional for JWT callers
engineVersionstringNoRequired match to the server’s engine version

scenario.seed is required when scenario is supplied. Omitting scenario.agents keeps the default primary agent. Supplying agents requires an explicitly allowlisted JWT user or API key. The key does not inherit its creator’s allowlist entry.

Agent fieldTypeRequiredDescription
idstringYesAgent identifier
marker{x, y}YesInitial position with numeric coordinates
policyobjectNoAgent policy
policy.lambdanumberNoLambda policy value
policy.gammanumberNoGamma policy value
attractorPreferencesobjectNoAttractor names mapped to numeric weights

engineVersion must match the server’s reported engine version string. A mismatch returns 400 VALIDATION_ERROR. The check does not select another build or verify the loaded binary’s identity.

For inline scenarios, scenarioId is inline:<simulation-id>.

{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"scenarioId": "standard",
"engineVersion": "1.4.4",
"state": { /* State fields omitted */ }
}
Terminal window
curl -X POST https://api.anankelabs.io/v1/simulations \
-H "X-Api-Key: <api-key>" \
-H "Content-Type: application/json" \
-d '{"scenarioId": "standard", "organizationId": "<organization-id>"}'
POST /v1/simulations/from-domain

Creates a simulation using a domain adapter. Domain adapters translate domain-specific input (for example, AI Safety vocabulary) into the engine’s native scenario format.

FieldTypeRequiredDescription
domainstringYesDomain adapter identifier (for example, "ai-safety")
inputobjectYesDomain-specific input payload
organizationIduuidFor API keysKey’s organization UUID. Optional for JWT callers
engineVersionstringNoRequired match to the server’s engine version

Same field names as Create Simulation, with scenarioId set to domain:<domain>:<simulation-id>.

StatusCodeWhen
404NOT_FOUNDUnknown domain adapter
403FORBIDDENCaller lacks the custom-collection allowlist entry or organization access

Domain input must contain an entities array and pass the selected adapter’s validation. The input and encoded agent collections must each contain 1 to 64 entries. Domain creation requires an explicitly allowlisted caller.

POST /v1/simulations/run

Creates and executes a simulation in a single request, returning the completed run’s trace. This endpoint supports batch workloads.

FieldTypeRequiredDescription
scenarioIdstringOne ofPre-built scenario ID
domainstringOne ofDomain adapter identifier
inputobjectWith domainDomain-specific input payload
ticksintegerYesRequested tick count (1 to 10,000), with no default
organizationIduuidFor API keysKey’s organization UUID. Optional for JWT callers
engineVersionstringNoRequired match to the server’s engine version

Provide exactly one of scenarioId or domain. With domain, also provide input and meet the domain collection requirements.

Usage limits can shorten a run. trace.metadata.ticks and the number of steps show the actual completed count. The JSON response is the default. Successful JSON responses support an Idempotency-Key.

Set Accept: application/x-ndjson to receive the trace as NDJSON, where each line is a trace step. The stream contains steps only, without the JSON wrapper, simulation ID, or metadata. The server retains the steps in memory for trace persistence. Streaming runs do not cache an idempotent response. An error after streaming starts can terminate the stream before completion.

{
"simulationId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"engineVersion": "1.4.4",
"trace": {
"metadata": {"scenarioId": "standard", "engineVersion": "1.4.4", "ticks": 500},
"initialState": { /* Initial state fields omitted */ },
"steps": [
{
"tick": 1,
"move": "stay",
"state": { /* State fields omitted */ },
"warning": { /* Warning signal fields omitted */ },
"loss": null,
"agents": [
{
"id": "default",
"state": { /* State fields omitted */ },
"policy": { /* Optional lambda and gamma values omitted */ }
}
]
}
// Remaining steps omitted
]
}
}

Terminal window
curl -X POST https://api.anankelabs.io/v1/simulations/run \
-H "X-Api-Key: <api-key>" \
-H "Content-Type: application/json" \
-d '{"scenarioId": "standard", "ticks": 500, "organizationId": "<organization-id>"}'

Terminal window
curl -X POST https://api.anankelabs.io/v1/simulations/run \
-H "X-Api-Key: <api-key>" \
-H "Accept: application/x-ndjson" \
-H "Content-Type: application/json" \
-d '{"scenarioId": "standard", "ticks": 500, "organizationId": "<organization-id>"}'
GET /v1/simulations

Returns simulations in descending creation order. API keys list only their own organization. JWT callers list personal simulations by default. Supplying organizationId lists that organization’s simulations after a membership check. The API ignores an API key caller’s organizationId query filter.

ParameterTypeDefaultDescription
organizationIduuidNoneOrganization filter (JWT users only, API keys use their own org)
limitinteger50Results per page, clamped to 1 to 200
offsetinteger0Pagination offset, clamped to 0 or greater

limit and offset use integer parsing. Zero or an unparseable limit uses 50. An unparseable offset uses 0.

{
"data": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"scenarioId": "standard",
"organizationId": "11111111-1111-4111-8111-111111111111",
"createdAt": "2025-06-15T10:30:00.000Z",
"state": { /* State fields omitted */ }
}
],
"pagination": {
"limit": 50,
"offset": 0,
"total": 1
}
}
Terminal window
curl "https://api.anankelabs.io/v1/simulations?limit=10" \
-H "X-Api-Key: <api-key>"
GET /v1/simulations/{id}

Returns the current state of a single simulation.

ParameterTypeDescription
iduuidSimulation ID

The organizationId field is null for a personal simulation.

{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"scenarioId": "standard",
"organizationId": "11111111-1111-4111-8111-111111111111",
"state": { /* State fields omitted */ },
"createdAt": "2025-06-15T10:30:00.000Z"
}
StatusCodeWhen
401UNAUTHORIZEDMissing or invalid authentication
403FORBIDDENMissing API key scope or access to this simulation
404NOT_FOUNDSimulation does not exist
POST /v1/simulations/{id}/step

Advances an existing simulation by a given number of ticks.

ParameterTypeDescription
iduuidSimulation ID
FieldTypeRequiredDescription
ticksintegerYesRequested tick count (1 to 10,000), with no default

The returned ticks is the actual completed count, which usage limits can shorten. Stepping updates the stored state and creates a prophecy record. It does not create or refresh the persisted trace. This endpoint does not cache idempotent responses.

{
"state": { /* State fields omitted */ },
"ticks": 100
}
Terminal window
curl -X POST "https://api.anankelabs.io/v1/simulations/<simulation-id>/step" \
-H "X-Api-Key: <api-key>" \
-H "Content-Type: application/json" \
-d '{"ticks": 100}'
GET /v1/simulations/{id}/trace

Returns the persisted trace from POST /simulations/run. The default response is JSON. With Accept: application/x-ndjson, the response contains only the persisted steps, one per line. Creating or stepping a simulation alone does not persist a trace. Later stepping does not refresh a previous run’s trace.

ParameterTypeDescription
iduuidSimulation ID
{
"metadata": {"scenarioId": "standard", "engineVersion": "1.4.4", "ticks": 500},
"initialState": { /* Initial state fields omitted */ },
"steps": [
{
"tick": 1,
"move": "stay",
"state": { /* State fields omitted */ },
"warning": { /* Warning signal fields omitted */ },
"loss": null,
"agents": [
{
"id": "default",
"state": { /* State fields omitted */ },
"policy": { /* Optional lambda and gamma values omitted */ }
}
]
}
// Remaining steps omitted
]
}
FieldTypeDescription
ticknumberStep count within this run, starting at 1
movestringThe move that was applied
stateobjectFull simulation state at this tick
warningobject | nullWarning signal returned for this step, or null
lossobject | nullBasin loss event, if one occurred
agentsAgent[]Per-agent state and policy snapshot
StatusCodeWhen
404NOT_FOUNDSimulation not found or trace not yet available

Terminal window
curl "https://api.anankelabs.io/v1/simulations/<simulation-id>/trace" \
-H "X-Api-Key: <api-key>" \
-H "Accept: application/x-ndjson"
PUT /v1/simulations/{id}/agent-policy

Updates the policy parameters for a specific agent in the cached simulation engine. If the engine is absent from the server cache, this returns 404 NOT_FOUND. Create or step the simulation first. The REST schema sets no numeric range for lambda or gamma.

ParameterTypeDescription
iduuidSimulation ID
FieldTypeRequiredDescription
agentIdstringYesAgent to update (default for the base policy)
policyobjectYesPolicy values to update
policy.lambdanumberNoLambda policy value
policy.gammanumberNoGamma policy value
{ "ok": true }
Terminal window
curl -X PUT "https://api.anankelabs.io/v1/simulations/<simulation-id>/agent-policy" \
-H "X-Api-Key: <api-key>" \
-H "Content-Type: application/json" \
-d '{"agentId": "default", "policy": {"lambda": 0.7}}'
PUT /v1/simulations/{id}/time-control

Controls playback of a running simulation: play, pause, or single-step. speed has no REST default. If omitted, it keeps the session’s playback speed. The session UI state must exist in the server cache. If absent, the endpoint returns 404 NOT_FOUND.

ParameterTypeDescription
iduuidSimulation ID
FieldTypeRequiredDescription
actionstringYesOne of "play", "pause", or "step"
speednumberNoPlayback speed multiplier (0.1 to 10)
{ "ok": true }
Terminal window
curl -X PUT "https://api.anankelabs.io/v1/simulations/<simulation-id>/time-control" \
-H "X-Api-Key: <api-key>" \
-H "Content-Type: application/json" \
-d '{"action": "play", "speed": 2.0}'