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.succeededpayload - Test Failure: Sends a sample
job.failedpayload
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