Skip to main content

A2A push notifications

A2A push notifications (A2A v1.0 §6.3) replace the poll loop a federating peer would otherwise run against tasks/get. Register a callback URL on the task when you send it, and every lifecycle transition is POSTed to that URL the moment the executor advances the task. Use polling and push together, or either alone — the task ledger records everything regardless. The A2A federation reference covers the endpoints this guide builds on; this guide is the push-specific walkthrough.

1. The pushNotifications capability flag

Every AgentCard Orbit serves advertises its push capability under metadata.capabilities:
Fetch the card before you subscribe — see Discovery modes for the card URL and access policy:
"pushNotifications": true means the agent accepts a registered pushNotification target on tasks/send (REST or JSON-RPC) and delivers lifecycle callbacks to it. A peer that never checks the flag can still attempt a subscription — Orbit validates the target at send time and rejects a malformed one with a 422 — but checking the flag first avoids wasted envelopes on peers that poll only.

2. Subscribe with pushNotification on tasks/send

Attach a pushNotification block to the task-create request. The same block is accepted on both transports — the REST shorthand and the JSON-RPC tasks/send method — and on the dashboard’s outbound-delegation path. REST:
JSON-RPC:
The pushNotification block has three fields: Subscribing from the dashboard instead of curl: open Agents → → A2A → Delegate to peer and fill the optional push-URL field — the drawer forwards the value as the same pushNotification block. Subscribing is per task. A long-lived integration registers the callback on each task it sends; there is no agent-level default target.

3. Webhook endpoint shape

Deliver your callback on any HTTPS endpoint you control. Orbit POSTs a JSON-RPC-shaped envelope:
Answer 2xx. Any other response (or a connection failure) is recorded as a delivery failure on the task; the status transition itself still succeeds.

4. Verify the callback

Two signing schemes cover the callback; reject unsigned traffic at your endpoint either way. Detached Ed25519 JWS — X-Orbit-A2A-Push-Signature. When the Orbit deployment has its agent signing key provisioned, this header carries a compact JWS over the exact request body. Resolve the signing key from the JWKS URL the AgentCard advertises at metadata.a2aBearerAuth.jwksUri (also published on the Web Bot Auth directory endpoint) and verify with the kid in the JWS header. This is the preferred scheme: no shared secret crosses the integration. HMAC fallback — X-A2A-Signature. When no signing key is provisioned, Orbit falls back to the same shared-secret scheme used on inbound task calls: t=<unix_seconds>,v1=HMAC_SHA256(secret, "<t>.<raw_body>"). Verify with the A2A shared secret you already hold for that peer — see HMAC signing (task calls). For mTLS between your gateway and Orbit’s egress IPs, terminate it at your edge and still apply one of the two payload signatures — transport authentication and payload authentication answer different questions (who dialed vs. who signed this body).

5. Tear down a subscription

Subscriptions die with the task — there is no separate unsubscribe call to track.
  • Cancel the task (tasks/cancel, or REST PATCH …/a2a/tasks/{taskId} with { "status": "cancelled" }): the terminal transition is the last callback your URL receives.
  • Let the task finish: completed / failed are terminal too; no further callbacks fire afterwards.
  • Rotate away: if a registered callback URL must change mid-flight, finish/cancel the task and re-send it with the new target. The stored target on an existing task is never mutated.

6. Operator surface — seeing what’s subscribed

The dashboard lists every push target along with the task it belongs to:
  • Agents → → A2A → Task history — open a task row; the detail view shows the registered callback URL and whether the last delivery landed or was skipped.
  • API: GET /api/v1/agents/{agentId}/a2a/tasks/{taskId} returns the task envelope; the subscribed target sits under metadata.a2a_push.
Wire GET …/a2a/tasks (authenticated list endpoint) into your own operations dashboard if you need a fleet-level view of open subscriptions — the same payload shape applies.

Errors

Work through Troubleshooting: A2A federation for the wider federation failure taxonomy.

See also