Runtime Endpoints & Communication Sessions
GABridge registration, route-frozen communication grants, grant-scoped messaging, per-tool-call approval, and the realtime channel that carries them to a BYO runtime.
A device or runtime registers itself as an endpoint, then messages flow through a short-lived communication session (30-minute grant). Delivery walks a five-step state machine:
queued → dispatched → device_acked → runtime_pending → runtime_acked
Both endpoints below are planned: the contract is published for design feedback and is not yet callable.
POST/api/v1/local-agent/delegationsGA
Delegate a Runtime Turn
The one-call entry point for local-runtime → local-runtime handoffs: it resolves the peer’s reachable runtime, freezes a route, opens a communication grant, and delivers the task — in a single request.
- Auth: device token (aicoo_dev_*). The caller delegates from one of its own runtime sessions.
- First contact returns 202 { status: "collaboration_requested" } — the task dispatches once the peer accepts the collaboration (an Allow once / Always-allow gate).
- After acceptance, resending with the SAME clientMessageId returns 201 { status: "delegated" } and dispatches a task_invite; a new clientMessageId opens a fresh request instead of reusing the active collaboration.
- Message conveys intent, not authority: the caller never names the peer’s endpoint — the frozen grant does. Receipts (device_ack → runtime_ack) and per-tool approval follow on the runtime-session channel.
Parameters
| Name | In | Type | Required |
|---|
targetThe peer to delegate to — a username/handle, or an object with principalId. | body | string | { principalId: string } | Yes |
taskThe objective to run on the peer’s runtime. | body | string | Yes |
sessionHandleThe caller’s own runtime session the delegation originates from. | body | string | Yes |
clientMessageIdIdempotency + collaboration key. Reuse it to dispatch on an already-accepted collaboration; a new value opens a new request. | body | string | No |
requestedTtlMinutesRequested grant lifetime, capped at 30 minutes. | body | number | No |
contextOptional context capsule; validated and rejected if unsafe. | body | object | No |
Request Example
curl -X POST https://www.aicoo.io/api/v1/local-agent/delegations \
-H "Authorization: Bearer aicoo_dev_YOUR_DEVICE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"target":"teammate","task":"Summarise today\'s build failures","sessionHandle":"rs_...","clientMessageId":"deleg-001"}'
Example Output
{
"success": true
}
POST/api/v1/local-agent/endpointsGA
Register Runtime Endpoint
Registers (or re-registers) a local bridge as an addressable delivery endpoint and mints its device credential.
- Auth: Aicoo user key or OAuth bearer. Every later bridge call uses the device token instead.
- The device token (aicoo_dev_*) is returned exactly once — store it, it cannot be read back.
- Re-registering the same device rotates the credential rather than creating a duplicate endpoint.
Parameters
| Name | In | Type | Required |
|---|
deviceIdStable per-machine identifier chosen by the bridge. | body | string | Yes |
runtimeWhich local runtime this bridge fronts. Only claude-code and codex are accepted today; other values are rejected with 400. | body | "claude-code" | "codex" | Yes |
capabilitiesAdvertised bridge capabilities (tools, streaming, file access). | body | object | No |
Request Example
curl -X POST https://www.aicoo.io/api/v1/local-agent/endpoints \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"deviceId":"mbp-16","runtime":"claude-code"}'
Example Output
{
"success": true
}
POST/api/v1/local-agent/grantsGA
Request Communication Grant
Requests a short-lived, route-frozen grant to reach another principal’s local agent.
- Precondition: an agent permission from the target to the requester must already exist — a grant cannot create access.
- Message conveys intent, not authority: the requester never names a destination endpoint.
- Pending until the recipient accepts; the route is frozen at accept time.
Parameters
| Name | In | Type | Required |
|---|
targetWho to reach. Both fields are required. | body | { kind: string, principalId: string } | Yes |
requestedTtlMinutesRequested lifetime, capped at 30 minutes. | body | number | No |
Request Example
curl -X POST https://www.aicoo.io/api/v1/local-agent/grants \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"target":{"kind":"user","principalId":"usr_9f2c"}}'
Example Output
{
"success": true
}
GET/api/v1/local-agent/grantsGA
List Grants
Lists the communication grants the caller participates in, as requester or recipient.
- Returns flat rows; clients map them into their own nested shape.
- Includes status and expiry so a bridge can drop grants that have lapsed.
Parameters
| Name | In | Type | Required |
|---|
| No path/query/body parameters required. |
Request Example
curl https://www.aicoo.io/api/v1/local-agent/grants \
-H "Authorization: Bearer YOUR_API_KEY"
Example Output
{
"success": true
}
POST/api/v1/local-agent/grants/{id}/acceptGA
Accept Grant
Recipient accepts a pending grant: resolves the default route, freezes endpoint + session, and sets a ≤30-minute expiry.
- Freezing the route at accept time is what stops a later request from being redirected elsewhere.
- Decline and revoke are available at the sibling /decline and /revoke paths.
Parameters
| Name | In | Type | Required |
|---|
idGrant (communication session) id. | path | string | Yes |
Request Example
curl -X POST https://www.aicoo.io/api/v1/local-agent/grants/cs_7d31/accept \
-H "Authorization: Bearer YOUR_API_KEY"
Example Output
{
"success": true
}
POST/api/v1/local-agent/messagesGA
Send Grant-Scoped Message
Sends a message inside an active grant. The destination comes from the frozen route.
- The caller cannot specify a destination endpoint — it is derived from the grant.
- Delivery state machine: queued → dispatched → device_acked → runtime_pending → runtime_acked.
- Idempotent per clientMessageId, so a bridge retry cannot duplicate a message.
- task_invite is capped by the caller’s remaining Credits, reserved atomically before dispatch.
Parameters
| Name | In | Type | Required |
|---|
commSessionIdActive grant to send within. | body | string | Yes |
bodyMessage payload delivered to the receiving runtime. | body | string | Yes |
clientMessageIdIdempotency key for safe retries. | body | string | No |
Request Example
curl -X POST https://www.aicoo.io/api/v1/local-agent/messages \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"commSessionId":"cs_7d31","body":"summarise today\u2019s notes"}'
Example Output
{
"success": true
}
POST/api/v1/local-agent/messages/{id}/ackGA
Acknowledge Delivery
Bridge advances the delivery state machine for a dispatched message.
- Auth: device token. Only the owning device may ack — this is what makes runtime_ack unspoofable.
- Used for both device_acked and runtime_acked transitions.
Parameters
| Name | In | Type | Required |
|---|
idDelivery id being acknowledged. | path | string | Yes |
phaseWhich transition to record. | body | "device_ack" | "runtime_ack" | Yes |
Request Example
curl -X POST https://www.aicoo.io/api/v1/local-agent/messages/dl_5a20/ack \
-H "Authorization: Bearer aicoo_dev_YOUR_DEVICE_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"phase":"runtime_ack",
"attemptId":"attempt_1",
"usage":{"model":"pulse-standard","inputTokens":1000000,"outputTokens":200000}
}'
Example Output
{
"success": true
}
POST/api/v1/local-agent/sessionsGA
Register Managed Session
Registers an opaque handle for a live runtime session so grants can target it.
- Auth: device token.
- The provider-native session id is never uploaded — only the opaque handle.
Parameters
| Name | In | Type | Required |
|---|
handleOpaque session handle minted by the bridge. | body | string | Yes |
Request Example
curl -X POST https://www.aicoo.io/api/v1/local-agent/sessions \
-H "Authorization: Bearer aicoo_dev_YOUR_DEVICE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"handle":"sess_op4q"}'
Example Output
{
"success": true
}
POST/api/v1/local-agent/tool-approvalsGA
Request Tool Approval
Bridge registers a tool call for owner approval before the local runtime is allowed to execute it.
- Auth: device token. Called from the runtime’s canUseTool hook.
- A matching policy auto-allows; otherwise the call stays pending until the owner decides.
- This is the per-tool-call gate: a grant lets someone ask, it does not let them run tools.
Parameters
| Name | In | Type | Required |
|---|
commSessionIdGrant the tool call belongs to. | body | string | Yes |
toolNameTool the runtime wants to invoke. | body | string | Yes |
toolInputSummaryHuman-readable summary shown to the owner. | body | string | Yes |
Request Example
curl -X POST https://www.aicoo.io/api/v1/local-agent/tool-approvals \
-H "Authorization: Bearer aicoo_dev_YOUR_DEVICE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"commSessionId":"cs_7d31","toolName":"read_file","toolInputSummary":"README.md"}'
Example Output
{
"success": true
}
POST/api/v1/local-agent/tool-approvals/{id}/resolveGA
Resolve Tool Approval
Owner allows or denies a pending tool call from their phone or the web UI.
- Auth: user key — only the owner may decide, and only for their own pending approvals.
- The decision is pushed back to the originating bridge as tool.approval_decision.
- Already-resolved and expired approvals are rejected rather than silently re-decided.
Parameters
| Name | In | Type | Required |
|---|
idApproval id. | path | string | Yes |
decisionOwner decision. | body | "allow" | "deny" | Yes |
Request Example
curl -X POST https://www.aicoo.io/api/v1/local-agent/tool-approvals/ap_31bd/resolve \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"decision":"allow"}'
Example Output
{
"success": true
}
GET/api/v1/local-realtime/streamGA
Realtime Event Stream (SSE)
Long-lived SSE channel a bridge holds open to receive dispatches and decisions.
- Auth: device token.
- Durable replay from cursor, then live wake — reconnecting with the last cursor is lossless.
- The connection recycles roughly every 55s with jitter; reconnect with your cursor.
Parameters
| Name | In | Type | Required |
|---|
endpointIdEndpoint to stream events for. | query | string | Yes |
cursorLast seq seen; events after it are replayed on connect. | query | number | No |
Request Example
curl -N "https://www.aicoo.io/api/v1/local-realtime/stream?endpointId=ep_9f2c&cursor=1024" \
-H "Authorization: Bearer aicoo_dev_YOUR_DEVICE_TOKEN"
Example Output
{
"success": true
}
GET/api/v1/local-realtime/pollGA
Realtime Poll Fallback
Cursor-based polling for bridges that cannot hold an SSE connection.
- Auth: device token. Same cursor semantics as the stream endpoint.
- Use when a proxy or network blocks long-lived connections.
Parameters
| Name | In | Type | Required |
|---|
endpointIdEndpoint to poll. | query | string | Yes |
cursorLast seq seen. | query | number | No |
Request Example
curl "https://www.aicoo.io/api/v1/local-realtime/poll?endpointId=ep_9f2c&cursor=1024" \
-H "Authorization: Bearer aicoo_dev_YOUR_DEVICE_TOKEN"
Example Output
{
"success": true
}
POST/api/v1/local-agent/device-code/startGA
Start Device-Code Login
Begins browser-free pairing for a bridge that has no API key yet.
- Unauthenticated by design — the bridge has no credential at this point.
- Returns a short user code the owner approves in the web UI, plus a poll token held only by the bridge.
Parameters
| Name | In | Type | Required |
|---|
deviceIdStable per-machine identifier. | body | string | Yes |
runtimeLocal runtime being paired. | body | string | Yes |
Request Example
curl -X POST https://www.aicoo.io/api/v1/local-agent/device-code/start \
-H "Content-Type: application/json" \
-d '{"deviceId":"mbp-16","runtime":"claude-code"}'
Example Output
{
"success": true
}
POST/api/v1/local-agent/device-code/pollGA
Poll Device-Code Approval
Polls until the owner approves, then returns the credential once.
- Authorized by possession of the poll token, not a session.
- The credential is returned encrypted and the pairing row is consumed after a single successful read.
Parameters
| Name | In | Type | Required |
|---|
pollTokenToken from the start call. | body | string | Yes |
Request Example
curl -X POST https://www.aicoo.io/api/v1/local-agent/device-code/poll \
-H "Content-Type: application/json" \
-d '{"pollToken":"..."}'
Example Output
{
"success": true
}
GET/api/v1/local-agent/whoamiGA
Whoami
Returns the principal behind the presented device token or user credential.
- Cheap way for a bridge to confirm its token is still valid.
Parameters
| Name | In | Type | Required |
|---|
| No path/query/body parameters required. |
Request Example
curl https://www.aicoo.io/api/v1/local-agent/whoami \
-H "Authorization: Bearer aicoo_dev_YOUR_DEVICE_TOKEN"
Example Output
{
"success": true
}
GET/api/v1/local-agent/pair-statusGA
Pair Status
Reports whether the caller has a reachable local runtime paired.
- A default route that is offline does not count as reachable.
Parameters
| Name | In | Type | Required |
|---|
| No path/query/body parameters required. |
Request Example
curl https://www.aicoo.io/api/v1/local-agent/pair-status \
-H "Authorization: Bearer YOUR_API_KEY"
Example Output
{
"success": true
}
GET/api/v1/local-agent/resolve-personGA
Resolve Person
Resolves a handle or username to a principal a grant can target.
- Only returns people the caller is already connected to.
Parameters
| Name | In | Type | Required |
|---|
handleUsername or handle to resolve. | query | string | Yes |
Request Example
curl "https://www.aicoo.io/api/v1/local-agent/resolve-person?handle=teammate" \
-H "Authorization: Bearer YOUR_API_KEY"
Example Output
{
"success": true
}
GET/api/v1/local-agent/default-routeGA
Default Route
Reads the endpoint that inbound grants resolve to; PUT sets it, DELETE clears it.
- Auth: device token.
- Accepting a grant freezes whatever this points at, so later changes do not redirect an active grant.
Parameters
| Name | In | Type | Required |
|---|
| No path/query/body parameters required. |
Request Example
curl https://www.aicoo.io/api/v1/local-agent/default-route \
-H "Authorization: Bearer aicoo_dev_YOUR_DEVICE_TOKEN"
Example Output
{
"success": true
}
POST/api/v1/local-agent/endpoints/{id}/heartbeatGA
Endpoint Heartbeat
Keeps an endpoint marked online.
- Auth: device token.
- Missing heartbeats flip presence to offline, which removes it from routing.
Parameters
| Name | In | Type | Required |
|---|
idEndpoint id. | path | string | Yes |
Request Example
curl -X POST https://www.aicoo.io/api/v1/local-agent/endpoints/ep_9f2c/heartbeat \
-H "Authorization: Bearer aicoo_dev_YOUR_DEVICE_TOKEN"
Example Output
{
"success": true
}
DELETE/api/v1/local-agent/endpoints/{id}GA
Revoke Endpoint
Revokes an endpoint and clears any default route pointing at it.
- Auth: device token or user credential.
- A revoked endpoint stops being a delivery target immediately.
Parameters
| Name | In | Type | Required |
|---|
idEndpoint id. | path | string | Yes |
Request Example
curl -X DELETE https://www.aicoo.io/api/v1/local-agent/endpoints/ep_9f2c \
-H "Authorization: Bearer YOUR_API_KEY"
Example Output
{
"success": true
}
POST/api/v1/local-agent/grants/{id}/declineGA
Decline Grant
Recipient declines a pending grant request.
Parameters
| Name | In | Type | Required |
|---|
idGrant id. | path | string | Yes |
Request Example
curl -X POST https://www.aicoo.io/api/v1/local-agent/grants/cs_7d31/decline \
-H "Authorization: Bearer YOUR_API_KEY"
Example Output
{
"success": true
}
POST/api/v1/local-agent/grants/{id}/revokeGA
Revoke Grant
Either party ends an active grant early.
- Revoking stops further delivery immediately rather than waiting for the 30-minute expiry.
Parameters
| Name | In | Type | Required |
|---|
idGrant id. | path | string | Yes |
Request Example
curl -X POST https://www.aicoo.io/api/v1/local-agent/grants/cs_7d31/revoke \
-H "Authorization: Bearer YOUR_API_KEY"
Example Output
{
"success": true
}
GET/api/v1/local-agent/messages/{id}GA
Message Delivery Status
Returns the delivery state machine and per-attempt history for a message.
- Use this to tell "not delivered yet" apart from "the runtime rejected it".
Parameters
| Name | In | Type | Required |
|---|
idMessage id. | path | string | Yes |
Request Example
curl https://www.aicoo.io/api/v1/local-agent/messages/msg_31ff \
-H "Authorization: Bearer YOUR_API_KEY"
Example Output
{
"success": true
}
POST/api/v1/local-agent/messages/{id}/replyGA
Reply to Message
Bridge returns the runtime’s answer along the same grant.
- Auth: device token.
- The reply travels the reverse of the frozen route — the bridge cannot redirect it elsewhere.
Parameters
| Name | In | Type | Required |
|---|
idMessage being replied to. | path | string | Yes |
bodyReply content. | body | string | Yes |
Request Example
curl -X POST https://www.aicoo.io/api/v1/local-agent/messages/msg_31ff/reply \
-H "Authorization: Bearer aicoo_dev_YOUR_DEVICE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"body":"here is the summary"}'
Example Output
{
"success": true
}
PATCH/api/v1/local-agent/sessions/{handle}GA
Update Managed Session
Syncs bridge-side session state for an existing handle.
Parameters
| Name | In | Type | Required |
|---|
handleOpaque session handle. | path | string | Yes |
Request Example
curl -X PATCH https://www.aicoo.io/api/v1/local-agent/sessions/sess_op4q \
-H "Authorization: Bearer aicoo_dev_YOUR_DEVICE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"state":"idle"}'
Example Output
{
"success": true
}
GET/api/v1/local-agent/tool-approvals/{id}GA
Read Tool Approval
Reads one approval and its current decision.
- Visible to the owner and the requesting bridge only.
Parameters
| Name | In | Type | Required |
|---|
idApproval id. | path | string | Yes |
Request Example
curl https://www.aicoo.io/api/v1/local-agent/tool-approvals/ap_31bd \
-H "Authorization: Bearer YOUR_API_KEY"
Example Output
{
"success": true
}
POST/api/v1/local-agent/injections/validateGA
Validate Injection
Fail-closed check the bridge runs before injecting a message into the local runtime.
- Auth: device token.
- Rejects anything whose grant has expired or been revoked — the last gate before untrusted text reaches a runtime.
Parameters
| Name | In | Type | Required |
|---|
commSessionIdGrant the injection claims to belong to. | body | string | Yes |
Request Example
curl -X POST https://www.aicoo.io/api/v1/local-agent/injections/validate \
-H "Authorization: Bearer aicoo_dev_YOUR_DEVICE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"commSessionId":"cs_7d31"}'
Example Output
{
"success": true
}