Connect a custom webhook
Send publishes and site-audit fixes to your own HTTPS endpoint as a signed JSON envelope.
If your CMS isn't one SearchChamp connects to directly, the custom webhook is the escape hatch. SearchChamp POSTs a signed JSON envelope to an HTTPS endpoint you control — a custom CMS, a serverless function, a Zapier or Make hook, anything that can receive an authenticated request — and your endpoint does the publishing.
What you'll need
- An HTTPS endpoint that can receive a POST and verify an HMAC signature. Plain
http://isn't accepted.
Steps
Open the custom webhook card
Go to Site Settings → Integrations and scroll to Custom webhook. Select Connect.

Enter your URLs
Give SearchChamp a Webhook URL — where publishes are delivered. A Revert URL is optional; if you leave it blank, revert events go to the same endpoint. Both must be https://.
Save the signing secret
On connect, the card shows a signing secret once. Copy it somewhere safe — it isn't displayed again. You'll need it to verify that incoming requests really came from SearchChamp.
Test the connection
Use Test connection on the card. It sends a cw.test_fire event, signed exactly like a real publish, with no article payload. Respond with any 2xx status to confirm your endpoint is reachable and your signature check works.
Verifying requests
Every request is signed with HMAC-SHA256 over the exact JSON request body, using your connection's signing secret. Three headers come with every request:
| Header | Value |
|---|---|
X-Atlio-Signature | sha256=<hex-hmac> |
X-Atlio-Issued-At | ISO-8601 timestamp the request was signed at |
X-Atlio-Idempotency-Key | A UUID — dedupe on this, deliveries may be retried |
Verify the signature against the raw, unparsed request body. The signature is computed before serialization on our side, and re-serializing a parsed JSON object can produce different bytes (key order, whitespace) that won't match.
Events
Three event types arrive at your endpoint:
cw.publish— an article was published or updated. Carries the full publish payload: title, body, slug, status, tags, and SEO meta.cw.revert— a publish was reverted. Carries thecms_post_idyour endpoint returned from the originalcw.publish.cw.test_fire— sent by Test connection. No article payload.
The exact envelope shape for each, plus a Node.js signature-verification snippet, is documented in the app: open Site Settings → Integrations → Custom webhook → View documentation.
Responding
Return any 2xx status for success. On cw.publish, a JSON body containing cms_post_id and published_url is optional but recommended — SearchChamp records both if present, and cms_post_id is what makes a later revert possible.
Any non-2xx status, a timeout (15 seconds), or a connection error is recorded as a failed delivery. Failed publish and revert deliveries are not retried automatically — use the idempotency key if you build your own retry or backfill tooling.
What the webhook supports
| Capability | Support |
|---|---|
| Publish | Partial — delivery only. A success means your endpoint accepted the payload, not that the article is live |
| Edit content | Not supported — each delivery is a full payload, and SearchChamp can't read your page back, so republishing sends a fresh copy rather than editing in place |
| Meta tags | Partial — title, description, OG fields, and focus keyword are in the payload; writing them onto the page is your endpoint's job |
| Images | Partial — images are delivered, not uploaded. The payload carries fetchable image URLs plus a placeholder token for each, and the body arrives with tokens in place of <img> tags. Your endpoint must download each image and swap in its own URLs; ignoring them publishes the tokens as literal text |
| llms.txt | Not supported — the webhook carries article publishes only |
Disconnecting
Disconnecting immediately invalidates the stored signing secret on our side — no further requests are sent, signed or otherwise. Reconnecting generates a brand-new secret; the old one is never reused.