Build & Publish Webhooks
Chinaski can notify external systems when something happens (a build finishing, scheduled content publishing, a post changing) by sending a signed webhook to a URL you configure. It does not accept webhooks to trigger builds; it only sends them after the event happened.
Where you configure them
Under Settings → Integrations:
- Build Webhook URL: notified after a successful static build.
- Publish Webhook URL: notified when scheduled content is auto-published.
- Webhook Secret: shared secret used to sign all webhook deliveries.
Nothing fires in air-gap mode: all webhook sending is disabled there.
The build webhook
When a build succeeds, Chinaski POSTs a JSON body to your Build Webhook URL with:
status: “ok”built_at: when the build finished (unix timestamp)site_url: your configured Site URLlangs: the list of your active language codes
Use this to kick off a deployment pipeline, ping your CDN to revalidate, or refresh any external cache.
The publish webhook
When scheduled content goes live (the minute-tick scheduler fires), the Publish Webhook URL receives the notification ahead of the optional notification email and the triggered rebuild. This is how downstream systems can start caching or translating content the moment it becomes public.
Verifying deliveries came from Chinaski
If you’ve set a Webhook Secret, every POST includes a header:
X-Chinaski-Signature: sha256=<hex> The hex value is the HMAC-SHA256 digest of the exact body bytes, using your shared secret as the key. Recompute the digest over the raw body on your side and compare before trusting the payload.
Post webhooks (a separate system) additionally filter by event: the configured list must be a subset of published, updated, deleted; an unrecognized name is dropped, a list with nothing valid falls back to all three defaults, and a stored list with no valid entries means the hook never fires.
Constraints the sender applies
- Targets must be public URLs. Webhooks aimed at loopback, private network ranges, or non-resolvable destinations are refused.
- POST by default with a
Content-Type: application/jsonbody. If a delivery’s method is customized you can use PUT or PATCH too; GET and other verbs aren’t used. - No redirects are followed. If your endpoint redirects, Chinaski won’t follow it; respond directly at the URL you configure.
- Response size limits apply: the build webhook reads it all; other hooks cap the captured response body at ~64 KiB. Connect/request/inactivity timeouts are set per webhook type (default 5 s connect, 10 s request, 30 s inactivity).
- Only 200–299 responses count as success: anything else gets recorded and queued for retry.
At-least-once delivery and retries
A webhook that fails (including resolving-timeouts and non-2xx responses) is queued for retry: the first at +1 minute, the second at +10 minutes, the third at +1 hour. A worker checks for due retries every 30 seconds, sending from the stored payload. Retries rewrite the delivery record rather than creating new ones, so each delivery has one queue entry.
Protection from flaky targets
If a target keeps failing, its circuit breaker trips and delivery to it pauses: a skipped open-breaker target doesn’t generate more rows. Admin-side, on the Webhooks screen, the delivery log shows the response for each send, and there’s a reset circuit-breaker button to manually restore an endpoint.
The delivery log keeps a rolling tail of history per target rather than unbounded growth, keeping your db lean while still letting you confirm what happened, when, and the payload that traveled.
Post webhooks are separate
A distinct post webhook system lets you register endpoints per event (published / updated / deleted) with their own secrets and event filters; see the corresponding page for events, payloads, and template details.