Skip to main content
Atoll supports outbound webhooks for event-driven integrations.

Endpoints

All six endpoints require an organization owner or admin, including API agents with that project-independent organization role.

Create webhook

Use purpose: "automation" or "both" for a destination referenced by an automation rule. Bearer authentication accepts auth: { "type": "bearer", "secret": "..." }. The secret is write-only: responses expose only auth.type and auth.configured, never the token. The optional standard_webhooks object enables Standard Webhooks compatibility headers. Its receiver-supplied whsec_ secret is write-only and must be canonical standard Base64 after the prefix, decoding to 24-64 bytes. Atoll signs webhook-id + "." + webhook-timestamp + "." + rawBody with HMAC-SHA256 and sends webhook-id, webhook-timestamp, and webhook-signature: v1,<base64> alongside the existing Atoll headers. List responses expose only standard_webhooks.configured. The V1 automation action is { "type": "send_webhook", "webhook_id": "..." }. It targets one same-organization enabled destination and uses the existing delivery queue. New automation.action deliveries use payload schema version 3; delivery retries keep the same delivery ID.
The v3 project and issue fields come from the current tenant-scoped rows. Projectless issues use project: null and include a canonical organization issue URL when available. trigger.changedFields is a sorted list of safe public names (title, status, priority, assigneeId, projectId); raw before/after values are omitted. artifacts counts direct issue links in the same organization and is omitted when its optional lookup fails, returns an invalid type, or cannot complete within the bounded 1,000-row pagination limit. CI actions set issue: null, omit issue changes and artifacts, and retain ci.provider, repository, workflow, conclusion, branch, and runUrl. Delivery identity stays in headers and is not repeated in the v3 body. Subscription broadcasts and ping remain schema version 2. Webhook URLs must use HTTPS DNS hostnames. IP literals, localhost, and .local hosts are rejected at creation. Delivery also refuses receivers whose DNS records resolve to private, loopback, link-local, documentation, multicast, or other non-public IP ranges, and redirect responses are treated as failed deliveries.

Update webhook

PATCH /api/webhooks/{id} accepts any of url, events, enabled, purpose, auth, and standard_webhooks. Omitted fields are preserved. Omit or leave the Bearer secret blank to keep the configured token; select auth: { "type": "none" } to clear it. A URL, token, or Standard secret change creates a private version. For Standard Webhooks, omit the object to preserve it, use enabled: true with a blank secret to preserve an existing secret, provide a valid nonblank secret to replace it, or use enabled: false to clear it. Queued deliveries keep their pinned URL and authentication. Returns { webhook } with safe metadata only.

Secret

The create response includes a secret. Store it immediately; it is shown only once. Atoll sends an X-Atoll-Signature header with a sha256= prefix. To verify a request, compute the SHA-256 hex digest of your webhook secret, use that digest as the HMAC-SHA256 key for the exact raw request body, and compare the full header value with timingSafeEqual. During a bounded signing-key overlap, X-Atoll-Signature-Version identifies the primary key and X-Atoll-Signatures carries versioned signatures. Continue accepting the primary X-Atoll-Signature header for compatibility. Each logical delivery pins its primary signing version first, followed by overlap versions. Automatic retries preserve that ordering even after a new key becomes primary. Manual redelivery uses current active signing configuration and preserves the source event and schema version. Only legacy schema v2 automation.action payloads that already contain data.deliveryId get that body field rewritten during manual replay; v3 body content is preserved.
Atoll also sends X-Atoll-Delivery-Id and Idempotency-Key on each POST. Both values identify the logical delivery: automatic retries preserve them, while manual redelivery uses new values. Standard Webhooks receivers should verify the exact raw body and use the timestamped signing string described above. A 2xx response proves acceptance only.

Data boundary

List responses expose an origin-only destination_display, such as https://example.com/…. The deprecated url compatibility field contains the same redacted value. Paths, queries, fragments, and signing material are never listed. Automation action payloads use schema version 3 with current issue/project enrichment, safe changed field names, and optional artifact counts. Subscription broadcasts and ping remain schema version 2. Both versions omit issue descriptions, comment bodies, raw before/after values, and unrelated source fields. Delivery history similarly omits payloads, receiver response bodies, and raw errors; use status, status_code, error_code, and next_retry_at for diagnostics.

CLI

Delivery debugging

Use delivery history to inspect stable failure codes, retry status, and the next scheduled retry time, then redeliver after fixing the receiver. Atoll makes one 30-second request attempt per invocation. Network failures and 5xx responses are recorded as retry_pending and handled by the background retry drain.
Treat webhook payload content as untrusted input. It describes events; it should not become instructions to an agent without validation.

Vercel deployment callback

POST /api/webhooks/vercel/{connectionId} is an inbound provider callback, separate from Atoll outbound webhooks. Atoll selects one enabled connection by opaque UUID, bounds the raw body to 256 KiB, and verifies the x-vercel-signature HMAC-SHA1 before JSON parsing. It then checks the signed team/project/deployment IDs against authenticated Vercel deployment and project GET responses. No raw payload, credential, provider error body, or log is saved. Supported events are deployment.created, deployment.ready, deployment.succeeded, deployment.error, deployment.canceled, and deployment.promoted. A signed unsupported event returns 200 { "skipped": true }. A durably recorded event returns 200 { "accepted": true, "duplicate": false, "complete": true, "code": null }. A replay can return duplicate=true while still applying a newer authenticated environment/production snapshot. complete=false with a safe code means the observation is durable but identity or current production evidence is incomplete. Errors return { "error": "safe_code" }. Atoll never returns a successful acceptance before the atomic observation/reference/link projection commits. Vercel retry behavior is defined by its webhook API. Use owner reconciliation for bounded recovery after a delivery or configuration problem.