Skip to content

REST API Overview

The Kairos REST API provides programmatic access to the Kairos Recursive Causality Simulator. All endpoints are served under the /v1 prefix and follow standard REST conventions.

https://api.anankelabs.ai/v1

An interactive API reference powered by Scalar is available at /v1/docs, and the raw OpenAPI 3.1 specification is served at /v1/openapi.json.

The API supports two authentication methods. Protected endpoints require exactly one of these.

Pass your organization’s API key in the X-Api-Key header. Keys are prefixed with krs_.

Terminal window
curl https://api.anankelabs.ai/v1/simulations \
-H "X-Api-Key: krs_your_api_key_here"

API keys are scoped. When you create a key you assign it one or more of the following scopes:

ScopeGrants access to
simulation:readList and retrieve simulations, traces, prophecies
simulation:writeCreate simulations, run steps, submit decrees, update policies
org:readRead organization details and license info
usage:readRead usage and billing metrics

Pass a JWT token in the Authorization header. This method is primarily used by the Kairos web application.

Terminal window
curl https://api.anankelabs.ai/v1/simulations \
-H "Authorization: Bearer eyJhbGciOi..."

The following endpoints require no authentication:

  • GET /v1/health
  • GET /v1/openapi.json
  • GET /v1/docs
  • GET /v1/scenarios
  • GET /v1/scenarios/{id}

All errors return a consistent JSON envelope:

{
"error": {
"code": "NOT_FOUND",
"message": "Simulation not found.",
"details": null,
"requestId": "req_abc123"
}
}

For validation errors, the details field contains an issues array describing each field-level problem:

{
"error": {
"code": "VALIDATION_ERROR",
"message": "Request validation failed.",
"details": {
"issues": [
{ "path": "ticks", "message": "Number must be less than or equal to 10000" }
]
},
"requestId": "req_abc123"
}
}
StatusMeaning
200Success
201Resource created
400Validation error
401Missing or invalid authentication
403Insufficient scope or not authorized for the resource
404Resource not found
409Idempotency key reused with a different request body
429Rate limit exceeded
500Internal server error

Rate limits are enforced per identity (API key, user, or IP address). Limits scale with your organization’s license tier and are surfaced in the response headers below.

Route classifications:

  • CreatePOST /simulations*, POST /simulations/{id}/decrees
  • StepPOST /simulations/{id}/step
  • Read — all GET requests
  • SSEGET /simulations/{id}/events (concurrent connection limit)

Every response includes rate limit metadata:

HeaderDescription
X-RateLimit-LimitMaximum requests allowed in the current window
X-RateLimit-RemainingRequests remaining in the current window
X-RateLimit-ResetUnix timestamp when the window resets
Retry-AfterSeconds to wait before retrying (only on 429)

For POST (create/mutate) endpoints, you can pass an Idempotency-Key header to safely retry requests without creating duplicate resources.

Terminal window
curl -X POST https://api.anankelabs.ai/v1/simulations \
-H "X-Api-Key: krs_..." \
-H "Idempotency-Key: my-unique-key-123" \
-H "Content-Type: application/json" \
-d '{"scenarioId": "capability-divergence"}'

Behavior:

  • Same key + same body — replays the cached response (response includes Idempotency-Replayed: true header)
  • Same key + different body — returns 409 IDEMPOTENCY_KEY_REUSE
  • New key — executes normally and caches the response

Idempotency keys expire after 24 hours. The key is scoped to your identity, the HTTP method, and the request path.

HeaderRequiredDescription
X-Api-KeyOne ofAPI key authentication
AuthorizationOne ofBearer JWT authentication
Content-TypeFor request bodiesapplication/json
AcceptOptionalapplication/json (default) or application/x-ndjson for streaming
X-Request-IdOptionalCustom request ID for tracing; auto-generated if omitted
Idempotency-KeyOptionalIdempotent retry key for POST requests
HeaderDescription
X-Request-IdRequest identifier (echo or auto-generated)
X-RateLimit-LimitRate limit ceiling
X-RateLimit-RemainingRequests remaining
X-RateLimit-ResetWindow reset timestamp
Retry-AfterSeconds to wait (only on 429)
Idempotency-Replayedtrue if the response was replayed from cache