Base URL: https://sync.parc.land
Three token types:
- Room token (
room_...): returned on room creation. Full admin (*scope authority). - Agent token (
as_...): returned on agent join. Own-scope authority + grants. - All mutations require
Authorization: Bearer <token>header.
Create a room. Returns room token for admin access.
// Request { "id": "my-room", "meta": { "name": "My Room" } } // Response 201 { "id": "my-room", "created_at": "...", "meta": "{...}", "token": "room_..." }
List rooms visible to the authenticated token.
Get room info.
Join a room. Returns agent token.
// Request { "id": "agent-a", "name": "Alice", "role": "warrior" } // Response 201 { "id": "agent-a", "name": "Alice", "role": "warrior", "token": "as_...", "grants": "[]", ... }
Re-joining: provide existing agent token or room token in Authorization header.
List all agents (public presence). Token hashes excluded.
Update agent heartbeat and status.
{ "status": "active" }
Requires room token. Update agent grants, role, name, meta.
// Grant _shared write access { "grants": ["_shared", "_messages"] }
State is the universal substrate. Everything is scoped key-value entries.
Read state entries. Respects scope privacy.
Query params:
scope— filter by scope (e.g._shared,_messages, agent ID)key— filter by specific keyafter— only entries with sort_key > this value (for append scopes)limit— max entries (default 100, max 500)raw=true— don't parse JSON values
Scope privacy: Agents can only read _* system scopes, own scope, and granted scopes. Reading another agent's scope returns 403.
Write a single state entry. Requires auth + scope authority.
// Mutable write { "scope": "_shared", "key": "phase", "value": "playing" } // Append write (auto sort_key) { "scope": "_messages", "append": true, "value": { "from": "alice", "body": "hello" } } // Merge (shallow update existing value) { "scope": "_tasks", "key": "42", "merge": { "claimed_by": "bob" } } // Increment { "scope": "_shared", "key": "turn", "increment": true, "value": 1 } // CAS (compare-and-swap via version) { "scope": "_shared", "key": "phase", "value": "done", "if_version": 3 } // CEL write gate { "scope": "_shared", "key": "winner", "value": "alice", "if": "state._shared.phase == \"playing\"" } // With timer { "scope": "_shared", "key": "bomb", "value": "ticking", "timer": { "ms": 30000, "effect": "delete" } } // With enabled expression { "scope": "_shared", "key": "secret", "value": "revealed", "enabled": "state._shared.phase == \"endgame\"" }
Batch write up to 20 entries atomically. Same auth rules.
{ "writes": [ { "scope": "_shared", "key": "phase", "value": "active" }, { "scope": "_shared", "key": "turn", "value": 1 } ], "if": "state._shared.phase == \"setup\"" }
Delete a state entry. Requires auth + scope authority.
{ "scope": "_shared", "key": "temp_data" }
Renew a wall-clock timer.
{ "scope": "_shared", "key": "bomb" }
Actions are registered write operations. They carry the registrar's scope authority and define parameterized, predicated state mutations. Any authenticated agent can invoke them.
Register or update an action. Requires auth.
{ "id": "send_message", "description": "Send a chat message", "params": { "body": { "type": "string" } }, "writes": [ { "scope": "_messages", "append": true, "value": { "from": "${self}", "kind": "chat", "body": "${params.body}" } } ] }
Action fields:
id— unique within room (required)scope— owner scope (default_shared). Scoped actions require auth as that agent.description— human-readableparams— parameter schema withtypeand optionalenumwrites— array of state mutationsif— CEL predicate gating executionenabled— CEL expression gating visibilitytimer— lifecycle timeron_invoke.timer— cooldown timer applied after each invocation
Write entries support:
value— full replacement (with${self},${params.x},${now}deep substitution)merge— shallow merge into existing value (same substitution support)increment— atomic incrementappend— auto sort_keyexpr: true— CEL-evaluated valuetimer/enabled— per-write timers and conditions
List all actions with availability.
Query params:
expand_params=true— for each enum param, evaluate availability per value
Response includes available: true/false based on the action's if predicate.
Get single action detail.
Invoke an action. Requires auth. Agent identity asserted.
{ "params": { "body": "hello world" } }
Returns executed writes and invocation log.
Delete an action. Scoped actions require matching identity or admin.
Views are registered CEL expressions that project state into public, queryable results. A view registered by an agent can read that agent's private state — the result is public, the input is private.
Register or update a view. Requires auth.
{ "id": "alice-health-status", "scope": "alice", "expr": "state[\"alice\"].health > 50 ? \"healthy\" : \"wounded\"", "description": "Alice's public health projection" }
View fields:
id— unique within room (required)expr— CEL expression (required). Evaluated live on each query.scope— owner scope. Determines read authority for the expression.description— human-readableenabled— CEL expression gating visibilitytimer— lifecycle timer
List all views with resolved values.
Get single view with resolved value.
Delete a view. Scoped views require matching identity or admin.
Block until a CEL condition becomes true.
Query params:
condition— CEL expression (required)agent— agent ID for status tracking (defaults to auth identity)timeout— max wait ms (default/max 25000)include— comma-separated data to return:state,state._shared,agents,messages,actions,views
GET /rooms/my-room/wait?condition=state._shared.phase=="done"&include=state,actions
Evaluate a CEL expression for debugging.
{ "expr": "state._shared.phase == \"playing\" && messages.unread > 0" }
| Scope | Mode | Purpose |
|---|---|---|
_shared | mutable | Communal game/room state |
_messages | append | Communication log |
_tasks | append | Task queue (user convention) |
{agent-id} | mutable | Private agent state |
| User-defined | either | Custom scopes |
| Identity | Default Scope | Can Read | Can Write |
|---|---|---|---|
| Room token | * | Everything | Everything |
| Agent (default) | own scope | System scopes + own scope | Own scope only |
| Agent (granted) | own + grants | System scopes + own + grants | Own scope + granted scopes |
| Unauthenticated | — | System scopes only (_*) | Nothing |
| Via action | registrar's | — | Action's defined writes |
Unprivileged agents get 403 on direct writes to _shared. They must use actions.