message.received) and run state
changes (run.blocked, run.completed, run.failed). Every delivery carries your organization’s
webhook secret in the X-Sente-Secret header.
Register an endpoint
POST /v1/webhooks with { url, events, identityId? }. Omit identityId for an org-wide webhook;
set it to scope deliveries to one identity. Registration is idempotent per (url, identity scope) —
registering the same pair again does not create a duplicate.
400) and
re-checked before every delivery.
Verifying deliveries
Compare theX-Sente-Secret header against your stored secret with a timing-safe compare, then ack
fast:
Events
The
run.* events are single-attempt: if your endpoint is down at that moment, the notification is
lost. GET /v1/runs/:id is the backstop — poll it if you must not miss a terminal state. See the
runs API reference.
message.received
A thin notification — it has no body. Fetch the full message (body and
annotation) with GET /v1/messages/:id /
sente.messages.get(id):
run.blocked
Fired when a register, login, or connect run needs a human — a CAPTCHA, an SMS/phone step, a payment
step, a confirm-before-submit pause, or an MFA code only the account owner can
receive. The payload carries everything needed to route a person to the gate:
code— why the run blocked:SUBMIT_CONFIRMATION_REQUIRED,CAPTCHA_REQUIRED,MISSING_FIELD,PAYMENT_REQUIRED,PHONE_REQUIRED,LOGIN_UNCONFIRMED, or (connect runs)TOTP_REQUIRED/MFA_REQUIRED.liveViewUrl— the interactive browser view where a person clears the step.actionUrl— a dashboard deep link to the run page (live view, submit, and resume in one place).holdExpiresAt— the run holds for roughly 10 minutes, then auto-fails withBLOCKED_TIMEOUTif not resumed. A notification should tell the human how long they have.
run.completed / run.failed
run.failed is the same shape with status: "failed", the error code/detail set, and
result: null.
Desktop notifications without a webhook
sente watch is the pull-based counterpart for a human at a machine — a daemon that polls and fires
an OS desktop notification the moment any run blocks, with the live-view URL and the
sente run resume <id> command:
Testing locally
No public URL needed during development — the CLI relays inbound mail to a local handler with the exact same payload andX-Sente-Secret header:
