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

EventWhen Arc0 captures it
connection.activatedA connection becomes active, including reconnect activation.
connection.failedAn authorization attempt fails or a connection requires reconnect.
execution.failedAn execution enters the failed state. Policy denials and unknown outcomes are separate states and do not emit this event.
approval.requestedA pending approval is created.
arc0.testAn 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.

On this page