API reference
Base URL, auth, every customer endpoint, errors, pagination, and idempotency.
Base URL and versioning
Base URL: https://api.demosyne.com/v1. The path prefix is the API version. Additive server changes never break an installed client; anything else is a new version prefix.
Auth
Every customer request carries Authorization: Bearer trr_…. See Authentication for scopes, bindings, and revocation.
Identity
| Method | Path | Scope | Returns |
|---|---|---|---|
| GET | /v1/me | any | Org, scopes, capabilities for this key |
Scenarios
| Method | Path | Scope | Returns |
|---|---|---|---|
| GET | /v1/scenarios | observe | Scenarios this key can see (yours and the shared catalogue) |
| POST | /v1/scenarios | define | Created scenario; honour Idempotency-Key |
| GET | /v1/scenarios/{scenario_id} | observe | One scenario |
Worlds
| Method | Path | Scope | Returns |
|---|---|---|---|
| GET | /v1/worlds | observe | Page envelope {data, has_more}; query limit, after, status |
| POST | /v1/worlds | define | Created world snapshot; creating from a scenario name in the SDK also reads the catalogue, which takes observe |
| GET | /v1/worlds/{world_id} | observe | World snapshot (usage present only with measure) |
| POST | /v1/worlds/{world_id}/advance | control | Advance receipt (start_tick, target_tick) |
| POST | /v1/worlds/{world_id}/pause | control | Updated world snapshot |
| GET | /v1/worlds/{world_id}/summary | observe | Cast summary and last narrations |
Characters
| Method | Path | Scope | Returns |
|---|---|---|---|
| GET | /v1/worlds/{world_id}/characters | observe | Cast list |
| POST | /v1/worlds/{world_id}/characters | seat | Created or seated character |
| PATCH | /v1/worlds/{world_id}/characters/{character_id} | seat | Updated character (brain, memory flags, prompts) |
| GET | …/characters/{character_id}/perception | observe | Scene (clock, narration, text) |
| PUT | …/characters/{character_id}/action | seat | Staged attempt |
| GET | …/characters/{character_id}/history | seat | History entries |
| PUT | …/characters/{character_id}/history | seat | Replaced history |
Keys
| Method | Path | Scope | Returns |
|---|---|---|---|
| GET | /v1/keys | control | Keys for this org (secret never included) |
| POST | /v1/keys | control | Minted key; secret shown once |
| DELETE | /v1/keys/{key_id} | control | Revoked key metadata |
Errors
The server speaks {"detail": …}. Every response carries x-request-id (inbound header honoured, minted otherwise). Status to meaning:
Preserve that header and quote its exact value when asking for support; the SDK also attaches it to API errors. It is the public correlation value, so send it instead of an authorization header, API key, or request body. Staff correlate it against the internal logs, which bind the same value to every line the request wrote.
| Status | Meaning |
|---|---|
| 401 | Authentication failed or missing |
| 403 | Scope, binding, or org refused the call |
| 404 | Unknown resource |
| 409 | Conflict (advance in flight, idempotency key reuse with a different body, …) |
| 422 | Unprocessable entity |
| 429 | Rate limited |
| 5xx | Server error |
Pagination
World listing accepts limit (default 100) and after (an id), and returns { "data": [...], "has_more": bool }. Scenario and key listings stay complete lists for now.
Idempotency
POST /v1/scenarios honours Idempotency-Key: same key and same body returns the existing scenario; same key and a different body is 409.