Skip to content

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#

  1. Create an endpoint

    Build an HTTPS endpoint that accepts POST requests with a JSON body and checks the bearer token (see below). It should reply with any 2xx status once it has saved the article.

  2. 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 Authorization header.
    • Site URL and Blog Path (default /blog/): used to build each article's canonical URL.

    Then click Save Integration.

  3. Test it

    Click Test Connection on the integration card. SEOForge sends a test event, and your endpoint should reply with a 2xx.

The webhook form in SEOForge

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:

http
Content-Type: application/json
Authorization: Bearer YOUR_AUTH_TOKEN
X-Source: seoforge

Check 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#

json
{
  "event_type": "test_connection",
  "timestamp": "2026-11-06T09:00:00.000Z",
  "data": { "test": true }
}

Publish event#

json
{
  "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
    }
  }
}
FieldNotes
idThe SEOForge article ID. Use it to update an article you've already saved
content_markdown, content_htmlThe same article in two formats. The cover image isn't included in the body
excerptThe first 300 characters
slugBased on the article title
canonical_urlYour Site URL + Blog Path + slug
tagsThe primary keyword
image_urlThe 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.