Webhooks
Get a signed HTTPS request whenever a session is created.
A webhook sends a signed POST to your HTTPS endpoint whenever a session is created, from any source: the dashboard, the CLI, the API, agents, and handlers.
Create a webhook
The response includes a secret that starts with whsec_. Save it: it's shown only once. To change it, delete the webhook and create a new one.
The URL must be public HTTPS on port 443 or 8443. An account can have up to 3 webhooks.
Activate it
- Send a test event with
POST /v1/webhooks/{webhook_id}/ping. Your endpoint must answer with HTTP 200. - Open Settings > Webhooks and choose Request activation.
Ellipsis turns the webhook on after reviewing the request. Until then it receives only pings.
Events
| Event | Sent when |
|---|---|
session.create | A session is created |
webhook.ping | You call the ping endpoint; always sent |
Every delivery has the same envelope. For session.create, data.session is the object GET /v1/sessions/{session_id} returns:
This example is shortened; real IDs are longer, and session has every field.
Verify signatures
Each request has 3 headers:
| Header | Value |
|---|---|
webhook-id | The event ID; the same on every retry |
webhook-timestamp | Unix seconds when this attempt was sent |
webhook-signature | v1, followed by a base64 HMAC-SHA256 signature |
To verify, base64-decode your secret without its whsec_ prefix, and sign {webhook-id}.{webhook-timestamp}.{raw body} with it. Use the raw request bytes, not re-serialized JSON:
These examples reject requests older than 5 minutes.
Delivery
- Any 2xx response within 10 seconds counts as delivered. Pings need exactly 200.
- A failed delivery is retried after 1 minute and again after 10 minutes, then marked failed.
- Events can arrive out of order or more than once; use
webhook-idto skip duplicates. GET /v1/webhooks/deliverieslists the last 30 days of deliveries, andGET /v1/webhooks/deliveries/{delivery_id}shows one with its payload and attempts.