Project webhooks
Receive signed project notifications and inspect delivery attempts.
Project webhooks notify your backend about Arc0 lifecycle changes. They are separate from provider event subscriptions under Events. In an Embedded project, open Webhooks, enter an HTTPS endpoint, select events, and save. Owners and admins can configure the endpoint. Live and Sandbox keep independent settings.
Copy the signing secret immediately: the console shows it once. Secrets are encrypted at rest and never returned by a settings read. Rotate signing secret generates a new version. Queued deliveries keep their original version; retain the old verification secret for seven days. New events use the new secret. Updating the URL or disabling the endpoint cancels pending deliveries; an already started request can still finish.
Events available now
| Event | When Arc0 captures it |
|---|---|
connection.activated | A connection becomes active, including reconnect activation. |
connection.failed | An authorization attempt fails or a connection requires reconnect. |
execution.failed | An execution enters the failed state. Policy denials and unknown outcomes are separate states and do not emit this event. |
approval.requested | A pending approval is created. |
arc0.test | An admin chooses Send test event. This is sent regardless of event selections. |
connection.expired is later work: there is no automatic expiry transition that
reliably produces this event yet. Provider triggers and additional lifecycle events
are outside this settings page.
Notifications contain identifiers only, without provider credentials, arguments, results, names or raw error messages:
{
"id": "delivery-id",
"type": "execution.failed",
"version": "1",
"projectId": "project-id",
"occurredAt": "2026-10-16T12:00:00.000Z",
"data": { "resourceId": "execution-id" }
}For failed authorization attempts, resourceId is the connect-flow ID. For connection
transitions it is the connection ID; for approvals it is the approval ID.
Verify the signature
Verify the exact raw request body before parsing JSON. Arc0 sends arc0-event-id,
arc0-delivery-id, arc0-timestamp (Unix seconds), arc0-signing-version, and
arc0-signature (hex HMAC-SHA256). The signed bytes are
<event-id>.<timestamp>.<raw-body>. Reject timestamps more than five minutes from your
clock. The TypeScript SDK helper performs a constant-time signature comparison:
import { verifyEventSignature } from '@arc0/sdk';
const valid = verifyEventSignature({
rawBody, // exact received bytes, not JSON.stringify(parsedBody)
headers: Object.fromEntries(request.headers),
secrets: signingSecretsByVersion, // read from your secret store
});
if (!valid) return new Response('Invalid signature', { status: 401 });
const event = JSON.parse(rawBody);
// Atomically deduplicate event.id before applying effects.Delivery and retries
The worker attempts queued notifications with a one-minute recovery lease. A 2xx
response succeeds. Network failures, 408, 429 and 5xx responses retry, up to eight
attempts, with delays starting at 30 seconds and doubling to a one-hour ceiling.
Bounded Retry-After values can extend a delay. Other 4xx responses are terminal.
Deliveries older than seven days are terminal. Requests time out after ten seconds;
redirects are never followed. DNS results must be public IPv4 addresses and the
transport pins the checked address while preserving HTTPS certificate verification.
Delivery is at least once. A timeout or worker restart can repeat a request; deduplicate by the stable event ID. The timestamp and signature change per attempt. The console shows the latest 100 deliveries, their state, attempt count, and latest HTTP status. It does not retain response bodies or transport errors.
Each endpoint holds at most 1,000 pending or sending deliveries. When full, lifecycle
capture drops new notifications and increments dropped_count and last_dropped_at.
The console shows this warning; dropped notifications are not replayed. The original
connection, execution or approval change still succeeds. Repeated Send test event
requests return the existing pending or sending test delivery. A full queue without
an outstanding test returns HTTP 409.
Dispatch rotates projects by last-served time, with at most five projects sending concurrently across workers, one request per project, and three deliveries per project per turn. Dispatch claims recover after two minutes if the dispatcher stops.
The cleanup job deletes delivered, failed and cancelled log rows older than 30 days in bounded batches. Pending and sending rows are excluded from retention cleanup.
API
Project-bound business keys with events:manage can read/save settings, send a test
and inspect deliveries through /v1/management/project-webhooks (GET/PUT),
/v1/management/project-webhooks/test (POST), and
/v1/management/project-webhooks/deliveries (GET). These follow the management API's
data response envelope. Signing secrets are disclosed only through the console.
See the API reference and OpenAPI document.