Webhooks
Subscribe to what Atribu finishes, instead of polling it — including the platform lifecycle events an agent waits on.
Atribu fans out events to HTTPS endpoints you register. Before #1049 the whole platform was poll-only: an agent that started an OAuth connect, queued a recompute or fired an export had no way to learn it landed except by asking again.
Subscribing
GET /api/v1/webhooks/subscriptions
POST /api/v1/webhooks/subscriptions
PATCH /api/v1/webhooks/subscriptions/{id}
DELETE /api/v1/webhooks/subscriptions/{id}A subscription names a url, a list of events, and a list of providers. A
delivery is matched on both lists — an event whose provider your
subscription does not name is not delivered, whatever its event type.
Platform lifecycle events are opt-in, and the trap is the provider list
Every lifecycle event below carries the provider atribu, not a channel — a
recompute is not WhatsApp, and a connection.connected for meta_ads is not
any messaging channel either. So an existing subscription whose providers is
["whatsapp"] receives none of them until it PATCHes atribu in. The
connector's real provider rides in data.provider.
The platform lifecycle events
| event | fires when |
|---|---|
connection.connected | a provider connect completed |
connection.reconnect_required | a connection stopped delivering and needs re-authorizing |
connection.revoked | a connection was removed |
handoff.completed | a hand-off you minted was finished by a human |
recompute.completed | an attribution recompute finished |
conversion.attributed | once per conversion definition, on its first attributed conversion |
export.completed / export.failed | a Conversion Sync export run settled |
profile.freshness.changed | the profile's attribution freshness moved |
conversion.attributed firing exactly once, durably, is what makes it usable as
"the setup worked" — it is stamped on the definition row by the projector, never
recomputed by a scan.
The messaging and commerce event types (message.received,
order.status.changed, catalog.updated, …) are documented with the surfaces
that produce them — see the Node SDK reference.
Secrets, tests and replays
POST /api/v1/webhooks/subscriptions/{id}/rotate-secret
POST /api/v1/webhooks/test/{id}
POST /api/v1/webhooks/deliveries/{id}/replayrotate-secret is an atomic dual-key rotation with a grace window: the old
secret keeps verifying while you deploy the new one, so a rotation is not an
outage. test/{id} fires a synthetic, correctly-signed event — the right way to
prove your verifier works before real traffic depends on it. replay re-enqueues
an existing delivery payload rather than fabricating a new one, so a consumer
that was down gets the actual bytes it missed.
Every delivery is HMAC-signed; verify the signature before trusting the body.
The runbook for adding a consumer is
docs/external-webhooks.md.
| Method | Path | What it does |
|---|---|---|
POST | /api/v1/webhooks/deliveries/{id}/replay | Replay a webhook delivery |
GET | /api/v1/webhooks/subscriptions | List webhook subscriptions |
POST | /api/v1/webhooks/subscriptions | Create a webhook subscription |
PATCH | /api/v1/webhooks/subscriptions/{id} | Update a webhook subscription |
DELETE | /api/v1/webhooks/subscriptions/{id} | Delete a webhook subscription |
POST | /api/v1/webhooks/subscriptions/{id}/rotate-secret | Rotate a subscription's HMAC secret |
POST | /api/v1/webhooks/test/{id} | Fire a synthetic test event |
Generated from openapi.json. The full request and response schema for every operation is in the OpenAPI document.