Webhook Integration
Webhooks let you connect EarlySEO to anything by POSTing article payloads to an HTTPS endpoint you control. Use them to publish to a custom CMS, trigger downstream workflows, sync to a database, or notify services.
Common Use Cases
- Publish to a headless CMS (Sanity, Contentful, Directus)
- Sync articles to your database and auto-publish
- Trigger image generation or internal linking pipelines
- Notify Slack / Discord when a new article is ready
Setup
- Go to Settings → Integrations in your EarlySEO dashboard
- Click Add Webhook
- Fill in the form:
| Field | Description |
|---|---|
| Endpoint URL | Your HTTPS endpoint URL, e.g. https://your-api.com/earlyseo-webhook |
| Access Token | A secret Bearer token (minimum 12 characters) — you validate this on your server |
| HMAC Secret (optional) | A shared secret for request signature verification |
- Click Create Integration
EarlySEO will POST to your endpoint every time an article is ready to publish.
Request Format
EarlySEO sends an HTTP POST with Content-Type: application/json and an Authorization: Bearer <token> header.
Example Payload
{
"id": "art_abc123",
"title": "Best Practices for API Design",
"slug": "api-design-best-practices",
"meta_description": "Short SERP-optimized description...",
"content_html": "<h1>...</h1><p>HTML body...</p>",
"content_markdown": "# ...\n\nMarkdown body...",
"published_at": "2025-02-22T10:00:00Z"
}Example: Next.js Route Handler
// app/api/earlyseo-webhook/route.ts
export async function POST(req: Request) {
const token = req.headers.get('authorization');
if (token !== `Bearer ${process.env.EARLYSEO_WEBHOOK_TOKEN}`) {
return new Response('Unauthorized', { status: 401 });
}
const payload = await req.json();
// persist, enqueue, publish, etc.
return new Response('ok', { status: 200 });
}HMAC Signature Verification (Optional)
If you set an HMAC Secret, EarlySEO signs the request body with HMAC-SHA256 and includes the signature in the X-EarlySEO-Signature header.
import crypto from 'crypto';
function verifySignature(
body: string,
secret: string,
signature: string
) {
const expected = crypto
.createHmac('sha256', secret)
.update(body)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(expected, 'hex'),
Buffer.from(signature, 'hex')
);
}Server Requirements
- Must be reachable via HTTPS (HTTP URLs are rejected)
- Should return 2xx quickly — do heavy processing in a background job
- Timeouts: EarlySEO waits up to 10 seconds for a response before marking the delivery as failed