[ docs · webhooks ]preview

React to drift, runs, and publishes — the moment they happen.

Subscribe to pipeline events. Quill delivers signed POSTs to your endpoint, with idempotent retries and a queryable delivery log. Use them to ping Slack on stale-doc detection, trigger your CI to republish, or fan out into your own analytics.

In preview. Webhook deliveries are landing in the next release cycle. The CLI emits the same events as a structured log today — if you need the integration path before the HTTP surface ships, email api@quilldocs.ai with your use case.
[ events ]

Five events. The ones that matter.

Quill emits events at the points in the pipeline where your CI, your operator, or your Slack would want to know. Every event includes the workspace id, the run or article id, and enough context to act without a follow-up API call.

run.completedevent

A pipeline run finished successfully. Payload includes the run id, the feature it covered, the queue of articles it produced, and timing.

run.failedevent

A run errored. Payload includes the failure category (discovery, runner, narration, video, or docs-gen), the structured error, and a link to the trace.

article.draftedevent

A new article (or article version) landed in the review queue. Includes the article id, its surface (help-center, dev-docs, blog, changelog), and the run that produced it.

article.publishedevent

An operator approved an article and it went live on the public surface. Includes the article id, the public URL, and the approver.

drift.detectedevent

Quill noticed that code an article cites has changed in a way that probably invalidates the doc. Payload includes the article, the affected code paths, and a confidence score.

[ delivery posture ]

How Quill delivers them.

Signed POSTs to your URL

JSON body, X-Quill-Signature header with an HMAC-SHA256 of the payload using your subscription secret. Verify before trusting — the secret rotates with one click from the portal.

Retries with backoff

Non-2xx responses get re-delivered with exponential backoff — 1s, 5s, 30s, 5m, 30m, 1h, 6h. Eight attempts over a 24-hour window. Subsequent failures land in the dead-letter queue, visible from the portal.

Delivery log

Every attempted delivery — successful, retried, or failed — is persisted with the payload, response code, response body (truncated), and timing. Searchable for 30 days; exportable for long-term storage.

Replay on demand

Any past delivery can be re-fired against the same URL or a different one. Useful when you're debugging an integration or backfilling after an outage on your side. One click in the portal or a single API call.

[ payload shape ]

A representative event.

Every event has a top-level envelope (id, type, workspace, timestamp) and a typed data field. The shape inside data is stable per event type.

{ "id": "evt_01HMBYZ...", "type": "article.drafted", "workspace": "ws_acme", "created_at": "2026-06-10T03:14:22Z", "data": { "article_id": "art_flows_create_v3", "surface": "help-center", "title": "Create your first flow", "version": 3, "queue_url": "https://app.quilldocs.ai/articles/art_flows_create_v3", "run_id": "run_01HMBXY..." } }
[ verifying ]

Verify the signature.

Constant-time comparison against the HMAC of the raw body. The same pattern Stripe / GitHub use. Node example:

import crypto from "node:crypto"; export function verifyQuill(rawBody: string, header: string, secret: string) { const expected = crypto .createHmac("sha256", secret) .update(rawBody, "utf8") .digest("hex"); const a = Buffer.from(expected, "hex"); const b = Buffer.from(header, "hex"); return a.length === b.length && crypto.timingSafeEqual(a, b); }

Build the integration before the docs catch up.

The CLI emits the same events as a structured log today. Tell us what you're building and we'll point you at the right hook.