Auto Blogger
EN
Log in
Menu

Webhooks send your server or automation tool a message each time a post is published on a website. Use them with the WordPress plugin, Zapier, Make, your own app, or any service that accepts an HTTPS URL.

Set up a webhook

  1. Sign in to the dashboard.
  2. Open Websites and select your site.
  3. Open Integrations and add a Webhook.
  4. Enter your URL — it must start with https://.
  5. Optionally add a Secret if your endpoint should verify that requests come from Auto Blogger.

You can add more than one webhook per website. Each URL receives the same notification when a post goes live.

Request details

Each delivery is an HTTPS POST with a JSON body.

Header Value
Content-Type application/json
Accept application/json
Idempotency-Key Unique per publish (e.g. 42-1716206400) — use this to ignore duplicate deliveries after a retry
X-Webhook-Signature Only when you set a Secret — see Verify the signature

Your endpoint should respond with any 2xx status within about 30 seconds. Queue heavy work on your side after you respond.

Example payload

When a post goes live, the body looks like this (pretty-printed for readability):

{
  "event": "post.published",
  "website": {
    "uuid": "550e8400-e29b-41d4-a716-446655440000"
  },
  "post": {
    "id": 42,
    "slug": "how-we-grew-organic-traffic",
    "title": "How we grew organic traffic",
    "meta_title": "How we grew organic traffic | Acme Blog",
    "meta_description": "A practical guide to improving search visibility without sacrificing quality.",
    "published_at": "2026-05-20T14:30:00+00:00",
    "url": "https://www.example.com/how-we-grew-organic-traffic",
    "html_excerpt": "Search visibility comes from consistent publishing and clear structure…",
    "html": "<p>Search visibility comes from consistent publishing…</p>"
  }
}

When the post has a cover image, an images object is included:

{
  "event": "post.published",
  "website": {
    "uuid": "550e8400-e29b-41d4-a716-446655440000"
  },
  "post": {
    "id": 42,
    "slug": "how-we-grew-organic-traffic",
    "title": "How we grew organic traffic",
    "meta_title": "How we grew organic traffic | Acme Blog",
    "meta_description": "A practical guide to improving search visibility without sacrificing quality.",
    "published_at": "2026-05-20T14:30:00+00:00",
    "url": "https://www.example.com/how-we-grew-organic-traffic",
    "html_excerpt": "Search visibility comes from consistent publishing and clear structure…",
    "html": "<p>Search visibility comes from consistent publishing…</p>",
    "images": {
      "optimizedImage": "https://cdn.example.com/media/42/conversions/cover.jpg",
      "alt": "Chart showing traffic growth",
      "title": "Organic traffic growth",
      "banner_facebook": "https://cdn.example.com/media/42/conversions/og.jpg",
      "banner_pressebox_shortstory": "https://cdn.example.com/media/42/conversions/og.jpg",
      "banner_own_blog": "https://cdn.example.com/media/42/conversions/og.jpg"
    }
  }
}

Field reference

Field Description
event Always post.published for publish notifications
website.uuid Your website’s identifier (same as in feed URLs)
post.id Internal post ID (use with Idempotency-Key for deduplication)
post.slug URL slug on your site
post.title Post headline
post.meta_title SEO title (falls back to the post title when not set)
post.meta_description SEO description
post.published_at ISO 8601 timestamp when the post went live
post.url Full public URL on your website
post.html_excerpt Plain-text summary (up to 500 characters)
post.html Full article HTML
post.images Present only when a cover image exists — URLs for social and embed use

Verify the signature

If you configured a Secret, every request includes:

X-Webhook-Signature: sha256=<hex>

The value is sha256= followed by the HMAC-SHA256 of the raw request body (the exact JSON bytes), using your secret as the key.

Important:

  • Verify against the raw body before your framework re-encodes JSON.
  • Compare signatures in a constant-time way to reduce timing attacks.

PHP

$secret = 'your-webhook-secret';
$rawBody = file_get_contents('php://input');
$header = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';

$expected = 'sha256=' . hash_hmac('sha256', $rawBody, $secret);

if (! hash_equals($expected, $header)) {
    http_response_code(401);
    exit('Invalid signature');
}

$payload = json_decode($rawBody, true, flags: JSON_THROW_ON_ERROR);

Node.js

const crypto = require('crypto');

const secret = 'your-webhook-secret';
const rawBody = req.body; // use raw body middleware, not parsed JSON
const header = req.headers['x-webhook-signature'] ?? '';

const expected =
  'sha256=' +
  crypto.createHmac('sha256', secret).update(rawBody, 'utf8').digest('hex');

const valid =
  header.length === expected.length &&
  crypto.timingSafeEqual(Buffer.from(header), Buffer.from(expected));

if (!valid) {
  return res.status(401).send('Invalid signature');
}

const payload = JSON.parse(rawBody);

Python

import hmac
import hashlib

secret = b"your-webhook-secret"
raw_body = request.get_data()  # bytes, before JSON parsing
header = request.headers.get("X-Webhook-Signature", "")

expected = "sha256=" + hmac.new(secret, raw_body, hashlib.sha256).hexdigest()

if not hmac.compare_digest(expected, header):
    return "Invalid signature", 401

payload = json.loads(raw_body)

Test your endpoint

You can simulate a delivery locally (replace URL and secret):

BODY='{"event":"post.published","website":{"uuid":"550e8400-e29b-41d4-a716-446655440000"},"post":{"id":42,"slug":"test","title":"Test","meta_title":"Test","meta_description":"","published_at":"2026-05-20T12:00:00+00:00","url":"https://www.example.com/test","html_excerpt":"Hi","html":"<p>Hi</p>"}}'
SECRET='your-webhook-secret'
SIG="sha256=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac "$SECRET" | awk '{print $2}')"

curl -sS -X POST 'https://your-server.example/webhooks/auto-blogger' \
  -H 'Content-Type: application/json' \
  -H "X-Webhook-Signature: $SIG" \
  -H 'Idempotency-Key: 42-1716206400' \
  -d "$BODY"

Retries and duplicates

  • Failed deliveries are retried a few times (after about 10 minutes, then about 1 hour).
  • The same publish may arrive more than once — use Idempotency-Key (or post.id + published_at) to process each publish only once.
  • Check delivery status on the post in your dashboard, or use Resend webhooks if you need another attempt.

Related guides