Building the receiver? See the Webhook Reference for the full developer guide — handshake, signing, every event, every field, response contract, database schemas, and ready-to-paste receiver examples in 6 languages.
- Click Add Webhook.
- Enter your Webhook URL.
- Add an optional Secret Key — when set, theStacc signs every request so your receiver can verify it really came from theStacc. The secret must be at least 16 characters (and at most 256).
- Add custom headers (optional) — for authentication tokens, API keys, or routing.
- Click Test Connection to verify the URL is reachable.
- Click Sample Payload to send the real publish-shape JSON and validate your parser.
Two events your receiver must handle
theStacc sends a different payload shape for each button. Branch on theevent field — your receiver should handle both, or it will fail Test Connection even when the publish path works.
event: "test.ping" — fired by Test Connection. Liveness probe only. No blog fields.
200 {"ok": true}. Do not require title, slug, or content for this event — there are none.
event: "blog.published" — fired on every real publish (and by Sample Payload with a preview- prefixed blog_id for receiver validation).
blog_id starts with preview-, it’s a sample call — accept it but skip your CMS write so test runs don’t pollute your database.
What to return so the live URL appears in theStacc
Respond with200 (or 201) and a JSON body containing the live post URL. theStacc reads the response and stores both fields against the blog so the dashboard shows a clickable View live post link.
url(orpublished_url) — the public URL of the blog on your site. If omitted, theStacc shows a “Sent to webhook — your receiver didn’t return a public URL” warning.id— your internal CMS post id. Stored asexternal_post_idso future updates / unpublishes can target the right record.
blog_id starts with preview-), it’s fine to skip both fields and return {"ok": true, "skipped": true}.
Minimal receiver example (Next.js / Vercel)
Verify webhook signatures (recommended)
When you configure a webhook secret, theStacc signs every request with HMAC-SHA256 and sends the hex digest in theX-Webhook-Signature header. Verify it on every request — without verification, anyone who guesses your endpoint URL can post fake blogs to your CMS.
Critical: the signature is computed over the raw request body that theStacc sent, which is JSON serialized in compact form (json.dumps(payload, separators=(',', ':')) — no whitespace between keys and values). If you re-serialize the parsed JSON before hashing, the byte-for-byte representation will differ and the hashes won’t match. Always hash the raw bytes you receive over the wire.
Node.js / Next.js:
X-Webhook-Signature header is omitted and your receiver must trust the URL alone — fine for development, not recommended in production.
All event types
theStacc emits five different events on the same webhook URL. Branch onevent.
For
blog.updated / blog.unpublished / blog.deleted, look up the post in your CMS using the external_post_id you returned from blog.published (theStacc stores it and sends blog_id so you can map back).
Operational details
- Timeout: theStacc waits up to 15 seconds for a 2xx response. Slow CMS writes (image uploads, search indexing) will time out — return 2xx fast and do heavy work async.
- No automatic retries. A 5xx or timeout fails the publish in theStacc and the user sees a “Failed to publish” toast. If your endpoint is occasionally slow, queue the actual CMS write internally and return 2xx immediately.
- Redirects rejected. A 3xx response is treated as failure (anti-SSRF guardrail; a public webhook receiver that 302s to an internal address would otherwise bypass URL safety checks).
- HTTPS only.
http://URLs and internal/private IP ranges are rejected at save time. - Idempotency. Use
blog_idas a dedupe key. If theStacc ever resends (manual user retry), you’ll see the sameblog_id. - Test before writing receiver code. Point your webhook at webhook.site or requestbin.com first to inspect the actual request body and headers, then build your receiver against the real shape.
Best practices
- Use HTTPS — theStacc rejects
http://and internal addresses. - Return a 2xx status code. Redirects (3xx) are rejected.
- Verify the
X-Webhook-Signatureheader on every request when a secret is set. - Idempotency — use
blog_idas a dedupe key in case of retries. - Set up error alerting on your endpoint so silent 4xx/5xx responses don’t go unnoticed.
