The webhook connection → POSTs each published article to your endpoint as JSON, and your system decides what a "publish" means — write to your CMS, queue a build, forward it somewhere else. This page is the contract for the developer implementing the receiver.
Build the receiver
To implement the receiving endpoint:
- Implement an HTTPS endpoint that accepts a JSON POST.
- Respond
200quickly — acknowledge receipt, then process. A slow receiver risks timeouts that read as failures. - Upsert on
externalId, render whichever content format you prefer, and return the public URL in your response if your system knows it — that lets publish verification → check the real page.
The payload
The payload carries the article in both formats plus its metadata:
| Field | What it holds |
|---|---|
event | What happened — a publish event for a new article |
title | The article title |
contentHtml | The full article as HTML |
contentMarkdown | The same article as markdown — use whichever fits your stack |
excerpt | A short summary for listings |
externalId | Stable ID for this article — the idempotency key |
Treat externalId as the dedupe key: retries and republishes carry the same ID, so an upsert on it makes your receiver idempotent for free.
Limits and usage
- Delivery is per published article — there's no event firehose beyond publishes.
- Your endpoint must be reachable from the public internet over HTTPS. The sender doesn't join private networks.
- Payload sizes are article-sized; a receiver with tiny body limits will truncate long posts.
If something isn't working
You received the same article twice. A retry after a slow first response — this is why externalId upserts matter. Idempotent receivers never notice.
Publishes show failed but your endpoint got the POST. Your response wasn't a 2xx, or it arrived after the timeout. Return 200 first, process after.
HTML renders oddly in your CMS. Use contentMarkdown and render it with your own pipeline — the markdown is the cleaner source when your system has opinions about HTML.