Webhook Setup — Blogs & Products

Automatically push published blog posts and optimized product SEO data from WUDO to your website. When you publish a blog or optimize products in WUDO, the data gets delivered to your site instantly.

What are webhooks?

Webhooks push data from WUDO directly to your website. Instead of your website pulling content via the API, WUDO sends it automatically. This works for two types of content:

  • Blog posts — pushed when you hit "Publish" in the dashboard
  • Optimized products — pushed when product SEO optimization completes

Requirements

  • A WUDO account with an API Key integration
  • A website that can receive HTTP POST requests (Next.js, Express, etc.)
  • Access to set environment variables on your website
1

Complete Onboarding

During onboarding, choose "Custom Website" as your integration method. A webhook connection is created automatically when you finish setup. You'll be shown your Webhook Secret on the completion screen.

2

Add Environment Variables

Add both keys to your website's .env file:

WUDO_API_KEY=wudo_pk_your_api_key_here

WUDO_WEBHOOK_SECRET=whsec_your_webhook_secret_here

3

Add Webhook Receiver

Create webhook endpoints on your website. WUDO sends signed HTTP POST requests to these URLs:

/api/webhooks/blog— receives blog content on publish (event: blog.published)
/api/webhooks/products— receives optimized product SEO data (event: products.optimized)

Both endpoints should verify the X-Wudo-Signature header using your webhook secret. See our code examples for complete implementations.

Signature Verification

WUDO signs every webhook request using HMAC-SHA256 over the raw request body. The signature is sent in the X-Wudo-Signature header with the format sha256={hex}. Two additional headers are included: X-Wudo-Event (event name) and User-Agent: Wudo-Webhook/1.0.

// Node.js / Next.js signature verification
import crypto from 'crypto';

function verifySignature(rawBody: string, signature: string, secret: string): boolean {
  if (!signature?.startsWith('sha256=')) return false;

  const receivedHex = signature.slice('sha256='.length);
  const expectedHex = crypto
    .createHmac('sha256', secret)
    .update(rawBody, 'utf8')
    .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(receivedHex, 'hex'),
    Buffer.from(expectedHex, 'hex')
  );
}

// In your webhook handler:
const body = await request.text();
const signature = request.headers.get('X-Wudo-Signature') ?? '';
if (!verifySignature(body, signature, process.env.WUDO_WEBHOOK_SECRET!)) {
  return new Response('Invalid signature', { status: 401 });
}
const payload = JSON.parse(body);
4

Deploy & Test

Rebuild and deploy your website. Then go to Settings → Integrations and click "Test Connection" on the Auto-Publish card to verify everything works.

How It Works

  1. 1You publish a blog post in the WUDO dashboard
  2. 2WUDO sends a signed HTTP POST to your webhook endpoint with the full blog content
  3. 3Your website verifies the signature, saves the blog, and revalidates cache
  4. 4The new blog post appears on your website immediately

Product Webhook Payload

When product optimization completes, WUDO sends a products.optimized event to your webhook endpoint with the optimized SEO data for each product:

{
  "event": "products.optimized",
  "timestamp": "2026-02-15T14:30:00Z",
  "data": {
    "products": [
      {
        "external_id": "prod-123",
        "meta_title": "Premium Blue Cotton T-Shirt | Soft & Breathable",
        "meta_description": "Experience ultimate comfort...",
        "page_title": "Premium Blue Cotton T-Shirt",
        "page_description": "<p>Rich HTML content...</p>",
        "image_url": "https://..."
      }
    ],
    "total_count": 1,
    "exported_count": 1,
    "failed_count": 0
  }
}

Blog Webhook Payload

When you publish a blog, WUDO sends a blog.published event to your webhook endpoint with the full blog content. The same structure is used for blog.updated and blog.deleted events (deleted payloads only include slug). All fields use snake_case and null values are omitted.

{
  "event": "blog.published",
  "timestamp": "2026-02-15T14:30:00Z",
  "data": {
    "title": "10 Web Design Trends for 2026",
    "slug": "10-web-design-trends-2026",
    "html_content": "<article>Full HTML content...</article>",
    "css_content": "body { ... }",
    "js_content": "...",
    "excerpt": "Discover the latest web design trends...",
    "meta_title": "10 Web Design Trends for 2026 | YourSite",
    "meta_description": "Discover the latest web design trends...",
    "author": "Wudo AI",
    "tags": ["web design", "trends"],
    "keywords": ["web design", "2026", "trends"],
    "category": "Web Design",
    "featured_image_url": "/api/v1/blogs/images/{id}/banner.webp",
    "og_image_url": "/api/v1/blogs/images/{id}/og.webp",
    "schema_org_json": "{...}",
    "reading_time_minutes": 8,
    "word_count": 3500,
    "publish_immediately": true,
    "images": [
      {
        "url": "/api/v1/blogs/images/{id}/section-1.webp",
        "alt_text": "Modern dashboard layout example",
        "type": "section"
      }
    ]
  }
}

Need help?