All docsPublishing

Connect your site & publishing API

When NeverDrafts generates an article to win an AI answer, it can publish it for you. Native integrations cover the popular platforms; the webhook API covers everything else.

Native integrations

WordPress

Install the free NeverDrafts plugin from wordpress.org, then connect it in Dashboard → Integrations. Articles publish straight into WordPress as drafts or live posts.

Get the WordPress plugin →

Webflow

Create a Webflow API token (Site settings → Apps & integrations → API access), paste it in Dashboard → Integrations, and pick the site and CMS collection to publish into.

Framer

Install the NeverDrafts plugin from the Framer marketplace and connect it to your project — published articles sync into your Framer CMS.

Get the Framer plugin →

Notion

Connect your Notion workspace in Dashboard → Integrations, pick a database, and map its fields — published articles land as pages in that database.

Anything else

Use the custom webhook below — we POST every published article to your endpoint as JSON, and your code puts it wherever it belongs.

All native integrations are set up in Dashboard → Integrations — no code required.

Webhook API — publish to your own CMS

Add an API Webhook integration and NeverDrafts will POST every published article to your endpoint. You need three things:

  • —Integration name: 2–30 characters, letters/numbers/spaces only.
  • —Webhook endpoint: A public HTTPS URL on your server that receives the POST.
  • —Access token: A secret you choose; sent with every request as Authorization: Bearer <token>.

Authentication

Every request carries your access token as Authorization: Bearer <token>. Your handler should reject anything without a valid token:

server.js
javascript
// Node.js/Express example
app.use(express.json());

const ACCESS_TOKEN = process.env.ACCESS_TOKEN;

function validateAccessToken(req) {
  const authHeader = req.headers.authorization || '';
  return authHeader.startsWith('Bearer ') && authHeader.split(' ')[1] === ACCESS_TOKEN;
}

app.post('/webhook', (req, res) => {
  if (!validateAccessToken(req)) {
    return res.status(401).json({ error: 'Invalid access token' });
  }
  // Handle payload
  res.status(200).json({ ok: true });
});

The publish_articles event

When an article is published, we send this JSON payload — both markdown and HTML bodies are included, plus the metadata your CMS needs:

payload.json
javascript
{
  "event_type": "publish_articles",
  "timestamp": "2026-04-01T12:00:00Z",
  "data": {
    "articles": [
      {
        "id": "123456",
        "title": "How to Implement Webhooks",
        "content_markdown": "Webhooks are a powerful...",
        "content_html": "<p>Webhooks are a powerful...</p>",
        "meta_description": "Learn how to implement webhooks in your application",
        "created_at": "2026-03-31T10:30:00Z",
        "image_url": "https://example.com/images/webhook-article.jpg",
        "slug": "how-to-implement-webhooks",
        "tags": ["webhooks", "integration", "api"],
        "structured_data": {
          "article": {
            "@context": "https://schema.org",
            "@type": "Article",
            "headline": "How to Implement Webhooks",
            "description": "Learn how to implement webhooks in your application",
            "datePublished": "2026-03-31T10:30:00Z",
            "author": {
              "@type": "Person",
              "name": "Jane Doe",
              "url": "https://example.com/about/jane"
            },
            "publisher": { "@type": "Organization", "name": "Example Inc" }
          },
          "faq": {
            "@context": "https://schema.org",
            "@type": "FAQPage",
            "mainEntity": [
              {
                "@type": "Question",
                "name": "What is a webhook?",
                "acceptedAnswer": {
                  "@type": "Answer",
                  "text": "An HTTP request your server receives when an event happens."
                }
              }
            ]
          }
        },
        "sources": [
          {
            "url": "https://developer.mozilla.org/en-US/docs/Web/HTTP",
            "title": "HTTP | MDN"
          }
        ],
        "author": { "name": "Jane Doe", "url": "https://example.com/about/jane" }
      }
    ]
  }
}

New optional fields

Newer articles also carry the fields below. Each is optional: treat a missing or null value as "not available" rather than as an error.

  • —structured_data: schema.org JSON-LD to embed in an application/ld+json script tag. article is an Article object; faq is a FAQPage object, present only when the piece has an FAQ section.
  • —sources: The pages the article cites, as [{ url, title }]. Render them as a references list or use them for link checks.
  • —author: The byline configured in Dashboard -> Settings -> Brand & author, as { name, url }. Set it as the post author; it matches the Article schema author.

Testing & best practices

  • —In Dashboard → Integrations → Add Integration → API Webhook, enter your endpoint and token, then click Test Your Webhook before publishing for real.
  • —Respond with HTTP 200 as fast as possible; process the payload asynchronously if your import is slow.
  • —401s mean the Authorization header doesn't match your configured token exactly; 500s usually mean JSON parsing — expect Content-Type: application/json.