{"openapi":"3.2.0","$self":"https://schedule-bit-api-dev.khaled-mailhub.workers.dev/v1/openapi.json","info":{"title":"schedule-bit Cloud API","summary":"A scheduling engine as an API.","version":"1.0.0","description":"Any resource (a room, a machine, a person's hours) is a **World** whose time\nis kept as bits. Claims go through a guarded **door** that answers with a\nreceipt or a reason. Every act is sealed in a hash-chained **journal**. One\njob can be carried through several Worlds as a **relay**, across workspaces\nby **grant**.\n\n**This document is the source of truth for the API.** The router is checked\nagainst it on every build: every operation here is called, and every answer\nmust match its schema (`cloud/tests/openapi.test.ts`).\n\nConventions:\n- **Masks** are hex strings (`\"0x600\"`); **slots** are also given as lists (`[9, 10]`).\n- **Positions** are a UTC `date` (plus `hour` on a `temporal-minute` World), or\n  raw `parametric` + `coordinates`.\n- **Errors** are RFC 9457 `application/problem+json`. A refusal by the engine\n  is a 409 carrying `refusal`, the engine's reason.\n- **Writes** accept an `Idempotency-Key`: the same key and body answer the same\n  for 24 hours.\n- **Authenticated responses** carry `RateLimit-Limit`, `RateLimit-Remaining`\n  and `RateLimit-Reset`.\n- **`x-websocket`** on an operation names the frames of the WebSocket it\n  opens: `receive` is the schema of what the server sends, `send` of what a\n  client may send. Frames are JSON text.\n- **`x-assist`** on an operation offers it to the Director (`POST /v1/assist`):\n  `read` in both of its modes, `write` only when it may act. An operation\n  without it is never offered, whatever the key could do.\n","contact":{"name":"schedule-bit","url":"https://schedule-bit-site.pages.dev"},"license":{"name":"MIT","identifier":"MIT"}},"servers":[{"url":"https://api.schedule-bit.io","description":"this deployment"}],"security":[{"apiKey":[]}],"tags":[{"name":"meta","summary":"Meta","description":"Health, presets, this document, and who a key is.","kind":"nav"},{"name":"worlds","summary":"Worlds","description":"A World is one schedulable resource in one Durable Object.","kind":"nav"},{"name":"occupiers","summary":"Occupiers","parent":"worlds","description":"Who may hold time on a World, and how many at once."},{"name":"door","summary":"The door","parent":"worlds","description":"Claims and the acts around them. Every one is judged; a refusal says why."},{"name":"reading","summary":"Reading","parent":"worlds","description":"What is free, what one party holds, every plane's bits, and the sealed journal."},{"name":"watching","summary":"Watching","parent":"worlds","description":"Live events over a WebSocket."},{"name":"relays","summary":"Relays","description":"One job carried through several hand Worlds, leg by leg.","kind":"nav"},{"name":"asks","summary":"Asks","parent":"relays","description":"A hand's inbox of what planners have asked of it."},{"name":"grants","summary":"Grants","parent":"relays","description":"Let another workspace see or ask your Worlds."},{"name":"account","summary":"Account","description":"Keys, webhooks, usage and billing of the workspace.","kind":"nav"},{"name":"keys","summary":"API keys","parent":"account"},{"name":"webhooks","summary":"Webhooks","parent":"account"},{"name":"billing","summary":"Plans and billing","parent":"account"},{"name":"signup","summary":"Sign-up","description":"How a workspace and its first key are had, without a key.","kind":"nav"},{"name":"assistant","summary":"Assistant","description":"The Director, a planner model that reads and acts on your Worlds through this API's own tools, with your key.","kind":"nav"}],"paths":{"/v1/health":{"get":{"operationId":"health","summary":"Is the API up","tags":["meta"],"security":[{}],"responses":{"200":{"description":"Up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Health"}}}}}}},"/v1/presets":{"get":{"operationId":"presets","x-assist":"read","summary":"The kinds of World that can be made","tags":["meta"],"security":[{}],"responses":{"200":{"description":"The presets.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Presets"}}}}}}},"/v1/openapi.json":{"get":{"operationId":"openapi","x-mcp":false,"summary":"This document, as JSON","tags":["meta"],"security":[{}],"responses":{"200":{"description":"The OpenAPI document the API is built and checked against.","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/v1/docs":{"get":{"operationId":"docs","x-mcp":false,"summary":"This document, as a reference page","tags":["meta"],"security":[{}],"responses":{"200":{"description":"An HTML page that renders `/v1/openapi.json`.","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/v1/mcp":{"post":{"operationId":"mcp","x-mcp":false,"summary":"This API as MCP tools (Model Context Protocol)","description":"A Streamable HTTP MCP endpoint. One JSON-RPC message per POST, answered as\nJSON. `tools/list` names one tool per operation of this document (but for\nthose marked `x-mcp: false`), generated from it, so the tools never fall\nbehind the API. `tools/call` runs the operation through the same router,\nwith the same key, limits and answers as a direct call. Listing is open;\ncalling a tool needs the key an ordinary request would.\n","tags":["meta"],"security":[{"apiKey":[]},{}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JsonRpcRequest"}}}},"responses":{"200":{"description":"The JSON-RPC response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JsonRpcResponse"}}}},"202":{"description":"A notification, accepted; there is nothing to answer."},"400":{"$ref":"#/components/responses/BadRequest"}}}},"/v1/me":{"get":{"operationId":"whoami","summary":"Who this key is","description":"The key's workspace, id, scopes and plan. Never the secret. Any key may ask, whatever its scopes.","tags":["meta"],"responses":{"200":{"description":"The key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Me"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/v1/operator/keys":{"post":{"operationId":"operatorIssueKey","x-mcp":false,"summary":"Mint a workspace's first key (the operator)","description":"For the service's operator, with the operator key rather than a workspace\nkey. Makes the workspace if it doesn't exist, then mints a key in it; the\nsecret is shown once. Absent (404) where no operator key is configured.\nEvery use is logged.\n","tags":["account"],"security":[{"operatorKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["workspace"],"properties":{"workspace":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]{0,62}$"},"scopes":{"type":"array","minItems":1,"items":{"$ref":"#/components/schemas/Scope"},"description":"Default: read, write, admin."},"label":{"type":"string","maxLength":128},"plan":{"type":"string","enum":["beta","starter","scale","internal"],"description":"Set the workspace's plan too."},"expiresInDays":{"type":"integer","minimum":1,"maximum":3650}}}}}},"responses":{"201":{"description":"The key, with its secret.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["workspace","workspaceMade","key"],"properties":{"workspace":{"type":"string"},"workspaceMade":{"type":"boolean"},"key":{"$ref":"#/components/schemas/KeyWithSecret"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/v1/signup/config":{"get":{"operationId":"signupConfig","x-mcp":false,"summary":"What the sign-up form needs","tags":["signup"],"security":[{}],"responses":{"200":{"description":"The Turnstile site key, and whether sign-up is available here.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupConfig"}}}}}}},"/v1/signup":{"post":{"operationId":"signup","x-mcp":false,"summary":"Ask for a workspace","description":"Checks the Turnstile token, then mails a single-use link, valid for 30\nminutes, to the address. The answer is the same whether or not the\naddress is known. A taken or reserved workspace name is said to be taken.\n","tags":["signup"],"security":[{}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupRequest"}}}},"responses":{"202":{"description":"A link is on its way, if the address can receive mail.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupPending"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"403":{"$ref":"#/components/responses/Forbidden"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"503":{"$ref":"#/components/responses/NotConfigured"}}}},"/v1/signup/verify":{"post":{"operationId":"signupVerify","x-mcp":false,"summary":"Use the mailed link","description":"Makes the workspace (on the beta plan) and its first owner key, whose secret is shown once.","tags":["signup"],"security":[{}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["token"],"properties":{"token":{"type":"string","description":"The `sbv_…` token from the link."}}}}}},"responses":{"201":{"description":"The workspace, and its owner key with the secret.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupVerified"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"409":{"$ref":"#/components/responses/Conflict"},"410":{"$ref":"#/components/responses/Gone"},"503":{"$ref":"#/components/responses/NotConfigured"}}}},"/v1/worlds":{"get":{"operationId":"listWorlds","x-assist":"read","summary":"The workspace's Worlds","tags":["worlds"],"responses":{"200":{"description":"The Worlds.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorldList"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}},"post":{"operationId":"createWorld","x-assist":"write","summary":"Make a World","tags":["worlds"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWorld"}}}},"responses":{"201":{"description":"The World.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/World"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PlanLimit"},"403":{"$ref":"#/components/responses/Forbidden"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/v1/worlds/{w}":{"parameters":[{"$ref":"#/components/parameters/World"}],"get":{"operationId":"getWorld","x-assist":"read","summary":"One World","tags":["worlds"],"responses":{"200":{"description":"The World.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/World"}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/v1/worlds/{w}/occupiers":{"parameters":[{"$ref":"#/components/parameters/World"}],"get":{"operationId":"listOccupiers","x-assist":"read","summary":"Who may hold time here","tags":["occupiers"],"responses":{"200":{"description":"The occupiers, the World's keeper among them.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["occupiers"],"properties":{"occupiers":{"type":"array","items":{"$ref":"#/components/schemas/Occupier"}}}}}}},"404":{"$ref":"#/components/responses/NotFound"}}},"post":{"operationId":"declareOccupier","x-assist":"write","summary":"Declare a holder, event or series","tags":["occupiers"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeclareOccupier"}}}},"responses":{"201":{"description":"The occupier.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["occupier"],"properties":{"occupier":{"$ref":"#/components/schemas/Occupier"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/v1/worlds/{w}/capacity":{"parameters":[{"$ref":"#/components/parameters/World"}],"post":{"operationId":"setCapacity","x-assist":"write","summary":"How many may hold one slot at once","tags":["occupiers"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["seats"],"properties":{"seats":{"type":"integer","minimum":1,"maximum":1024,"description":"Only grows."}}}}}},"responses":{"200":{"description":"The seats now.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["seats"],"properties":{"seats":{"type":"integer"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"}}}},"/v1/worlds/{w}/claims":{"parameters":[{"$ref":"#/components/parameters/World"}],"post":{"operationId":"claim","x-assist":"write","summary":"Claim slots through the door","description":"Judged in order: a stopped series, who already holds the slots (rank,\npinning, tie-break), capacity, then the claimant's own rules. A higher\nrank displaces a lower one only where the World allows it; the displaced\nparty is named, and offered somewhere else where one can be found.\n`soft: true` holds as intent that takes nothing until confirmed.\n","tags":["door"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimRequest"}}}},"responses":{"201":{"description":"The receipt.","headers":{"x-journal-head":{"$ref":"#/components/headers/JournalHead"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Receipt"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"402":{"$ref":"#/components/responses/PlanLimit"},"409":{"$ref":"#/components/responses/Refused"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/worlds/{w}/claims:explain":{"parameters":[{"$ref":"#/components/parameters/World"}],"post":{"operationId":"explainClaim","x-assist":"write","summary":"Judge a claim without making it","tags":["door"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimRequest"}}}},"responses":{"200":{"description":"It would be admitted.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["admissible"],"properties":{"admissible":{"type":"boolean","const":true}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"409":{"$ref":"#/components/responses/Refused"}}}},"/v1/worlds/{w}/releases":{"parameters":[{"$ref":"#/components/parameters/World"}],"post":{"operationId":"release","x-assist":"write","summary":"Give slots back","description":"Whoever queued for them is offered them first.","tags":["door"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"$ref":"#/components/requestBodies/WhoAt"},"responses":{"200":{"description":"The receipt.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Receipt"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"409":{"$ref":"#/components/responses/Refused"}}}},"/v1/worlds/{w}/handovers":{"parameters":[{"$ref":"#/components/parameters/World"}],"post":{"operationId":"handover","x-assist":"write","summary":"Pass slots from one party to another in one act","tags":["door"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/At"},{"type":"object","required":["from","to"],"properties":{"from":{"$ref":"#/components/schemas/OccupierRef"},"to":{"$ref":"#/components/schemas/OccupierRef"}}}]}}}},"responses":{"200":{"description":"The receipt.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Receipt"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"409":{"$ref":"#/components/responses/Refused"}}}},"/v1/worlds/{w}/confirmations":{"parameters":[{"$ref":"#/components/parameters/World"}],"post":{"operationId":"confirm","x-assist":"write","summary":"Make a soft hold firm","tags":["door"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"$ref":"#/components/requestBodies/WhoAt"},"responses":{"200":{"description":"The receipt.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Receipt"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"409":{"$ref":"#/components/responses/Refused"}}}},"/v1/worlds/{w}/give-ups":{"parameters":[{"$ref":"#/components/parameters/World"}],"post":{"operationId":"giveUp","x-assist":"write","summary":"Let a soft hold go","tags":["door"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"$ref":"#/components/requestBodies/WhoAt"},"responses":{"200":{"description":"The act, sealed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Acted"}}}},"400":{"$ref":"#/components/responses/BadRequest"}}}},"/v1/worlds/{w}/queue":{"parameters":[{"$ref":"#/components/parameters/World"}],"post":{"operationId":"queue","x-assist":"write","summary":"Wait in line for held slots","tags":["door"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"$ref":"#/components/requestBodies/WhoAt"},"responses":{"200":{"description":"The place in line.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["place","commitSeq","head"],"properties":{"place":{"type":"integer","minimum":1},"commitSeq":{"type":"integer"},"head":{"$ref":"#/components/schemas/Head"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"}}}},"/v1/worlds/{w}/sweeps":{"parameters":[{"$ref":"#/components/parameters/World"}],"post":{"operationId":"sweep","x-assist":"write","summary":"Lapse soft holds past their until","tags":["door"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"The act, sealed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Acted"}}}}}}},"/v1/worlds/{w}/offered":{"parameters":[{"$ref":"#/components/parameters/World"}],"get":{"operationId":"offered","x-assist":"read","summary":"Free slots at a position","tags":["reading"],"parameters":[{"$ref":"#/components/parameters/Date"},{"$ref":"#/components/parameters/Hour"},{"$ref":"#/components/parameters/Parametric"},{"$ref":"#/components/parameters/Coordinates"}],"responses":{"200":{"description":"What is free.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Position"},{"type":"object","required":["offered","slots"],"properties":{"parametric":true,"coordinates":true,"offered":{"$ref":"#/components/schemas/Mask"},"slots":{"$ref":"#/components/schemas/Slots"}}}],"unevaluatedProperties":false}}}},"400":{"$ref":"#/components/responses/BadRequest"}}}},"/v1/worlds/{w}/holdings":{"parameters":[{"$ref":"#/components/parameters/World"}],"get":{"operationId":"holdings","x-assist":"read","summary":"What one party holds at a position","tags":["reading"],"parameters":[{"name":"who","in":"query","required":true,"schema":{"type":"string"},"description":"An occupier's id or unique name."},{"$ref":"#/components/parameters/Date"},{"$ref":"#/components/parameters/Hour"},{"$ref":"#/components/parameters/Parametric"},{"$ref":"#/components/parameters/Coordinates"}],"responses":{"200":{"description":"Held and soft slots.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Position"},{"type":"object","required":["occupier","held","heldSlots","soft","softSlots"],"properties":{"occupier":{"$ref":"#/components/schemas/Occupier"},"held":{"$ref":"#/components/schemas/Mask"},"heldSlots":{"$ref":"#/components/schemas/Slots"},"soft":{"$ref":"#/components/schemas/Mask"},"softSlots":{"$ref":"#/components/schemas/Slots"}}}],"unevaluatedProperties":false}}}},"400":{"$ref":"#/components/responses/BadRequest"}}}},"/v1/worlds/{w}/journal":{"parameters":[{"$ref":"#/components/parameters/World"}],"get":{"operationId":"journal","x-assist":"read","summary":"Sealed commits, paged by sequence","description":"Each commit seals the previous one, so altering any past commit breaks every seal after it.","tags":["reading"],"parameters":[{"name":"since","in":"query","schema":{"type":"integer","minimum":0,"default":0}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":1000,"default":100}}],"responses":{"200":{"description":"The commits after `since`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Journal"}}}},"400":{"$ref":"#/components/responses/BadRequest"}}}},"/v1/worlds/{w}/planes":{"parameters":[{"$ref":"#/components/parameters/World"}],"get":{"operationId":"planes","x-assist":"read","summary":"Every plane's bits over a run of positions","description":"What a World holds, as bits: from the position named, for `positions` consecutive\npositions (days on an hour World, hours on a minute World), the free mask and every\noccupier plane with a bit set, with the address `key` journal entries name. Seat\nplanes are not listed. `seq` and `head` are the journal's as this was read: apply\n`GET …/journal?since=<seq>` entries (`plane = plane & ~clear | set` at `key`) to stay\ncurrent. `offered` leaves out foreign copies and proposed planes, as /offered does.\n","tags":["reading"],"parameters":[{"$ref":"#/components/parameters/Date"},{"$ref":"#/components/parameters/Hour"},{"$ref":"#/components/parameters/Parametric"},{"$ref":"#/components/parameters/Coordinates"},{"name":"positions","in":"query","schema":{"type":"integer","minimum":1,"maximum":31,"default":7},"description":"Positions from the one named: days, or hours on a minute World."}],"responses":{"200":{"description":"The planes, as of `seq`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Planes"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/v1/worlds/{w}/watch-tickets":{"parameters":[{"$ref":"#/components/parameters/World"}],"post":{"operationId":"watchTicket","summary":"A ticket to watch from a browser","description":"A browser cannot set a header on a WebSocket. The ticket works once, within 60 seconds, for this World only.\n\nThe body is optional. Its `name` and `color` are who this viewer is to the others\nwatching with presence; without a name, it is shown as the tail of the key.\n","tags":["watching"],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WatchTicketRequest"}}}},"responses":{"201":{"description":"The ticket.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["ticket","expiresAt"],"properties":{"ticket":{"type":"string","pattern":"^wt_"},"expiresAt":{"$ref":"#/components/schemas/Millis"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/worlds/{w}/watch":{"parameters":[{"$ref":"#/components/parameters/World"}],"get":{"operationId":"watch","x-mcp":false,"summary":"Every event, as it commits (WebSocket)","description":"Upgrade to a WebSocket with the API key, or with `?ticket=` from a browser.\nThe first message is `{\"type\":\"hello\",\"world\":…}`; each after it is a\n`WorldEvent`. Send `ping` to receive `pong`.\n\nA `commit` event's `data` is `CommitEventData`: the act's operation and the\njournal commits it sealed (at most 8, in `/journal`'s shape), so a watcher can\nkeep its planes current without reading the journal. When they would not fit\nin 8 KB, or there are more than 8, `truncated: true` comes in their place:\nread `/journal?since=`. A replayed idempotent write sealed nothing and carries\n`commits: []`.\n\n**Presence** (only with `presence=true`): after `hello` the socket gets\n`presence.roster`, then `presence.joined`, `presence.left` and `presence` frames\n(`PresenceOut`), and may send `PresenceIn` frames: JSON text, at most 512 bytes, at\nmost 10 a second per socket (bursts of 20) and 60 a second per World; excess is\ndropped, and a socket that keeps flooding (more than 50 drops in 10 seconds) is\nclosed with 1008. At most 32 presence sockets per World and 8 per key; later ones\nget `presence.full` and watch without presence. A viewer's name and colour come\nfrom its ticket (or `name`, with a key); `keyTail` is the last 4 characters of the\nissuing key's id. Presence is motion: it never touches the World's record, journal,\ncommand log or webhooks, and is not metered. `ping` is answered `pong` without\nwaking the World.\n","tags":["watching"],"security":[{"apiKey":[]},{}],"parameters":[{"name":"ticket","in":"query","schema":{"type":"string","pattern":"^wt_"},"description":"A watch ticket, in place of the key."},{"name":"presence","in":"query","schema":{"type":"boolean","default":false},"description":"Also carry presence."},{"name":"name","in":"query","schema":{"type":"string","minLength":1,"maxLength":32},"description":"With a key header (not a ticket): the name others see."},{"name":"Upgrade","in":"header","required":true,"schema":{"type":"string","const":"websocket"}}],"x-websocket":{"receive":{"$ref":"#/components/schemas/WatchFrame"},"send":{"$ref":"#/components/schemas/PresenceIn"}},"responses":{"101":{"description":"Switched to a WebSocket; messages are `WatchFrame`s."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"426":{"description":"Not a WebSocket upgrade.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/worlds/{w}/hands":{"parameters":[{"$ref":"#/components/parameters/World"}],"get":{"operationId":"listHands","x-assist":"read","summary":"Hands taken in here","tags":["relays"],"responses":{"200":{"description":"The hands, and the root each was taken in at.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["hands"],"properties":{"hands":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["hand","root"],"properties":{"hand":{"$ref":"#/components/schemas/GlobalName"},"root":{"type":["string","null"]}}}}}}}}}}},"post":{"operationId":"takeIn","x-assist":"write","summary":"Take a hand in (again refreshes it)","description":"A hand in another workspace needs a `see` grant from it.","tags":["relays"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["hand"],"properties":{"hand":{"type":"string","description":"`world` of this workspace, or `workspace/world`."}}}}}},"responses":{"200":{"description":"Taken in.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["hand","occupier","root","commitSeq","head"],"properties":{"hand":{"$ref":"#/components/schemas/GlobalName"},"occupier":{"type":"integer"},"root":{"type":["string","null"]},"commitSeq":{"type":"integer"},"head":{"$ref":"#/components/schemas/Head"}}}}}},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/v1/worlds/{w}/relays":{"parameters":[{"$ref":"#/components/parameters/World"}],"get":{"operationId":"listRelays","x-assist":"read","summary":"Relays planned here","tags":["relays"],"responses":{"200":{"description":"The relays.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["relays"],"properties":{"relays":{"type":"array","items":{"$ref":"#/components/schemas/Relay"}}}}}}}}},"post":{"operationId":"layRelay","x-assist":"write","summary":"Lay a relay out","tags":["relays"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LayRelay"}}}},"responses":{"201":{"description":"The relay, unasked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Relay"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"403":{"$ref":"#/components/responses/Forbidden"},"409":{"$ref":"#/components/responses/Refused"},"422":{"$ref":"#/components/responses/Unprocessable"}}}},"/v1/worlds/{w}/relays/{r}":{"parameters":[{"$ref":"#/components/parameters/World"},{"$ref":"#/components/parameters/RelayName"}],"get":{"operationId":"getRelay","x-assist":"read","summary":"Where a relay stands, and what may be done next","tags":["relays"],"responses":{"200":{"description":"The relay.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Relay"}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/v1/worlds/{w}/relays/{r}/windows":{"parameters":[{"$ref":"#/components/parameters/World"},{"$ref":"#/components/parameters/RelayName"}],"get":{"operationId":"relayWindows","x-assist":"read","summary":"Every start where the whole relay fits","tags":["relays"],"parameters":[{"$ref":"#/components/parameters/Date"},{"$ref":"#/components/parameters/Hour"},{"$ref":"#/components/parameters/Parametric"},{"$ref":"#/components/parameters/Coordinates"},{"name":"positions","in":"query","schema":{"type":"integer","minimum":1,"maximum":512,"default":7}}],"responses":{"200":{"description":"The starts, or the leg the search died at.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["starts","blockedAt"],"properties":{"starts":{"type":"array","items":{"$ref":"#/components/schemas/Moment"}},"blockedAt":{"oneOf":[{"type":"null"},{"type":"object","required":["leg","hand"],"properties":{"leg":{"type":"integer"},"hand":{"type":"string"}}}]}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"422":{"$ref":"#/components/responses/Unprocessable"}}}},"/v1/worlds/{w}/relays/{r}/acts":{"parameters":[{"$ref":"#/components/parameters/World"},{"$ref":"#/components/parameters/RelayName"}],"post":{"operationId":"relayAct","x-assist":"write","summary":"Ask, sync, withdraw, or delegate a leg","description":"`ask` sends one ask per leg; nothing is held until each hand says yes.\n`sync` fetches the answers. `withdraw` takes every ask and held leg back.\n`delegate` asks another hand for one leg at the same slots.\n","tags":["relays"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RelayAct"}}}},"responses":{"200":{"description":"The relay after the act, and what changed.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/RelayBody"},{"type":"object","required":["told"],"properties":{"told":{"type":"array","items":{"$ref":"#/components/schemas/Told"}}}}],"unevaluatedProperties":false}}}},"400":{"$ref":"#/components/responses/BadRequest"},"403":{"$ref":"#/components/responses/Forbidden"},"409":{"$ref":"#/components/responses/Refused"},"503":{"$ref":"#/components/responses/NotConfigured"}}}},"/v1/worlds/{w}/asks":{"parameters":[{"$ref":"#/components/parameters/World"}],"get":{"operationId":"listAsks","x-assist":"read","summary":"What planners have asked of this World","tags":["asks"],"responses":{"200":{"description":"The asks, and what each has become.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["asks"],"properties":{"asks":{"type":"array","items":{"$ref":"#/components/schemas/Ask"}}}}}}}}}},"/v1/worlds/{w}/asks/{token}/answer":{"parameters":[{"$ref":"#/components/parameters/World"},{"name":"token","in":"path","required":true,"schema":{"$ref":"#/components/schemas/Token"}}],"post":{"operationId":"answerAsk","x-assist":"write","summary":"Answer an ask","tags":["asks"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["verdict"],"properties":{"verdict":{"type":"string","enum":["accept","reject","takeBack","moveTo"]},"slots":{"$ref":"#/components/schemas/SlotsInput"}}}}}},"responses":{"200":{"description":"The answer, sealed.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["answer","commitSeq","head"],"properties":{"answer":{"$ref":"#/components/schemas/Answer"},"commitSeq":{"type":"integer"},"head":{"$ref":"#/components/schemas/Head"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"409":{"$ref":"#/components/responses/Refused"}}}},"/v1/grants":{"get":{"operationId":"listGrants","summary":"Grants given and received","tags":["grants"],"responses":{"200":{"description":"Standing grants only.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["given","received"],"properties":{"given":{"type":"array","items":{"$ref":"#/components/schemas/Grant"}},"received":{"type":"array","items":{"$ref":"#/components/schemas/Grant"}}}}}}}}},"post":{"operationId":"giveGrant","summary":"Let another workspace see or ask your Worlds","description":"Takes `admin`. `ask` requires `see`. A revocation reaches every World within 5 seconds.","tags":["grants"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["to","can"],"properties":{"to":{"type":"string","description":"The workspace, or one of its Worlds as `workspace/world`."},"world":{"type":"string","default":"*","description":"One of your Worlds, or `*` for all."},"can":{"type":"array","minItems":1,"items":{"type":"string","enum":["see","ask"]}}}}}}},"responses":{"201":{"description":"The grant.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Grant"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/v1/grants/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^gr_"}}],"delete":{"operationId":"revokeGrant","summary":"Revoke a grant you gave","tags":["grants"],"responses":{"200":{"description":"Revoked.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["revoked"],"properties":{"revoked":{"type":"string"}}}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/v1/keys":{"get":{"operationId":"listKeys","summary":"The workspace's keys","description":"Takes `admin`. Revoked and expired keys too, oldest first; never a secret.","tags":["keys"],"responses":{"200":{"description":"The keys.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["keys"],"properties":{"keys":{"type":"array","items":{"$ref":"#/components/schemas/Key"}}}}}}},"403":{"$ref":"#/components/responses/Forbidden"}}},"post":{"operationId":"createKey","summary":"Mint a key","description":"Takes `admin`. A key never grants more than the key that makes it holds. The secret is shown once.","tags":["keys"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["scopes"],"properties":{"scopes":{"type":"array","minItems":1,"items":{"$ref":"#/components/schemas/Scope"}},"label":{"type":"string"},"expiresInDays":{"type":"integer","minimum":1,"maximum":3650}}}}}},"responses":{"201":{"description":"The key, with its secret.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KeyWithSecret"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"403":{"$ref":"#/components/responses/Forbidden"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/v1/keys/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^key_"}}],"delete":{"operationId":"revokeKey","summary":"Revoke a key","tags":["keys"],"responses":{"200":{"description":"The key, now revoked. Saying it twice changes nothing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Key"}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/v1/keys/{id}:rotate":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^key_"}}],"post":{"operationId":"rotateKey","summary":"Replace a key with a successor","description":"The old key retires at once, unless `graceSeconds` lets both work a while.","tags":["keys"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"graceSeconds":{"type":"integer","minimum":0,"maximum":86400,"default":0},"expiresInDays":{"type":"integer","minimum":1,"maximum":3650}}}}}},"responses":{"201":{"description":"The successor, with its secret, and the key it retired.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/KeyFields"},{"type":"object","required":["secret","retired"],"properties":{"secret":{"$ref":"#/components/schemas/Secret"},"retired":{"type":"object","additionalProperties":false,"required":["id","revokedAt"],"properties":{"id":{"type":"string"},"revokedAt":{"$ref":"#/components/schemas/Millis"}}}}}],"unevaluatedProperties":false}}}},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/v1/webhooks":{"get":{"operationId":"listWebhooks","summary":"Where events are posted","tags":["webhooks"],"responses":{"200":{"description":"The webhooks, without their secrets.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["webhooks"],"properties":{"webhooks":{"type":"array","items":{"$ref":"#/components/schemas/Webhook"}}}}}}}}},"post":{"operationId":"createWebhook","summary":"Post events to a URL","description":"At most 10 per workspace. The secret, which signs every delivery, is shown once.","tags":["webhooks"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri","pattern":"^https://"},"events":{"type":"array","minItems":1,"items":{"type":"string","enum":["*","claim.made","claim.released","ask.received","ask.withdrawn","ask.answered","relay.acted"]}}}}}}},"responses":{"201":{"description":"The webhook, with its secret.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Webhook"},{"type":"object","required":["secret"],"properties":{"secret":{"type":"string","pattern":"^whsec_"}}}],"unevaluatedProperties":false}}}},"400":{"$ref":"#/components/responses/BadRequest"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/v1/webhooks/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^wh_"}}],"delete":{"operationId":"deleteWebhook","summary":"Stop posting to a webhook","tags":["webhooks"],"responses":{"200":{"description":"Deleted.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["deleted"],"properties":{"deleted":{"type":"string"}}}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/v1/usage":{"get":{"operationId":"usage","summary":"This month's use against the plan","tags":["billing"],"responses":{"200":{"description":"The period, the counts, and the plan's limits.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Usage"}}}}}}},"/v1/billing":{"get":{"operationId":"billing","summary":"The plan, the subscription, and the plans on sale","tags":["billing"],"responses":{"200":{"description":"Billing as it stands.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Billing"}}}}}}},"/v1/billing/checkout":{"post":{"operationId":"checkout","summary":"Buy a plan","description":"Answers the URL of Stripe Checkout (or, under mock billing, the console's stand-in).","tags":["billing"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["plan"],"properties":{"plan":{"type":"string","enum":["starter","scale"]}}}}}},"responses":{"200":{"description":"Where to send the buyer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["url","id"],"properties":{"url":{"type":"string","format":"uri"},"id":{"type":"string"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"409":{"$ref":"#/components/responses/Conflict"},"502":{"$ref":"#/components/responses/BadGateway"},"503":{"$ref":"#/components/responses/NotConfigured"}}}},"/v1/billing/portal":{"post":{"operationId":"portal","summary":"Manage the subscription","tags":["billing"],"responses":{"200":{"description":"Where to send the customer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["url"],"properties":{"url":{"type":"string","format":"uri"}}}}}},"409":{"$ref":"#/components/responses/Conflict"},"503":{"$ref":"#/components/responses/NotConfigured"}}}},"/v1/billing/mock/{act}":{"parameters":[{"name":"act","in":"path","required":true,"schema":{"type":"string","enum":["complete","switch","cancel","fail","recover"]}}],"post":{"operationId":"mockBillingAct","summary":"Act at mock checkout or the mock portal (dev only)","description":"Only under mock billing, which is never on in prod. Each act becomes the\nStripe event it stands for, run through the webhook's own code.\n","tags":["billing"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"plan":{"type":"string","enum":["starter","scale"],"description":"For `complete` and `switch`."}}}}}},"responses":{"200":{"description":"The plan after the act.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MockActed"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/v1/stripe/webhook":{"post":{"operationId":"stripeWebhook","x-mcp":false,"summary":"Stripe's events (Stripe calls this)","description":"No API key; the `Stripe-Signature` header is the authentication.","tags":["billing"],"security":[{}],"parameters":[{"name":"Stripe-Signature","in":"header","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Received.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"503":{"$ref":"#/components/responses/NotConfigured"}}}},"/v1/assist":{"post":{"operationId":"assist","x-mcp":false,"summary":"Let the Director read or act on your Worlds, step by step (server-sent events)","description":"Runs claude-opus-5 over the operations marked `x-assist`, calling each through this\nAPI's MCP tools with **your** key: scopes, grants, rate limits, the write quota and\nrefusals apply as if you had called it. `look` offers only `x-assist: read` tools and\nworks with a read key; `act` needs `write`. Keys, webhooks, grants, billing, sign-up\nand watching are never offered. Calls outside `worlds`/`hands`, or a createWorld\nwithout `allowCreate`, are denied before they are made. Each step streams as it\nhappens; the stream ends with `stop`. Your prompt and the answers of its calls are\nsent to Anthropic; your schedule-bit key is not.\n\n**Whose Anthropic key.** Send your own in `anthropicKey` and the run is on your\nAnthropic account: the key is used for this request only, never stored, logged or\nstreamed back, and the run is not counted against your plan's assists or the\ndeployment's daily ceiling (it still takes the one-run lease and every per-run bound).\nWithout one, the run spends the deployment's ANTHROPIC_API_KEY and is counted. `open`\nsays which (`key`). If Anthropic refuses your key, the stream ends with a `problem`\ntitled `Assistant Key Rejected`, then `stop`, and the run counts as one of the\nworkspace's key checks (see `assistKeyCheck`); with those spent, a run on your own key\nanswers 429 until they refill. 503 when there is no key to run on (none sent, none\nconfigured), while the assistant is switched off, or, for a run on the deployment's\nkey, once its daily ceiling is spent.\n\nOne assist runs at a time per key. There is no resume: a dropped stream stops the\nrun, and the calls already made stand (the journal shows them). A keepalive comment\n(`: ka`) is sent every 15 seconds.\n","tags":["assistant"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssistRequest"}}}},"responses":{"200":{"description":"One event per step, ending with `stop`.","content":{"text/event-stream":{"schema":{"type":"string"},"itemSchema":{"type":"object","required":["event","data"],"properties":{"event":{"type":"string"},"id":{"type":"string"},"data":{"type":"string","contentMediaType":"application/json","contentSchema":{"$ref":"#/components/schemas/AssistEvent"}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"description":"This month's assists are spent (runs on the deployment's key only); `Retry-After` is when the month turns.","headers":{"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/TooManyRequests"},"503":{"description":"No Anthropic key to run on, switched off, or paused for the day; `detail` says which.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/assist/config":{"get":{"operationId":"assistConfig","x-mcp":false,"summary":"Whether the Director is offered here, to this key, on whose Anthropic key, and this month's use","description":"`available` is true while the assistant is on here: a run on your own Anthropic key\ncan then always start. `reason`, when not null, says what stops a run on the\ndeployment's key (none configured, the day or this month spent), and so when to bring\nyour own. `keys` says which a run may use. `modes` are those this key may use now:\n`look` needs `read`, `act` needs `write`. `month` counts runs on the deployment's key.\n","tags":["assistant"],"responses":{"200":{"description":"Availability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssistConfig"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/v1/assist/key-check":{"post":{"operationId":"assistKeyCheck","x-mcp":false,"summary":"Check an Anthropic key before a run spends it","description":"Asks Anthropic whether it takes the key, the cheapest way there is: one page of its\nModels API, which spends no tokens. The key is used for that question only, never\nstored or logged, and the answer does not repeat it. Anthropic out of reach answers\n200 with `valid: false` and a `detail` that says the key was not checked, so a client\nreads one shape; try again. Rate-limited and metered like any read; needs `read`.\nEach check is also a call to Anthropic from this deployment, so a workspace has\nAnthropic keys judged at most 10 times a minute and 100 times a UTC day (checks, and\nruns on your own key that Anthropic refused); past that, 429 with `Retry-After`.\n503 while the assistant is switched off.\n","tags":["assistant"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssistKeyCheckRequest"}}}},"responses":{"200":{"description":"What Anthropic said of the key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssistKeyCheck"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"description":"Over the per-minute rate, or the workspace's key checks for the minute or the day are spent; `Retry-After` says when to try again.","headers":{"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"The assistant is switched off here.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}}},"webhooks":{"worldEvent":{"post":{"operationId":"worldEventDelivery","summary":"An event, posted to your webhook","description":"Verify `x-schedule-bit-signature` (`t=<unix seconds>,v1=<hex HMAC-SHA256\nof \"<t>.<body>\" with the webhook secret>`) and refuse a `t` older than five\nminutes. Answer 2xx to stop retries; `410` stops deliveries to you for good.\n","tags":["webhooks"],"parameters":[{"name":"x-schedule-bit-event","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-schedule-bit-delivery","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-schedule-bit-signature","in":"header","required":true,"schema":{"type":"string","pattern":"^t=\\d+,v1=[0-9a-f]{64}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorldEvent"}}}},"responses":{"200":{"description":"Received."},"410":{"description":"Gone; no more deliveries."}}}}},"components":{"securitySchemes":{"operatorKey":{"type":"http","scheme":"bearer","bearerFormat":"sbo_…","description":"The service operator's key; opens /v1/operator only."},"apiKey":{"type":"http","scheme":"bearer","bearerFormat":"sbk_…","description":"A workspace key, scoped `read`, `write` and/or `admin`."}},"parameters":{"World":{"name":"w","in":"path","required":true,"schema":{"$ref":"#/components/schemas/WorldName"},"description":"A World of the key's workspace."},"RelayName":{"name":"r","in":"path","required":true,"schema":{"$ref":"#/components/schemas/WorldName"}},"IdempotencyKey":{"name":"Idempotency-Key","in":"header","schema":{"type":"string","minLength":1,"maxLength":255},"description":"The same key and body answer the same for 24 hours."},"Date":{"name":"date","in":"query","schema":{"type":"string","format":"date"},"description":"A UTC day."},"Hour":{"name":"hour","in":"query","schema":{"type":"integer","minimum":0,"maximum":23},"description":"The hour, on a `temporal-minute` World."},"Parametric":{"name":"parametric","in":"query","schema":{"type":"integer"},"description":"The year, in place of `date`."},"Coordinates":{"name":"coordinates","in":"query","style":"form","explode":false,"schema":{"type":"array","items":{"type":"integer"}},"description":"Month (0–11), day (1–31)[, hour], with `parametric`."}},"requestBodies":{"WhoAt":{"required":true,"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/At"},{"type":"object","required":["who"],"properties":{"who":{"$ref":"#/components/schemas/OccupierRef"}}}]}}}}},"headers":{"JournalHead":{"description":"The World's journal head after the act.","schema":{"$ref":"#/components/schemas/Head"}},"RetryAfter":{"description":"Seconds to wait.","schema":{"type":"integer"}}},"responses":{"BadRequest":{"description":"The request cannot be read.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"Unauthorized":{"description":"No key, or a key that is unknown, revoked or expired.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"Forbidden":{"description":"The key lacks the scope, or the World belongs to a workspace that granted nothing.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"NotFound":{"description":"No such thing in this workspace.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"Conflict":{"description":"It cannot be done as things stand.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"Refused":{"description":"The engine refused, and says why in `refusal`.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/RefusalProblem"}}}},"Gone":{"description":"Used already, or expired.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"PlanLimit":{"description":"Over the plan (the month's writes, or its Worlds). Waiting will not help; a bigger plan will.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"TooManyRequests":{"description":"Over the per-minute rate.","headers":{"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"Unprocessable":{"description":"A relay that cannot be laid out or looked across.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"BadGateway":{"description":"Stripe did not answer as it should.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"NotConfigured":{"description":"A third party this needs is not configured here; `detail` names which.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"schemas":{"Millis":{"type":"integer","description":"Unix milliseconds."},"Mask":{"type":"string","pattern":"^0x[0-9a-f]+$","description":"Slots as a hex bitmask: bit n is slot n."},"Slots":{"type":"array","items":{"type":"integer","minimum":0},"description":"Slot indices."},"SlotsInput":{"oneOf":[{"$ref":"#/components/schemas/Slots"},{"$ref":"#/components/schemas/Mask"}]},"Head":{"type":"string","pattern":"^[0-9a-f]{32}$","description":"A journal seal."},"Token":{"type":"string","pattern":"^[0-9a-f]{32}$","description":"An ask's content token, the same on both sides."},"WorldName":{"type":"string","pattern":"^[a-z0-9][a-z0-9._-]{0,62}$"},"GlobalName":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]*/[a-z0-9][a-z0-9._-]*$","description":"`workspace/world`."},"Scope":{"type":"string","enum":["read","write","admin"]},"Secret":{"type":"string","pattern":"^sbk_[A-Za-z0-9_]+$","description":"Shown once."},"OccupierRef":{"oneOf":[{"type":"integer"},{"type":"string"}],"description":"An occupier's id, or its unique name."},"Position":{"type":"object","required":["parametric","coordinates"],"properties":{"parametric":{"type":"integer","description":"The year."},"coordinates":{"type":"array","items":{"type":"integer"}}}},"Moment":{"type":"object","additionalProperties":false,"required":["parametric","coordinates","slot"],"properties":{"parametric":{"type":"integer"},"coordinates":{"type":"array","items":{"type":"integer"}},"slot":{"type":"integer","minimum":0}}},"At":{"type":"object","description":"A position (`date`[, `hour`], or `parametric` + `coordinates`) and `slots`.","required":["slots"],"properties":{"date":{"type":"string","format":"date"},"hour":{"type":"integer","minimum":0,"maximum":23},"parametric":{"type":"integer"},"coordinates":{"type":"array","items":{"type":"integer"}},"slots":{"$ref":"#/components/schemas/SlotsInput"}}},"Problem":{"type":"object","description":"RFC 9457 problem details; extension members may follow.","required":["type","title","status","detail"],"properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string","description":"A sentence a person can read."}}},"Refusal":{"type":"object","required":["by"],"description":"The engine's reason. `by` names the guard; the other members depend on it.","properties":{"by":{"type":"string","enum":["held","rule","rest","horizon","capacity","foreign","past","order","stale","stopped","open","untaken","unknown","unasked"]},"conflictsWith":{"type":"array","items":{"type":"string"}},"slots":{"$ref":"#/components/schemas/Mask"}}},"RefusalProblem":{"allOf":[{"$ref":"#/components/schemas/Problem"},{"type":"object","required":["refusal"],"properties":{"refusal":{"$ref":"#/components/schemas/Refusal"}}}]},"Health":{"type":"object","additionalProperties":false,"required":["ok"],"properties":{"ok":{"type":"boolean","const":true}}},"Presets":{"type":"object","additionalProperties":false,"required":["presets"],"properties":{"presets":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["id","position","leafSlotBits"],"properties":{"id":{"type":"string","enum":["temporal-hour","temporal-minute"]},"position":{"type":"string","enum":["day","hour"]},"leafSlotBits":{"type":"integer"}}}}}},"Me":{"type":"object","additionalProperties":false,"required":["workspace","key","plan"],"properties":{"workspace":{"type":"string"},"key":{"type":"object","additionalProperties":false,"required":["id","label","hint","scopes","expiresAt"],"properties":{"id":{"type":"string","description":"As `/v1/keys` lists it: `key_…` for keys minted by the API."},"label":{"type":["string","null"]},"hint":{"type":["string","null"],"description":"`sbk_…` and the last four characters."},"scopes":{"type":"array","items":{"$ref":"#/components/schemas/Scope"}},"expiresAt":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/Millis"}]}}},"plan":{"type":"object","additionalProperties":false,"required":["id","name"],"properties":{"id":{"type":"string"},"name":{"type":"string"}}}}},"SignupConfig":{"type":"object","additionalProperties":false,"required":["turnstileSitekey","available"],"properties":{"turnstileSitekey":{"type":["string","null"]},"available":{"type":"boolean"}}},"SignupRequest":{"type":"object","required":["email","workspace","turnstileToken"],"properties":{"email":{"type":"string","format":"email"},"workspace":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]{0,62}$"},"turnstileToken":{"type":"string"}}},"SignupPending":{"type":"object","additionalProperties":false,"required":["status","detail","expiresInSeconds"],"properties":{"status":{"type":"string","const":"pending"},"detail":{"type":"string"},"expiresInSeconds":{"type":"integer"}}},"SignupVerified":{"type":"object","additionalProperties":false,"required":["workspace","plan","ownerEmail","key"],"properties":{"workspace":{"type":"string"},"plan":{"type":"string"},"ownerEmail":{"type":"string","format":"email"},"key":{"$ref":"#/components/schemas/KeyWithSecret"}}},"CreateWorld":{"type":"object","required":["name"],"properties":{"name":{"$ref":"#/components/schemas/WorldName"},"preset":{"type":"string","enum":["temporal-hour","temporal-minute"],"default":"temporal-hour"},"allowDisplace":{"type":"boolean","default":false,"description":"May a higher rank displace a lower one."},"tieBreak":{"type":"string","enum":["incumbent","first-come","id"],"default":"incumbent"}}},"World":{"type":"object","additionalProperties":false,"required":["name","globalName","preset","leafSlotBits","allowDisplace","tieBreak","seats","occupiers","relays","seq","head"],"properties":{"name":{"$ref":"#/components/schemas/WorldName"},"globalName":{"$ref":"#/components/schemas/GlobalName"},"preset":{"type":"string"},"leafSlotBits":{"type":"integer"},"allowDisplace":{"type":"boolean"},"tieBreak":{"type":"string"},"seats":{"type":"integer"},"occupiers":{"type":"integer","description":"Occupiers other than seats, the keeper among them."},"relays":{"type":"integer"},"seq":{"type":"integer","description":"Commits in the journal."},"head":{"$ref":"#/components/schemas/Head"}}},"WorldList":{"type":"object","additionalProperties":false,"required":["worlds"],"properties":{"worlds":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["name","preset","createdAt"],"properties":{"name":{"$ref":"#/components/schemas/WorldName"},"preset":{"type":"string"},"createdAt":{"$ref":"#/components/schemas/Millis"}}}}}},"DeclareOccupier":{"type":"object","required":["name"],"properties":{"name":{"type":"string","minLength":1,"maxLength":128},"kind":{"type":"string","enum":["holder","event","series"],"default":"holder"},"holder":{"$ref":"#/components/schemas/OccupierRef"},"rank":{"type":"integer"},"pinned":{"type":"boolean"}}},"Occupier":{"type":"object","additionalProperties":false,"required":["id","kind","name","rank","pinned","holder"],"properties":{"id":{"type":"integer"},"kind":{"type":"string","enum":["holder","event","series","foreign"]},"name":{"type":"string"},"rank":{"type":"integer"},"pinned":{"type":"boolean"},"holder":{"type":["string","null"],"description":"Whose name an event or series stands in."},"keeper":{"type":"boolean","const":true,"description":"The World's own holder, named with its global name."}}},"ClaimRequest":{"allOf":[{"$ref":"#/components/schemas/At"},{"type":"object","required":["who"],"properties":{"who":{"$ref":"#/components/schemas/OccupierRef"},"rank":{"type":"integer"},"soft":{"type":"boolean","description":"Hold as intent, outside occupancy."},"until":{"$ref":"#/components/schemas/Millis"}}}]},"Receipt":{"type":"object","additionalProperties":false,"required":["wrote","slots","displaced","commitSeq","head"],"properties":{"wrote":{"$ref":"#/components/schemas/Mask"},"slots":{"$ref":"#/components/schemas/Slots"},"displaced":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["occupier","slots","offered"],"properties":{"occupier":{"type":"string"},"slots":{"$ref":"#/components/schemas/Slots"},"offered":{"oneOf":[{"type":"null"},{"type":"object","additionalProperties":false,"required":["parametric","coordinates","slots"],"properties":{"parametric":{"type":"integer"},"coordinates":{"type":"array","items":{"type":"integer"}},"slots":{"$ref":"#/components/schemas/Slots"}}}]}}}},"commitSeq":{"type":"integer"},"head":{"$ref":"#/components/schemas/Head"}}},"Acted":{"type":"object","additionalProperties":false,"required":["commitSeq","head"],"properties":{"commitSeq":{"type":"integer"},"head":{"$ref":"#/components/schemas/Head"}}},"Journal":{"type":"object","additionalProperties":false,"required":["head","seq","commits"],"properties":{"head":{"$ref":"#/components/schemas/Head"},"seq":{"type":"integer"},"commits":{"type":"array","items":{"$ref":"#/components/schemas/JournalCommit"}}}},"JournalCommit":{"type":"object","additionalProperties":false,"required":["seq","tick","actor","kind","ref","prevHash","hash","entries"],"properties":{"seq":{"type":"integer"},"tick":{"$ref":"#/components/schemas/Millis"},"actor":{"type":["string","null"]},"kind":{"type":"string"},"ref":{"type":["string","null"]},"prevHash":{"$ref":"#/components/schemas/Head"},"hash":{"$ref":"#/components/schemas/Head"},"entries":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["occupier","occupierId","role","key","set","clear"],"properties":{"occupier":{"type":"string","description":"The name; not unique for events and series."},"occupierId":{"type":"integer","description":"The occupier id; unique, as /planes names it."},"role":{"type":"string","enum":["held","intent","proposed"]},"key":{"type":"integer","description":"The address key of the position."},"set":{"$ref":"#/components/schemas/Mask"},"clear":{"$ref":"#/components/schemas/Mask"}}}}}},"Planes":{"type":"object","additionalProperties":false,"required":["seq","head","leafSlotBits","seats","positions"],"properties":{"seq":{"type":"integer","minimum":0},"head":{"$ref":"#/components/schemas/Head"},"leafSlotBits":{"type":"integer"},"seats":{"type":"integer","minimum":1},"positions":{"type":"array","maxItems":31,"items":{"type":"object","additionalProperties":false,"required":["parametric","coordinates","key","offered","planes"],"properties":{"parametric":{"type":"integer"},"coordinates":{"type":"array","items":{"type":"integer"}},"key":{"type":"integer","description":"The address key, as journal entries name it."},"offered":{"$ref":"#/components/schemas/Mask"},"planes":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["occupier","id","kind","role","mask"],"properties":{"occupier":{"type":"string","description":"The name; not unique for events and series."},"id":{"type":"integer","description":"The occupier id; unique."},"kind":{"type":"string","enum":["holder","event","series","foreign"]},"role":{"type":"string","enum":["held","intent","proposed"]},"mask":{"$ref":"#/components/schemas/Mask"}}}}}}}}},"Standing":{"type":"string","enum":["unasked","asked","held","refused","withdrawn","released"]},"LayRelay":{"type":"object","required":["name","legs"],"properties":{"name":{"$ref":"#/components/schemas/WorldName"},"legs":{"type":"array","minItems":1,"maxItems":32,"items":{"type":"object","required":["hand","length"],"properties":{"hand":{"type":"string"},"length":{"type":"integer","minimum":1},"gapAfter":{"type":"integer","minimum":0},"after":{"type":"array","items":{"type":"integer","minimum":0}}}}}}},"RelayBody":{"type":"object","required":["name","standing","legs","shortfalls","head","possible"],"properties":{"name":{"type":"string"},"standing":{"oneOf":[{"$ref":"#/components/schemas/Standing"},{"type":"string","const":"mixed"}]},"legs":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["leg","hand","standing","pieces","because","length"],"properties":{"leg":{"type":"integer"},"hand":{"type":"string"},"standing":{"$ref":"#/components/schemas/Standing"},"pieces":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["parametric","coordinates","slots","token","standing","restsOn"],"properties":{"parametric":{"type":"integer"},"coordinates":{"type":"array","items":{"type":"integer"}},"slots":{"$ref":"#/components/schemas/Slots"},"token":{"$ref":"#/components/schemas/Token"},"standing":{"$ref":"#/components/schemas/Standing"},"restsOn":{"oneOf":[{"type":"null"},{"type":"object","additionalProperties":false,"required":["seq","act","by"],"properties":{"seq":{"type":"integer"},"act":{"type":"string"},"by":{"type":"string"}}}]}}}},"because":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/Refusal"}]},"length":{"type":"integer"},"gapAfter":{"type":"integer"},"after":{"type":"array","items":{"type":"integer"}}}}},"shortfalls":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["leg","hand","by"],"properties":{"leg":{"type":"integer"},"hand":{"type":"string"},"by":{"type":"integer"}}}},"head":{"$ref":"#/components/schemas/Head"},"possible":{"type":"array","items":{"type":"string","enum":["ask","sync","withdraw","delegate"]}}}},"Relay":{"allOf":[{"$ref":"#/components/schemas/RelayBody"}],"unevaluatedProperties":false},"Told":{"type":"object","additionalProperties":false,"required":["leg","hand","from","to","slots"],"properties":{"leg":{"type":"integer"},"hand":{"type":"string"},"from":{"$ref":"#/components/schemas/Standing"},"to":{"$ref":"#/components/schemas/Standing"},"slots":{"$ref":"#/components/schemas/Slots"}}},"RelayAct":{"oneOf":[{"type":"object","required":["act","start"],"properties":{"act":{"const":"ask"},"start":{"type":"object","description":"A position and a slot.","required":["slot"],"properties":{"date":{"type":"string","format":"date"},"hour":{"type":"integer"},"parametric":{"type":"integer"},"coordinates":{"type":"array","items":{"type":"integer"}},"slot":{"type":"integer","minimum":0}}}}},{"type":"object","required":["act"],"properties":{"act":{"enum":["sync","withdraw"]}}},{"type":"object","required":["act","leg","to"],"properties":{"act":{"const":"delegate"},"leg":{"type":"integer","minimum":0},"to":{"type":"string","description":"Another hand: `world` or `workspace/world`."}}}]},"Ask":{"type":"object","additionalProperties":false,"required":["token","from","parametric","coordinates","slots","state","held","because"],"properties":{"token":{"$ref":"#/components/schemas/Token"},"from":{"$ref":"#/components/schemas/GlobalName"},"parametric":{"type":"integer"},"coordinates":{"type":"array","items":{"type":"integer"}},"slots":{"$ref":"#/components/schemas/Slots"},"state":{"type":["string","null"],"enum":["open","accepted","rejected","withdrawn","released",null]},"held":{"$ref":"#/components/schemas/Slots"},"because":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/Refusal"}]}}},"Answer":{"type":"object","additionalProperties":false,"required":["token","state","by","from","parametric","coordinates","slots","because","commitSeq","root"],"properties":{"token":{"$ref":"#/components/schemas/Token"},"state":{"type":"string","enum":["accepted","rejected","released"]},"by":{"$ref":"#/components/schemas/GlobalName"},"from":{"$ref":"#/components/schemas/GlobalName"},"parametric":{"type":"integer"},"coordinates":{"type":"array","items":{"type":"integer"}},"slots":{"$ref":"#/components/schemas/Slots"},"because":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/Refusal"}]},"commitSeq":{"type":"integer"},"root":{"type":"string"}}},"Grant":{"type":"object","additionalProperties":false,"required":["id","owner","world","to","can","createdAt"],"properties":{"id":{"type":"string","pattern":"^gr_"},"owner":{"type":"string","description":"The workspace that gave it."},"world":{"type":"string","description":"One of the owner's Worlds, or `*`."},"to":{"type":"string"},"can":{"type":"array","items":{"type":"string","enum":["see","ask"]}},"createdAt":{"$ref":"#/components/schemas/Millis"}}},"KeyFields":{"type":"object","required":["id","label","scopes","hint","state","createdAt","lastUsedAt","expiresAt","revokedAt","rotatedFrom"],"properties":{"id":{"type":"string","pattern":"^key_"},"label":{"type":["string","null"]},"scopes":{"type":"array","items":{"$ref":"#/components/schemas/Scope"}},"hint":{"type":["string","null"],"description":"`sbk_…` and the last four characters."},"state":{"type":"string","enum":["active","retiring","revoked","expired"]},"createdAt":{"$ref":"#/components/schemas/Millis"},"lastUsedAt":{"type":["integer","null"]},"expiresAt":{"type":["integer","null"]},"revokedAt":{"type":["integer","null"]},"rotatedFrom":{"type":["string","null"]}}},"Key":{"allOf":[{"$ref":"#/components/schemas/KeyFields"}],"unevaluatedProperties":false},"KeyWithSecret":{"allOf":[{"$ref":"#/components/schemas/KeyFields"},{"type":"object","required":["secret"],"properties":{"secret":{"$ref":"#/components/schemas/Secret"}}}],"unevaluatedProperties":false},"Webhook":{"type":"object","required":["id","url","events","createdAt"],"properties":{"id":{"type":"string","pattern":"^wh_"},"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string"}},"createdAt":{"$ref":"#/components/schemas/Millis"}}},"PlanView":{"type":"object","required":["id","name","limits"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"limits":{"type":"object","additionalProperties":false,"required":["requestsPerMinute","keyRequestsPerMinute","maxWorlds","monthlyWrites","assistsPerMonth"],"properties":{"requestsPerMinute":{"type":"integer"},"keyRequestsPerMinute":{"type":"integer"},"maxWorlds":{"type":"integer"},"monthlyWrites":{"type":"integer"},"assistsPerMonth":{"type":"integer","description":"Director runs (POST /v1/assist) a month on the deployment's Anthropic key; runs on your own key are not counted."}}}}},"Usage":{"type":"object","additionalProperties":false,"required":["workspace","period","usage","plan"],"properties":{"workspace":{"type":"string"},"period":{"type":"object","additionalProperties":false,"required":["id","start","end"],"properties":{"id":{"type":"string","pattern":"^\\d{4}-\\d{2}$"},"start":{"type":"string","format":"date-time"},"end":{"type":"string","format":"date-time"}}},"usage":{"type":"object","additionalProperties":false,"required":["requests","writes","worlds","assists"],"properties":{"requests":{"type":"integer"},"writes":{"type":"integer"},"worlds":{"type":"integer"},"assists":{"type":"integer","description":"Director runs started this month on the deployment's Anthropic key; runs on your own key are not counted."}}},"plan":{"allOf":[{"$ref":"#/components/schemas/PlanView"}],"unevaluatedProperties":false}}},"Billing":{"type":"object","additionalProperties":false,"required":["workspace","configured","mode","plan","customer","subscription","plans"],"properties":{"workspace":{"type":"string"},"configured":{"type":"boolean","description":"False when neither Stripe nor mock billing is set up here."},"mode":{"type":["string","null"],"enum":["stripe","mock",null]},"plan":{"allOf":[{"$ref":"#/components/schemas/PlanView"}],"unevaluatedProperties":false},"customer":{"type":"boolean"},"subscription":{"oneOf":[{"type":"null"},{"type":"object","additionalProperties":false,"required":["status","plan","currentPeriodEnd","cancelAtPeriodEnd","paymentFailedAt"],"properties":{"status":{"type":["string","null"]},"plan":{"type":["string","null"]},"currentPeriodEnd":{"type":["string","null"],"format":"date-time"},"cancelAtPeriodEnd":{"type":"boolean"},"paymentFailedAt":{"type":["string","null"],"format":"date-time"}}}]},"plans":{"type":"array","items":{"allOf":[{"$ref":"#/components/schemas/PlanView"},{"type":"object","required":["buyable"],"properties":{"buyable":{"type":"boolean"}}}],"unevaluatedProperties":false}}}},"MockActed":{"type":"object","additionalProperties":false,"required":["mock","event","plan","planName","subscription"],"properties":{"mock":{"const":true},"event":{"type":"object","additionalProperties":false,"required":["id","type"],"properties":{"id":{"type":"string"},"type":{"type":"string"}}},"plan":{"type":"string"},"planName":{"type":"string"},"subscription":{"type":"object","additionalProperties":false,"required":["status","cancelAtPeriodEnd","currentPeriodEnd"],"properties":{"status":{"type":["string","null"]},"cancelAtPeriodEnd":{"type":"boolean"},"currentPeriodEnd":{"type":["string","null"],"format":"date-time"}}}}},"JsonRpcRequest":{"type":"object","required":["jsonrpc","method"],"properties":{"jsonrpc":{"const":"2.0"},"id":{"type":["string","integer"]},"method":{"type":"string","examples":["initialize","tools/list","tools/call","ping"]},"params":{"type":"object"}}},"JsonRpcResponse":{"type":"object","additionalProperties":false,"required":["jsonrpc","id"],"properties":{"jsonrpc":{"const":"2.0"},"id":{"type":["string","integer","null"]},"result":{"type":"object"},"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"integer"},"message":{"type":"string"},"data":{}}}}},"WorldEvent":{"type":"object","additionalProperties":false,"required":["id","type","world","at","commitSeq","head","data"],"properties":{"id":{"type":"string","description":"Stable: `world:commitSeq:type`, for de-duplicating."},"type":{"type":"string","enum":["commit","claim.made","claim.released","ask.received","ask.withdrawn","ask.answered","relay.acted"]},"world":{"$ref":"#/components/schemas/GlobalName"},"at":{"$ref":"#/components/schemas/Millis"},"commitSeq":{"type":["integer","null"]},"head":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/Head"}]},"data":{"type":"object","description":"What happened; for a `commit` event, `CommitEventData`."}}},"CommitEventData":{"type":"object","description":"`data` of a `commit` WorldEvent (watchers only; never sent to webhooks).","required":["op"],"properties":{"op":{"type":"string","description":"The operation that committed."},"commits":{"type":"array","maxItems":8,"items":{"$ref":"#/components/schemas/JournalCommit"},"description":"The commits it sealed, oldest first; empty for a replayed idempotent write."},"truncated":{"type":"boolean","description":"Too large to carry; read /journal?since=."}}},"WatchTicketRequest":{"type":"object","additionalProperties":false,"properties":{"name":{"type":"string","minLength":1,"maxLength":32,"description":"The name others watching with presence see."},"color":{"type":"string","pattern":"^#[0-9a-f]{6}$","description":"Their colour for this viewer; the World picks one if absent."}}},"Viewer":{"type":"object","additionalProperties":false,"required":["sid","name","color","keyTail"],"properties":{"sid":{"type":"string","pattern":"^p_[0-9a-f]{8}$","description":"This socket, for as long as it is open."},"name":{"type":"string","maxLength":32},"color":{"type":"string","pattern":"^#[0-9a-f]{6}$"},"keyTail":{"type":"string","maxLength":4,"description":"The last 4 characters of the id of the key that let the viewer in."}}},"PresenceIn":{"description":"A frame a viewer sends. Positions are the World's own (date, hour, slot), never pixels; no `slot` on `at` means the pointer left.","oneOf":[{"type":"object","additionalProperties":false,"required":["t"],"properties":{"t":{"const":"at"},"date":{"type":"string","format":"date"},"hour":{"type":"integer","minimum":0,"maximum":23},"slot":{"type":"integer","minimum":0,"maximum":59},"lane":{"type":"string","maxLength":64}}},{"type":"object","additionalProperties":false,"required":["t","what","label"],"properties":{"t":{"const":"lift"},"what":{"enum":["occupier","run","softRun","spark","braid","bead","card","other"]},"label":{"type":"string","maxLength":64},"op":{"type":"string","maxLength":64},"date":{"type":"string","format":"date"},"hour":{"type":"integer","minimum":0,"maximum":23},"slots":{"$ref":"#/components/schemas/Mask"}}},{"type":"object","additionalProperties":false,"required":["t"],"properties":{"t":{"const":"over"},"date":{"type":"string","format":"date"},"hour":{"type":"integer","minimum":0,"maximum":23},"slots":{"$ref":"#/components/schemas/Mask"},"lane":{"type":"string","maxLength":64}}},{"type":"object","additionalProperties":false,"required":["t","how"],"properties":{"t":{"const":"end"},"how":{"enum":["drop","cancel"]}}},{"type":"object","additionalProperties":false,"required":["t","ph","op","call","via"],"properties":{"t":{"const":"act"},"ph":{"enum":["sent","settled"]},"op":{"type":"string","maxLength":64},"call":{"type":"string","maxLength":40},"status":{"type":"integer"},"head":{"$ref":"#/components/schemas/Head"},"via":{"enum":["hand","director","scenario"]}}},{"type":"object","additionalProperties":false,"required":["t","view"],"properties":{"t":{"const":"focus"},"view":{"type":"string","maxLength":64},"date":{"type":"string","format":"date"},"hour":{"type":"integer","minimum":0,"maximum":23}}},{"type":"object","additionalProperties":false,"required":["t","ph"],"properties":{"t":{"const":"director"},"ph":{"enum":["start","step","done"]},"step":{"type":"integer","minimum":0},"tool":{"type":"string","maxLength":64}}}]},"PresenceOut":{"description":"What the World sends a presence socket. A `presence` frame is a peer's `PresenceIn`, checked and rewritten: unknown fields dropped, strings cut to their longest.","oneOf":[{"type":"object","additionalProperties":false,"required":["type","you","peers"],"properties":{"type":{"const":"presence.roster"},"you":{"$ref":"#/components/schemas/Viewer"},"peers":{"type":"array","maxItems":31,"items":{"$ref":"#/components/schemas/Viewer"}}}},{"type":"object","additionalProperties":false,"required":["type","peer"],"properties":{"type":{"const":"presence.joined"},"peer":{"$ref":"#/components/schemas/Viewer"}}},{"type":"object","additionalProperties":false,"required":["type","sid"],"properties":{"type":{"const":"presence.left"},"sid":{"type":"string"}}},{"type":"object","additionalProperties":false,"required":["type","sid","frame"],"properties":{"type":{"const":"presence"},"sid":{"type":"string"},"frame":{"$ref":"#/components/schemas/PresenceIn"}}},{"type":"object","additionalProperties":false,"required":["type"],"properties":{"type":{"const":"presence.full"}}}]},"WatchHello":{"type":"object","required":["type","world"],"properties":{"type":{"const":"hello"},"world":{"type":"object","description":"The World as `GET /v1/worlds/{w}` describes it, without its name."}}},"WatchFrame":{"description":"Any frame the watch socket sends: `hello` first, then `WorldEvent`s and, with presence, `PresenceOut`.","oneOf":[{"$ref":"#/components/schemas/WatchHello"},{"$ref":"#/components/schemas/WorldEvent"},{"$ref":"#/components/schemas/PresenceOut"}]},"AssistRequest":{"type":"object","additionalProperties":false,"required":["prompt"],"properties":{"prompt":{"type":"string","minLength":1,"maxLength":2000,"pattern":"\\S","description":"What to do, in words. It must hold something other than whitespace."},"mode":{"type":"string","enum":["act","look"],"default":"act"},"worlds":{"type":"array","maxItems":16,"items":{"$ref":"#/components/schemas/WorldName"},"description":"The only Worlds of this workspace it may touch; absent means any. A World it creates joins the list."},"hands":{"type":"array","maxItems":16,"items":{"$ref":"#/components/schemas/GlobalName"},"description":"Worlds of other workspaces it may take in, lay legs on, or delegate to. Default none."},"allowCreate":{"type":"boolean","default":false,"description":"May it create Worlds (at most 3 per assist)?"},"today":{"type":"string","format":"date","description":"The day the prompt means by \"today\"; default the server's UTC day."},"focus":{"type":"object","additionalProperties":false,"description":"What the asker is looking at. Passed to the model as data, never as instructions.","properties":{"world":{"$ref":"#/components/schemas/WorldName"},"date":{"type":"string","format":"date"},"hour":{"type":"integer","minimum":0,"maximum":23}}},"history":{"type":"array","maxItems":4,"description":"Earlier prompts of this conversation and the Director's replies, oldest first.","items":{"type":"object","additionalProperties":false,"required":["prompt","reply"],"properties":{"prompt":{"type":"string","maxLength":2000},"reply":{"type":"string","maxLength":2000}}}},"anthropicKey":{"$ref":"#/components/schemas/AnthropicKey","description":"Your own Anthropic API key, to run this assist on your Anthropic account instead of the deployment's. Used for this request only, never stored or logged; the run is not counted against your plan's assists or the deployment's daily ceiling. Absent: the deployment's key."}}},"AnthropicKey":{"type":"string","writeOnly":true,"pattern":"^sk-ant-[A-Za-z0-9_-]{16,256}$","description":"An Anthropic API key. Used for this request only: sent to Anthropic and nowhere else, never stored, logged or returned. A value that does not read as a key is refused with 400, and the answer does not repeat it."},"AssistKeyCheckRequest":{"type":"object","additionalProperties":false,"required":["anthropicKey"],"properties":{"anthropicKey":{"$ref":"#/components/schemas/AnthropicKey"}}},"AssistKeyCheck":{"type":"object","additionalProperties":false,"required":["valid","detail"],"properties":{"valid":{"type":"boolean","description":"Anthropic takes the key. False when it refused it, and when it could not be asked (`detail` says which)."},"detail":{"type":"string","description":"What Anthropic said, in words; never the key."}}},"AssistLimits":{"type":"object","additionalProperties":false,"required":["turns","toolCalls","outputTokens","inputTokens","wallSeconds","creates"],"properties":{"turns":{"type":"integer"},"toolCalls":{"type":"integer"},"outputTokens":{"type":"integer"},"inputTokens":{"type":"integer","description":"Input across the turns, cache reads and writes included."},"wallSeconds":{"type":"integer"},"creates":{"type":"integer"}}},"AssistMonth":{"type":"object","additionalProperties":false,"description":"This month's runs on the deployment's Anthropic key, against the plan's. Runs on your own key are not counted.","required":["period","used","limit"],"properties":{"period":{"type":"string","pattern":"^\\d{4}-\\d{2}$"},"used":{"type":"integer","minimum":0},"limit":{"type":"integer","minimum":0}}},"AssistConfig":{"type":"object","additionalProperties":false,"required":["available","reason","model","modes","tools","limits","month","keys","disclosure"],"properties":{"available":{"type":"boolean","description":"The assistant is on here, so a run can start (on your own key, whatever `reason` says)."},"reason":{"type":["string","null"],"description":"What stops a run now: the assistant off here, or, for a run on the deployment's key, no key configured, the day or the month spent."},"model":{"type":["string","null"]},"modes":{"type":"array","items":{"enum":["look","act"]}},"tools":{"type":"object","additionalProperties":false,"required":["look","act"],"properties":{"look":{"type":"array","items":{"type":"string"}},"act":{"type":"array","items":{"type":"string"}}}},"limits":{"$ref":"#/components/schemas/AssistLimits"},"month":{"$ref":"#/components/schemas/AssistMonth"},"keys":{"type":"object","additionalProperties":false,"required":["deployment","own"],"description":"Whose Anthropic key a run may spend here.","properties":{"deployment":{"type":"boolean","description":"A run needs no key of yours: the deployment has ANTHROPIC_API_KEY (or, on dev, plays a script)."},"own":{"type":"boolean","description":"A run may bring your own key in `anthropicKey`: the assistant is on here."}}},"disclosure":{"type":"string"}}},"AssistEvent":{"description":"The JSON in each SSE `data`; `type` equals the SSE `event`.","oneOf":[{"title":"open","type":"object","additionalProperties":false,"required":["type","assistId","model","mode","key","tools","limits","month"],"properties":{"type":{"const":"open"},"assistId":{"type":"string","pattern":"^as_[0-9a-f]{16}$"},"model":{"type":"string"},"mode":{"enum":["act","look"]},"key":{"enum":["own","deployment","scripted"],"description":"Whose Anthropic key the run spends: yours (`anthropicKey`), the deployment's, or none (the dev script). Never the key itself."},"tools":{"type":"array","items":{"type":"string"}},"limits":{"$ref":"#/components/schemas/AssistLimits"},"month":{"$ref":"#/components/schemas/AssistMonth"}}},{"title":"note","type":"object","additionalProperties":false,"required":["type","delta"],"properties":{"type":{"const":"note"},"delta":{"type":"string","description":"The model's summarized thinking, as it streams."}}},{"title":"text","type":"object","additionalProperties":false,"required":["type","delta"],"properties":{"type":{"const":"text"},"delta":{"type":"string"}}},{"title":"forming","type":"object","additionalProperties":false,"required":["type","callId","tool","partial"],"properties":{"type":{"const":"forming"},"callId":{"type":"string"},"tool":{"type":"string"},"partial":{"type":"string","maxLength":4096,"description":"The arguments so far, as the model writes them: JSON, not yet whole."}}},{"title":"call","type":"object","additionalProperties":false,"required":["type","step","callId","tool","arguments","rest","mcp"],"properties":{"type":{"const":"call"},"step":{"type":"integer","minimum":1},"callId":{"type":"string"},"tool":{"type":"string"},"arguments":{"type":"object","description":"The MCP arguments, after clamps and the injected Idempotency-Key."},"rest":{"type":"object","additionalProperties":false,"required":["method","path"],"properties":{"method":{"type":"string"},"path":{"type":"string"},"query":{"type":"string"}}},"mcp":{"$ref":"#/components/schemas/JsonRpcRequest"}}},{"title":"result","type":"object","additionalProperties":false,"required":["type","step","callId","tool","status","body","truncated","head","commitSeq","ms"],"properties":{"type":{"const":"result"},"step":{"type":"integer","minimum":1},"callId":{"type":"string"},"tool":{"type":"string"},"status":{"type":"integer"},"body":{"description":"The answer, or its first 6 KB as a string when `truncated`."},"truncated":{"type":"boolean"},"head":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/Head"}]},"commitSeq":{"type":["integer","null"]},"ms":{"type":"integer","minimum":0}}},{"title":"denied","type":"object","additionalProperties":false,"required":["type","step","callId","tool","why","detail"],"properties":{"type":{"const":"denied"},"step":{"type":"integer","minimum":1},"callId":{"type":"string"},"tool":{"type":"string"},"why":{"enum":["not-offered","outside-scope","look-mode","create-cap","budget","invalid-arguments"]},"detail":{"type":"string"}}},{"title":"usage","type":"object","additionalProperties":false,"required":["type","turn","input","output","cacheRead","cacheWrite"],"properties":{"type":{"const":"usage"},"turn":{"type":"integer","minimum":1},"input":{"type":"integer","minimum":0},"output":{"type":"integer","minimum":0},"cacheRead":{"type":"integer","minimum":0},"cacheWrite":{"type":"integer","minimum":0}}},{"title":"stop","type":"object","additionalProperties":false,"required":["type","reason","turns","calls","month"],"properties":{"type":{"const":"stop"},"reason":{"enum":["end_turn","max_turns","max_calls","budget","deadline","refusal","max_tokens","aborted","error"]},"turns":{"type":"integer","minimum":0},"calls":{"type":"integer","minimum":0},"refusal":{"type":"object","additionalProperties":false,"required":["category","explanation"],"properties":{"category":{"type":["string","null"]},"explanation":{"type":["string","null"]}}},"month":{"$ref":"#/components/schemas/AssistMonth"}}},{"title":"problem","type":"object","additionalProperties":false,"required":["type","problem"],"properties":{"type":{"const":"problem"},"problem":{"$ref":"#/components/schemas/Problem"}}}]}}}}