Custom webhooks for any CMS
Endpoint, signing secret, payload and retries.
In shortA custom webhook lets AI Rank Lab publish to any CMS or app you control. Create it from an article's publish panel with Add Webhook and choose Standard (v1): AI Rank Lab then sends one signed JSON request per article, with a signing secret shown once. Your endpoint verifies the HMAC signature, stores the idempotency key, and returns 2xx with the live URL. Timeouts, 429 and 5xx errors are retried after 1, 5 and 15 minutes; other 4xx responses are final.
When to use a custom webhook
Use it when your site is not WordPress, or when you want full control over how articles land: a headless CMS, a static-site build, a Next.js blog, or a script that drops articles into a review queue. You need a developer who can build a small HTTPS endpoint. For WordPress, use Connect WordPress instead.
Two payload modes
| Standard (v1), recommended | Custom template (legacy) | |
|---|---|---|
| What is sent | A fixed JSON contract: body HTML, H1, meta title and description, canonical URL, Open Graph and Twitter fields, FAQ pairs, the full JSON-LD graph, images with sideload details, and the link plan | Your own JSON with {{placeholders}} filled in |
| Security | HMAC-SHA256 signature on every request, with a signing secret | An API key you put in the body, plus any custom headers |
| Duplicates | An idempotency key on every request, so retries update rather than duplicate | Up to your receiver |
| Reliability | Built as an object and serialised once | An unusual character in the article can break the JSON |
| Where you create it | Article editor → publish panel → Add Webhook | Content → Publish → WordPress and webhooks → Custom Webhook, or the editor with the legacy mode |
The Custom Webhook form on the WordPress and webhooks page always creates a legacy template webhook, requires an API Key, and has no payload mode setting. To get a signed Standard (v1) webhook, create it from the article editor as shown below.
Create a Standard (v1) webhook
- Open the publish panelOpen any article in Content → Write → AI content writer and click Publish to CMS. Below Publish Content, the Webhooks card lists your endpoints. Click Add Webhook.
- Fill in the endpointEnter a Name, the Endpoint URL (the final
httpsaddress: publishing does not follow redirects), the Method, and any Headers your endpoint needs. Set Payload mode to Standard (v1) — recommended. - Copy the signing secretWhen you save, the Copy your signing secret dialog shows a secret starting
whsec_. Copy it into your receiver now and click I've saved it. It is shown once and cannot be retrieved. The dialog says you can make a new one by editing the webhook, but the edit form has no secret field today, so if you lose it, delete the webhook and add it again.
What your endpoint must do
Each publish is one request, using the method you chose (normally POST), with these headers: X-AIRankLab-Event: article.publish, X-AIRankLab-Timestamp, X-AIRankLab-Signature and X-Idempotency-Key, plus any custom headers you set.
- Verify the signature on the raw body, before parsing. Compute HMAC-SHA256 of
timestamp + "." + rawBodywith your secret, hex-encode it, prefixsha256=, and compare withX-AIRankLab-Signature. Parsing and re-encoding the JSON first changes the bytes and the signature will never match. - Reject old requests. Refuse a timestamp more than 5 minutes old, so a captured request can't be replayed.
- Treat the idempotency key as already handled. The key stays the same while the article is unchanged. If you have seen it, return the existing post instead of creating another.
- Update, don't duplicate. When the same article is published again after edits, the key changes; match on the article's id and update the post.
- Return 2xx with the live URL, for example
{ "ok": true, "postId": "1234", "link": "https://..." }. AI Rank Lab reads the URL back and uses it for citation tracking. - Ignore fields you don't recognise. New fields can be added within version 1; a receiver that rejects unknown keys will break.
Status codes and retries
| You return | AI Rank Lab does |
|---|---|
| 2xx | Marks it published and saves the returned URL |
| 400, 401, 403, 404, 422 | Treats it as final. No retry. Include a reason in the JSON so it shows in the publish log |
| 409 (already exists) | Final. Better: return 2xx with the existing post |
| 408, 429 or 5xx | Retries after 1, 5 and 15 minutes, then marks the job failed |
| No response (timeout, DNS, refused) | Retries on the same schedule |
The request waits up to 300 seconds. If your publish is slow (downloading images, rebuilding a site), return 2xx quickly and finish in the background. Retries carry the same idempotency key, so a slow first attempt never creates two posts.
Legacy template mode in one paragraph
A template webhook sends whatever JSON you write in Payload Template (JSON), with placeholders such as {{articleTitle}}, {{content}}, {{metaDescription}} and {{slug}} filled in. Click any entry under Available Placeholders (Click to copy) to copy it. Write "***" as the value of apiKey and the stored key is inserted at send time. Keep it for receivers that already expect a fixed format; prefer Standard (v1) for anything new.
Check yourself
0 of 3 answered.
Progress is saved in this browser.
Put the lesson to work
Paste your site and get a free SEO, AEO and GEO audit with the fixes, then come back to the next lesson.