Job Completion Webhook

Overview

Job Completion Webhooks let you trigger external services whenever a job succeeds or fails. Use them to send Slack notifications, update spreadsheets, trigger downstream workflows, or integrate with any service that accepts HTTP requests.

Configure webhooks under Webhook in the Settings sidebar of your workflow editor.

Configuration

  • Webhook URL: The endpoint to receive notifications. Supports template variables like {{keyword}}, {{title}}, {{slug}}, {{notes}}, and any custom CSV columns.
  • Trigger Conditions:
    • On Success: Fire when a job completes successfully
    • On Failure: Fire when a job fails
    • Both can be enabled independently
  • Include Article Content: When enabled, the full article HTML is included in the payload
  • Webhook Secret: Optional secret for HMAC-SHA256 request signing (see Security below)

Payload Format

Publish Owl sends a JSON POST request with the following structure:

{`{
  "event": "job.succeeded",    // or "job.failed"
  "timestamp": "2026-01-15T10:30:00.000Z",
  "job": {
    "id": "abc123",
    "status": "succeeded",
    "keyword": "best coffee makers",
    "title": "10 Best Coffee Makers in 2026",
    "slug": "best-coffee-makers-2026",
    "outputUrl": "https://example.com/best-coffee-makers-2026",
    "content": "

...

...", // Only if "Include content" is enabled "metaDescription": "Discover...", "featuredImage": "https://...", "wordCount": 2500, "tokens": 15000, "costCents": 12, "error": null, // Error message if failed "scheduledDate": null, "createdAt": "2026-01-15T10:00:00.000Z" }, "agent": { "id": "def456", "name": "Coffee Blog Writer", "authorName": "John" }, "site": { "id": "ghi789", "name": "My Coffee Blog" } }`}

Security

When you configure a Webhook Secret, Publish Owl signs each request with HMAC-SHA256. The signature is sent in the X-Webhook-Signature header.

To verify the signature in your endpoint:

{`// Node.js example
const crypto = require('crypto');

function verifySignature(body, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(JSON.stringify(body))
    .digest('hex');
  return signature === expected;
}

app.post('/webhook', (req, res) => {
  const signature = req.headers['x-webhook-signature'];
  if (!verifySignature(req.body, signature, 'your-secret')) {
    return res.status(401).json({ error: 'Invalid signature' });
  }
  // Process webhook...
});`}

Testing

Use the built-in test buttons to send sample payloads to your endpoint:

  • Test Success: Sends a sample job.succeeded payload
  • Test Failure: Sends a sample job.failed payload

Test requests include the header X-Webhook-Test: true so your endpoint can distinguish test payloads from real ones.

Common Use Cases

  • Slack/Discord notifications: Get notified when articles are published or fail
  • Zapier/Make/n8n: Trigger automation workflows on job completion
  • Spreadsheet tracking: Log all published articles to Google Sheets
  • Error alerting: Get immediate alerts when jobs fail so you can investigate
  • Custom dashboards: Feed job data into your own analytics or monitoring system
Was this helpful?