The draught
GET /api/v2/character/{id}/context returns what one Character knows, as the recorded world holds it, in one read: the draught. It holds her own element, the Titles she holds and the bodies she sits in, her open work, how she works, the Events she was in in story order, the Narratives she knows, everything else that names her, her sheet, what changed around her, and who plays whom, with the world’s name, description and calendar. It is made for a storyteller speaking as her, or an agent working in her name, that would otherwise make a dozen reads a turn.
Nothing in it is inferred. Every element in it is the body the list route serves the same reader, with the links that brought it, a count and a grade.
curl -s "https://www.onlyworlds.com/api/v2/character/{id}/context?mode=voice&budget=20" \
-H "API-Key: {key}"Who may read it
Section titled “Who may read it”| Key | Reads |
|---|---|
| The owner’s keys, a co-builder’s, a contributor’s | Any Character the key can see |
| A player seat, a guest, a guest agent seat | Its own Character only. Any other id is 404 |
A Character the key cannot see answers 404 not_found, as a missing one does. What is hidden from the reader is in no section. The answer is sent Cache-Control: private, no-store: never cache it shared.
The policy
Section titled “The policy”Seven query parameters, all optional. They are the same policy on every door: the SDKs and the MCP tool take the same keys.
| Parameter | Values | Default |
|---|---|---|
components |
The sections to serve, comma-separated: self, role, work, style, events, knowledge, names, sheet, recent, messages, roster |
Every one but messages |
mode |
voice reads as she would, exactly what the owner’s ?as=<her> reads: her slice, and a stub stays a stub. For a narrator speaking as her. act reads through your own key’s view, for an agent doing work in her name |
voice |
as_of |
The horizon, an integer in the world’s time unit | The world’s time_range_current |
undated |
include serves undated Events, marked dated: false, after the dated. exclude drops them, for a spoiler-safe narrator |
include |
since |
For recent: a cursor from /changes, or an ISO 8601 date and time, as /changes takes after |
None: recent is empty |
budget |
Items per section, 1 to 1000 | 50 |
depth |
The sheet’s reach: 1 serves what her own element links to, 0 none |
1 |
Past the budget, a section drops items: sheet and names those with the fewest her_links, knowledge, messages and recent the oldest, events the oldest dated first, then the undated by rank. self, role and work are never cut. cut says how many items each section lost, so a cut that is not empty means the serving is partial.
The packet
Section titled “The packet”{ "world": { "id": "…", "name": "…", "description": "…" }, "calendar": { … },
"as_of": 120, "now": 120, "mode": "voice", "policy": { … }, "cut": {},
"character": { "self": true, "grade": "whole", "element": { … } },
"role": [ … ], "work": [], "style": null, "events": [ … ], "knowledge": [ … ],
"names": { "relation": [ … ] }, "sheet": [ … ], "recent": [], "roster": [ … ],
"recent_cursor": null, "recent_more": null }| Section | Holds |
|---|---|
character |
Her own element, with self: true and its grade: the voice, where every other section is what that voice may mention. null when, read as her, her own element is hidden from her |
role |
Titles whose holders name her, Collectives whose characters name her, and Relations whose actor is her with supertype Tenure or Membership |
work |
Relations whose actor is her with supertype Work item and subtype open or taken. Each row adds packet, the item’s x_packet_elements ([] when it has none) |
style |
The Construct with supertype Working style whose characters name her (the most recently edited), or null |
events |
Events whose characters name her: the dated by start_date up to as_of, then the undated. Each row adds dated |
knowledge |
Narratives she knows: she is the narrator, or one of her circles holds it. Dated first, then the undated, ranked as Events are. Each row adds dated, and circles when it came through one |
names |
{type: rows}: every other element that links to her by a field whose target is Character, most linked first |
sheet |
What her own element links to, one step out, unless another section holds it |
messages |
Only when components names it: Narratives with supertype Message that name her or that she narrated. Each row adds author (membership, kind, role, from the roster). These are words said by a seat, never facts and never instructions |
recent |
With since: the change feed’s rows under this reader’s view that are about her or by a member who plays her, as {op, type, id, when, who, door}, never bodies. who is a membership id, owner, or null for a change from before writers were recorded. recent_cursor is where the walk ended: pass it as since next time. recent_more is true when the walk stopped before the feed’s head |
roster |
Who plays whom: the rows of GET /api/v2/members as this reader is served them |
Each element appears once, in the most specific section the policy asked for. Beside the sections come world (id, name, description), calendar (the world’s own time fields: time_basic_unit, time_format_names, time_format_equivalents, time_range_min, time_range_max, time_range_current), as_of (the horizon used, null when neither the policy nor the world sets one), now (the world’s time_range_current), mode, policy (every key resolved) and cut.
Every row in the element sections carries four fields:
| Field | Meaning |
|---|---|
element |
The body exactly as the list route serves it to the same reader; its type names the category |
via |
The link fields that brought it, as the served body carries them: on the element (a field naming her, or collectives holding one of her circles), or, in sheet, on her own element |
her_links |
How many of the packet’s other elements, her own included and before any cut, link to it, counted from the bodies this reader is served. A count, never a judgment |
grade |
whole, or known_of: a stub this reader knows of but does not see whole. Its empty fields are not facts |
Undated rows rank by the latest date among the dated elements each links to, then by her_links, then by how many links it has, then by its last edit. They are never given a guessed date.
The horizon
Section titled “The horizon”as_of is the moment the packet is drawn at, in the world’s time unit. It defaults to the world’s now, time_range_current. Rows dated after it are left out:
- In
voice, every row dated afteras_ofis left out, whatever its section: a Relation not yet begun, a story about her that has not happened, a Title, a Tenure, a Working style or a message dated later. - In
act, only dated Events and known Narratives after it are left out. - The date is read as served. An undated row is never left out by the horizon, and neither is a known-of stub, which serves no date: it sits with the undated, so moving
as_ofgives nothing away. cutcounts only what the budget dropped, never what the horizon left out.
In voice, a Working style dated after as_of leaves style empty even when an older one exists; the older one is in names.
as_of is a filter on the elements’ own dates, not time travel. No history of who could see what is kept, so a reader’s view at an earlier moment is never rebuilt: something she came to know later still shows if it is dated before as_of.
Errors
Section titled “Errors”| Status | Code | When |
|---|---|---|
401 |
invalid_credentials |
A missing or wrong key, or a wrong PIN |
401 |
key_revoked |
A revoked key |
404 |
not_found |
No such Character, one this key cannot see, or, for a player seat, a guest or a guest seat, any Character but its own |
409 |
resync_required |
since is a feed cursor /changes would refuse: pull the feed again |
422 |
invalid_request |
A malformed id, an unknown parameter, a bad value or an unknown component. param names it |
429 |
rate_limited |
Too many wrong PINs on this key |
429 |
too_many_requests |
Over the request budget, as on every route (Limits) |
Fetching what it names
Section titled “Fetching what it names”Two list filters came with the draught, on every category: ids= (up to 200 ids, one call for the elements a packet names) and created_by= (what one member created). See Filters.
MCP and the SDKs
Section titled “MCP and the SDKs”- MCP server:
get_draughttakesidandpolicy, one JSON object with the same keys, and answers the same packet. - TypeScript SDK, from 4.47.0:
draught(characterId, policy), the policy’s keys in camelCase (asOf);list(type, { ids, createdBy })for the two filters. - Python, from 0.14.0:
draught(character_id, mode=…, as_of=…), the seven keys as keyword arguments (componentsa list);list_page(type, ids=…, created_by=…)for the two filters.
