Webhook Events
These are outbound webhook events: your server gets notified when runs complete. For inbound webhooks that start runs, see Webhook Triggers.
Register webhook endpoints to receive notifications when runs complete, fail, or need input. Events are delivered as signed HTTP POST requests with automatic retries.
Register a Webhook
Important: The
secretis only shown once, on creation. Store it securely for signature verification.
Available Events
The balance.* events let you react before runs start failing (auto-top-up, page on-call). Each carries balance_micros, balance_usd, and currency; set the threshold with client.billing.set_alert_threshold(low_balance_threshold_cents=...).
Payload Format
teammate_idis the wire name for the agent id: JSON request and response bodies keep it. The SDK acceptsagent_id(canonical) andteammate_idalike.
output is the agent's closing message, clean prose. On run.completed, three envelope fields ride along: when the agent needs a decision from your user, needs_reply is true (needs_reply_count says how many separate decisions are waiting) — surface the output, collect a reply, and continue the run with a follow-up message. headline is the agent's one-line outcome summary (may be null), capped at 200 characters — useful as a notification title, but it is agent-generated text: escape it like any untrusted string and never interpolate it into HTML or commands unescaped.
Treat run.failed as the latest state, not a permanent one. When the failure was a transient infrastructure error, the platform may automatically retry or resume the same run, so a run.failed can be followed by run.started and a terminal run.completed for the same run id. Key your handler on the most recent event.
For run.awaiting_input, data.status is awaiting_approval. When the pause is a question (AskUserQuestion), data.questions carries the full question list, so no separate runs.permissions() call is needed. See the payload example in Human-in-the-Loop. Tool-approval pauses omit questions.
Cancellation payload (run.cancelled)
Cancellations fire their own run.cancelled event. Until mid-2026 they arrived as run.failed with data.status: "cancelled"; webhooks created before then should add run.cancelled to their subscription.
Handling Connection Expiry
When a connected app's token expires or is revoked, a connection.expired event fires. Use it to notify the affected user and trigger a reconnect flow. App triggers that use the expired connection are disabled automatically; reconnecting re-enables the flow. See Webhook Triggers.
Payload and handling code: re-initiate OAuth on expiry
Signature Verification
Verification needs no client and no API key. Pass the raw request body: a parsed-then-restringified object will not match, because re-serializing does not preserve key order or spacing.
Each request includes Webhook-Id, Webhook-Timestamp, and Webhook-Signature headers, where the signature is v1=HMAC-SHA256(secret, "{id}.{timestamp}.{body}"). Use the SDK helper to verify:
Manage Webhooks
Retry Behavior
Delivery is attempted up to 3 times with exponential backoff (2s, 4s delay); any 2xx counts as success. After all attempts the delivery is marked failed, visible via list_deliveries(). Pending deliveries are also retried if the server restarts.
Next: Webhook Triggers · Streaming · Scheduling
