Register a webhook callback for terminal task events.
Subscribes a caller-supplied HTTPS endpoint to receive POST
callbacks when the task reaches a terminal state (succeeded /
failed / canceled / timeout / rejected). Idempotent on
(task_id, url) — re-registering the same URL updates the token.
Implementation note: openapi-gateway is zero-DB; the underlying
subscription is stored by A2A Service in its webhooks table.
The webhook fires regardless of which protocol created the task
(OpenAPI / A2A / MCP) — same row, different protocol_filter.
Authorizations
Pass a user JWT or a oag_ User API Key on the
Authorization: Bearer <token> header. Both are validated by
openapi-gateway against the Auth service.
Both credential types are user-scoped: every key (and every JWT) is bound to exactly one owner, and every route grants the caller full access to that owner's own resources. Cross-tenant access is denied by owner-ACL inside the handlers — there is no per-route scope vocabulary on this API.
Removed in v1.1.0: the legacy
agents:*/tasks:*/files:*/instances:*scope set has been dropped together with the403 insufficient_scopeerror. Existingoag_keys automatically gain full owner-level access and do not need to be re-issued. SDK calls that previously passedscopestocreateAPIKeyshould drop the argument. See the changelog at the bottom of this spec for the full migration note.
Path Parameters
128128Body
Absolute HTTPS endpoint to POST callbacks to. The receiver gets the protocol-specific payload (OpenAPI: a task event envelope; A2A: JSON-RPC StreamResponse; MCP: notification).
Optional bearer token sent as Authorization: Bearer <token>
on each callback so the receiver can verify the call.
P2-A — HMAC-SHA256 signing key. When set, the deliverer
signs every callback body and emits
X-BeeOS-Signature: t=<unix>,v1=<hex> where
hex = hmac_sha256(secret, t || "." || body). The receiver
should re-run the same HMAC to authenticate; mismatched
timestamps (±5 min recommended tolerance) should be
rejected to defend against replay.
Write-only. Never echoed on Get / List responses; the
has_secret boolean on TaskWebhookResponse is the only
observable signal. Rotate by Set-ing a fresh value;
passing "" on update preserves the existing secret (use
DELETE + re-register to clear).
16 - 256