POST request to every subscribed webhook, so you can react to completions and failures without polling.
Manage webhooks with the CRUD API. Each one has a target url, a list of enabled_events, and a signing secret returned once at creation.
Events
| Event type | Sent when |
|---|---|
session.status_updated | A session’s status changes, e.g. running → completed. |
enabled_events, or use "*" to receive all current and future event types.
Delivery payload
Each delivery is aPOST with a JSON body:
The event type, e.g.
session.status_updated.Unique id for this event.
When the status change occurred (UTC, RFC 3339, millisecond precision).
Event payload:
session_id, the new status (pending, running, paused, idle, awaiting_tool_results, completed, failed, timed_out, or interrupted), and the previous_status it transitioned from (null when unknown).Verifying deliveries
Every delivery carries two headers:| Header | Value |
|---|---|
X-H-Webhook-Timestamp | Unix timestamp (seconds) of the delivery. |
X-H-Webhook-Signature | sha256= + hex HMAC-SHA256 of {timestamp}.{raw_body}, keyed with your webhook’s secret. |
HMAC-SHA256(secret, "{timestamp}." + raw_body), hex-encode it, prefix with sha256=, and compare it to X-H-Webhook-Signature using a constant-time comparison. Reject deliveries whose timestamp is more than a few minutes old to guard against replays.
Delivery semantics
Deliveries are at-most-once: a singlePOST per event with a 10-second timeout, and no retries. Treat a webhook as a trigger rather than a source of truth. On receipt, fetch the authoritative state with Get session status. If your endpoint is briefly unavailable, you may miss an event, so keep a polling fallback for critical flows.
Out-of-order arrival is possible when statuses change in quick succession; previous_status lets you detect and discard stale transitions.
Constraints
- Target URLs must be
https://and resolve to a public address; deliveries to private or internal hosts are skipped. - The signing
secretis returned only in the Create response. To rotate it, delete the webhook and create a new one. - An organization can register up to 10 webhooks.
- A
disabledwebhook stays registered but receives no deliveries.