Skip to main content
The BeeOS OpenAPI lets you invoke any agent you own (or any public-visibility agent) in three modes from one unified contract. The modes share the same authentication (JWT or oag_ User API Key — see Authentication & API Keys for how to obtain one), the same agent identifier (agentId). This page describes the OpenAPI wire contract; A2A tasks, message envelopes, and runtime operations use related but distinct state machines. See Task and operation states for their mappings. Pick whichever fits your UX. Behind the scenes all three converge on the same chatinvoke core (see ADR 0017) so result shape, status semantics, and SSE wire format are consistent across modes.

1. Blocking invoke

The simplest mode. Returns a single JSON response once the agent finishes (or the gateway times out, default 120s).

Request

Response (200)

TypeScript SDK

Go SDK


2. Streaming invoke (SSE)

Same endpoint, different Accept header. The response body is an SSE stream with delta events (incremental text) and a terminal done event.

Request

Response (SSE)

The stream is one of three frame shapes, modelled in the contract as InvokeEventStream (a oneOf of InvokeAgentSSEDelta / InvokeAgentSSEError / InvokeAgentSSEDone). Unlike the /tasks/{id}/events stream, the invoke endpoint does NOT name the SSE event — every frame is a bare data: line and clients discriminate via the JSON type field:
If the gateway gives up before the agent produces a terminal reply (timeout, agent rejection, internal error), a single error frame is emitted before the final done:
timeout_ms is server-clamped at 115 s (see the OpenAPI spec’s InvokeAgentRequest.timeout_ms.maximum). Above that the clamp is silent — the gateway still emits service_timeout if the agent doesn’t reply within the effective window. For work that may exceed ~2 minutes, switch to the async task API which returns immediately and lets you observe progress over SSE.

SSE frame fields

Error code reference

The same codes show up in error.code / done.code and in blocking JSON error envelopes. Use them as your switch keys — the status_code / message fields are presentation, not contract. The full table lives in Error Reference — one source of truth for HTTP status × wire code × SSE frame across the entire OpenAPI surface. Common ones you’ll need to handle on the invoke path:
  • agent_not_found (404) — verify ownership / visibility
  • agent_service_unavailable / agent_offline (503) — retry briefly
  • conflict (409) — agent busy / refused / duplicate idempotency key (inspect message to discriminate)
  • service_timeout (504) — switch to async tasks
  • forbidden (403) — use a credential that owns the agent
  • rate_limited (429) — honour Retry-After

TypeScript (raw fetch)

The generated SDK’s blocking invokeAgent cannot stream — for SSE use fetch directly:

The canonical task core. Submit returns 202 immediately with a task_id. Use GET /tasks/{taskId} to poll, or subscribe to GET /tasks/{taskId}/events (SSE) for live updates. The lifecycle supports cancel and continue.

3a. Submit

3b. Poll for state

When the task reaches a terminal state, status flips to one of completed / failed / canceled / timeout / rejected and result (success) or error (failure) is populated. Terminal states are leaf nodes in the state machine — polling can short-circuit.

3c. Live SSE event stream

The terminal event: end always fires once. Its reason field is one of: See the TaskEventStream schema for the full list of type values inside individual event: message frames.

3d. Cancel

Cancel is idempotent — calling it on an already-terminal task is a no-op and returns the current snapshot.

3e. Continue (resume input_required / auth_required)

Some agents pause mid-task to request additional input or an OAuth-style permission grant. The state flips to input_required (or auth_required). Resume with:
For an auth_required pause set "auth_grant": true to send the user.auth_grant envelope instead.

TypeScript SDK

3f. List your tasks

Page through tasks you’ve submitted to a particular agent. The list is backed by Message Service channel metadata, so it is consistent with the GetTask snapshot you get from §3b.
Query parameters: The endpoint returns only tasks where the channel metadata’s protocol is openapi — conversation channels live under GET /api/v1/agents/{agentId}/conversations.

Cross-agent variant — GET /api/v1/tasks

If you’ve submitted tasks to multiple agents and want a unified “my tasks” view (common for multi-agent UIs), call the cross-agent endpoint instead:
The wire shape is identical to the per-agent variant — same tasks[] rows, same next_since cursor — so SDKs can share the decode + pagination code. The optional agent_id query param narrows back down to a single agent without forcing a different endpoint path. Use this when you don’t know in advance which agents the caller has submitted against.

3g. Replay task messages

Fetch the full message log for a single task. Useful for surfacing the agent’s intermediate steps after the SSE event stream has already closed.
Query parameters:

TypeScript SDK (list helpers)


Comparison summary


OpenAPI TaskStatus reference (ADR-0017)

These values belong specifically to the versioned OpenAPI /tasks wire contract. They are not the universal BeeOS product-state vocabulary. See Task and operation states before mapping them into an application UI or an A2A client. State transitions are documented in the TaskStatus schema component.

See also