Webhooks
Receive real-time notifications when crawl events occur. Instead of polling the API, Mulberry pushes events directly to your endpoint.
Creating a Webhook Endpoint
Create webhook endpoints from the Settings → Webhooks page in your dashboard. Configure the URL where you want to receive events and select which events to subscribe to.
Available Events
Subscribe to specific events or use wildcards:
Crawl Events
-
crawl.startedCrawl began processing -
crawl.completedCrawl finished successfully -
crawl.failedCrawl encountered an error -
crawl.page_successIndividual page crawled successfully -
crawl.*All crawl events (wildcard)
Business Listing Events
-
listing.createdNew listing discovered -
listing.updatedExisting listing modified -
listing.*All listing events (wildcard)
Live Page Events
-
live_page.polledPage was polled for changes -
live_page.changedChanges detected on monitored page -
live_page.errorPolling encountered an error -
live_page.*All live page events (wildcard)
Webhook Payload
When an event occurs, Mulberry sends a POST request to your endpoint with a JSON payload:
{
"id": "evt_xyz789",
"type": "crawl.completed",
"created_at": "2024-01-15T10:35:00Z",
"data": {
"crawl_id": "crawl_abc123",
"url": "https://docs.example.com",
"status": "completed",
"pages_crawled": 120,
"started_at": "2024-01-15T10:30:00Z",
"completed_at": "2024-01-15T10:35:00Z"
}
} | Field | Type | Description |
|---|---|---|
id | string | Unique event identifier |
type | string | Event type (e.g., crawl.completed) |
created_at | string | ISO 8601 timestamp of event creation |
data | object | Event-specific data payload |
Verifying Webhook Signatures
All webhook requests include a signature header for verification. This ensures the request came from Mulberry and wasn't tampered with.
Signature Header
The X-Mulberry-Signature header contains the signature:
X-Mulberry-Signature: t=1705315200,v1=abc123... | Component | Description |
|---|---|
t | Unix timestamp when the signature was generated |
v1 | HMAC-SHA256 signature of the payload |
Verification Steps
- Extract the timestamp and signature from the header
- Construct the signed payload:
{timestamp}.{request_body} - Compute HMAC-SHA256 using your webhook signing secret
- Compare the computed signature with the received signature
- Verify the timestamp is within an acceptable window (e.g., 5 minutes)
const crypto = require('crypto');
function verifyWebhook(payload, signature, secret) {
const [tPart, v1Part] = signature.split(',');
const timestamp = tPart.split('=')[1];
const receivedSig = v1Part.split('=')[1];
const signedPayload = `${timestamp}.${payload}`;
const expectedSig = crypto
.createHmac('sha256', secret)
.update(signedPayload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(receivedSig),
Buffer.from(expectedSig)
);
} Handling Webhook Requests
Your endpoint should follow these best practices:
Return a 2xx status code within 30 seconds
Always verify the signature before processing
Handle heavy work in background jobs
Handle duplicate events gracefully
Retry Behavior
If your endpoint fails to respond with a 2xx status, Mulberry retries with exponential backoff:
After 5 failed attempts, the webhook delivery is marked as failed and you'll receive a notification.
Webhook Signing Secret
Your webhook signing secret is available in Settings → Webhooks. You can regenerate it at any time, but this will invalidate signatures for any in-flight requests.