Skip to main content
Webhooks push events to your HTTPS endpoint so your agent reacts to inbound mail and run outcomes without polling. Guide: Webhooks.

Events

The run.* events are fired once, without retry — pair them with polling GET /v1/runs/:id if your endpoint can miss deliveries. message.received is queued and retried.

Delivery

Each delivery is an HTTP POST with content-type: application/json and a 10-second timeout. Every delivery to your org carries the org-level secret in the x-sente-secret header — verify it with a constant-time compare before trusting the payload:
Webhook URLs must be http(s) and resolve to public addresses. URLs pointing at loopback, private-range, link-local, or cloud-metadata addresses are rejected at registration (400) and re-checked before every delivery.

Create a webhook

POST /v1/webhooks Idempotent per (url, identity scope): re-posting the same url and scope returns the existing subscription with its events replaced — safe to call on every app start.
Response 201 (the only place the secret is returned by this API — store it):
Errors: 400 with zod issues for a bad events value; 400 {"error": "webhook url not allowed: ..."} for a non-public URL; 404 {"error": "identity not found"} for a foreign identityId.

List webhooks

GET /v1/webhooks
Response 200 (no secret in list responses):

Delete a webhook

DELETE /v1/webhooks/:id
Response: 204 with no body. 404 {"error": "not found"} otherwise.

Payloads

message.received

The payload is a summary — fetch the body and annotation with GET /v1/messages/:id.

run.blocked

Fired the moment a run parks for a human. Carries everything a notifier needs to route someone to the gate:
actionUrl deep-links to the dashboard run page (live view + resume in one place). holdExpiresAt is when the run auto-fails BLOCKED_TIMEOUT if nobody acts — your notification can say how long the human has. The code values are listed on Runs.

run.completed / run.failed

run.failed has the same shape with "status": "failed", the failure code/detail set, and "result": null.