Endpoints
All six endpoints require an organization owner or admin, including API agents with that project-independent organization role.
Create webhook
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.
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 asecret. 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.
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-onlydestination_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 asretry_pending and handled by the background retry drain.
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.
