Integrations
Publish to any site with a webhook
Receive SEOForge articles on your own endpoint as JSON, for Next.js, Ghost, headless CMSs or any custom stack.
If your site isn't on WordPress, Shopify, Wix or Framer, SEOForge can send each article to a URL you control. Your code then saves it however you like: a database row, a Markdown file committed to Git, or a call to your CMS.
Set it up#
Create an endpoint
Build an HTTPS endpoint that accepts
POSTrequests with a JSON body and checks the bearer token (see below). It should reply with any 2xx status once it has saved the article.Add it in SEOForge
In Settings → Integrations, choose Generic Webhook. Fill in:
- Webhook URL: your endpoint. It must use HTTPS.
- Auth Token: a secret you choose. SEOForge sends it in the
Authorizationheader. - Site URL and Blog Path (default
/blog/): used to build each article's canonical URL.
Then click Save Integration.
Test it
Click Test Connection on the integration card. SEOForge sends a test event, and your endpoint should reply with a 2xx.
The integration card also has a setup guide with sample code for serverless hosting, a VPS or Docker, and saving straight to a database.
Requests#
Every request is a POST with these headers:
Content-Type: application/json
Authorization: Bearer YOUR_AUTH_TOKEN
X-Source: seoforgeCheck the Authorization header and reject anything that doesn't match your token. Requests aren't signed beyond that token, so keep it secret and long.
Test event#
{
"event_type": "test_connection",
"timestamp": "2026-11-06T09:00:00.000Z",
"data": { "test": true }
}Publish event#
{
"event_type": "publish_article",
"timestamp": "2026-11-06T09:00:00.000Z",
"data": {
"article": {
"id": "b7f1…",
"title": "How to choose a CRM for a small team",
"content_markdown": "…",
"content_html": "<p>…</p>",
"excerpt": "…",
"meta_description": "…",
"slug": "how-to-choose-a-crm-for-a-small-team",
"canonical_url": "https://example.com/blog/how-to-choose-a-crm-for-a-small-team",
"tags": ["crm for small team"],
"image_url": "https://…/cover.jpg",
"word_count": 2417
}
}
}| Field | Notes |
|---|---|
id | The SEOForge article ID. Use it to update an article you've already saved |
content_markdown, content_html | The same article in two formats. The cover image isn't included in the body |
excerpt | The first 300 characters |
slug | Based on the article title |
canonical_url | Your Site URL + Blog Path + slug |
tags | The primary keyword |
image_url | The cover image |
Responses, timeouts and retries#
- Any 2xx reply counts as success. A 2xx only means your endpoint accepted the request, so return an error if saving fails.
- SEOForge waits up to 30 seconds for a publish and 10 seconds for a test.
- Failed requests aren't retried automatically. Publish again from SEOForge.
- The integration card's Publish History shows what your endpoint replied each time.
