Endpoints
Every A2A method is a
POST to /. The method name lives in the JSON-RPC
envelope, not the path. There are no REST-shaped routes — no GET /tasks/{id},
no DELETE /tasks/{id}.
Methods
The gateway dispatches exactly eleven method names and returnsmethod not found (-32601) for anything else.
SendStreamingMessage and SubscribeToTask return text/event-stream.
Everything else returns a JSON-RPC response body.
Errors arrive with HTTP 200
Every JSON-RPC error is returned with HTTP 200 and the error in the envelope. The HTTP status is not the failure signal on this surface.Authentication
The gateway takes one bearer credential in two kinds, disambiguated by prefix: anak- API key belonging to a service principal, or a JWT scoped to this
agent. A user’s API key is rejected with 403.
Authentication
Credential kinds, JWT admission rules, and the delegation chain.
The agent gateway has no rate limiting.
Contexts and threads
The A2AcontextId is the Noorle thread id. Echo it on a follow-up turn to
continue the same conversation; omit it and a fresh thread is created.
A client-supplied taskId is honored if present, otherwise the server mints
one. Task creation is atomic — reusing a task id fails rather than clobbering
the existing task.
Every stored key is scoped by account and agent, derived from the authenticated
context. A tenant field on the wire is never trusted.
Extensions
The card declares two Noorle extensions, both optional:
Negotiate by sending
A2A-Extensions with a comma-separated list of URIs.
The legacy header X-A2A-Extensions is also read; the response always echoes
the canonical A2A-Extensions name. Unknown URIs are ignored.
Messages and artifacts carrying an extension payload are tagged with the
extension URI only if you negotiated it.
Approval gates
When an agent’s autonomy policy pauses a call, the task moves to a non-terminalTASK_STATE_INPUT_REQUIRED — the HTTP or SSE request is not held open.
Resume by sending a follow-up SendMessage whose parts carry a
noorle.gate_decision data part. Both taskId and contextId are required;
both are server-minted and echoed back to you.
Only user callers may resolve a gate over A2A.
A rejected decision returns a noorle.gate_decision_rejected message on the
blocking path, or a single non-final INPUT_REQUIRED update on the streaming
path. The task stays parked either way.
Wire shapes worth knowing up front
- Task states are
TASK_STATE_*screaming-snake strings on the wire, not lowercase words. See Tasks. - Roles are
ROLE_USERandROLE_AGENT. - A message part has no
filevariant. The union istext,raw(base64),url, anddata. File attachments lower toraworurlwithfilenameandmediaTypealongside. - Streamed content rides artifact updates, not messages.