Webhooks
Test your webhook endpoint to verify it can receive notifications from meter.
Test webhook delivery
Send a sample webhook payload to verify your endpoint is configured correctly.
Request body
{
"webhook_url" : "https://your-app.com/webhooks/meter"
}
Field Type Required Description webhook_urlstring Yes The webhook URL to test
Response
{
"success" : true ,
"status_code" : 200 ,
"message" : "Webhook delivered successfully"
}
Field Type Description successboolean Whether the webhook was delivered successfully (2xx response) status_codeinteger HTTP status code returned by your endpoint (0 if request failed) messagestring Human-readable result message
Example
curl -X POST https://api.meter.sh/api/webhooks/test \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"webhook_url": "https://my-app.com/webhook"
}'
Meter sends webhooks for both successful and failed jobs. The payload structure differs based on the job status.
Success payload
Sent when a job completes successfully:
{
"job_id" : "660e8400-e29b-41d4-a716-446655440000" ,
"schedule_id" : "880e8400-e29b-41d4-a716-446655440000" ,
"status" : "completed" ,
"url" : "https://example.com/products" ,
"results" : [
{ "title" : "Sample Product A" , "price" : "$19.99" },
{ "title" : "Sample Product B" , "price" : "$29.99" }
],
"item_count" : 2 ,
"has_changes" : true ,
"content_hash" : "7f3d9a2b4c1e5f8a9b0c1d2e3f4a5b6c" ,
"completed_at" : "2025-01-15T10:30:12Z" ,
"metadata" : { "project" : "my-project" }
}
Field Type Description job_idUUID ID of the scrape job schedule_idUUID ID of the schedule that triggered the job statusstring Always completed for success webhooks urlstring The URL that was scraped resultsarray Extracted data from the page item_countinteger Number of items extracted has_changesboolean Whether content changed since last run content_hashstring Hash of the extracted content completed_atdatetime When the job completed metadataobject Custom JSON metadata from webhook_metadata (if configured)
Failure payload
Sent when a job fails:
{
"job_id" : "660e8400-e29b-41d4-a716-446655440000" ,
"schedule_id" : "880e8400-e29b-41d4-a716-446655440000" ,
"status" : "failed" ,
"url" : "https://example.com/products" ,
"error" : "Page not accessible: 404 Not Found" ,
"completed_at" : "2025-01-15T10:30:12Z" ,
"metadata" : { "project" : "my-project" }
}
Field Type Description job_idUUID ID of the scrape job schedule_idUUID ID of the schedule that triggered the job statusstring Always failed for failure webhooks urlstring The URL that failed to scrape errorstring Error message describing what went wrong completed_atdatetime When the job failed metadataobject Custom JSON metadata from webhook_metadata (if configured)
Failure webhooks do not include results, item_count, has_changes, or content_hash fields.
Webhook types
Meter supports four webhook formats:
Type Description Secret required standardFull JSON payload (default) Yes (auto-generated) slackFormatted Slack incoming webhook message Yes (auto-generated) slack_workflowSlack Workflow Builder trigger payload No discordFormatted Discord webhook embed No
Auto-detection rules
The webhook type is auto-detected from the URL when not explicitly set:
URL pattern Detected type Contains hooks.slack.com/services/ slackContains hooks.slack.com/triggers/ slack_workflowContains discord.com/api/webhooks/ or discordapp.com/api/webhooks/ discordEverything else standard
You can override auto-detection by setting webhook_type explicitly when creating a schedule.
Discord and Slack Workflow types do not require a webhook_secret. For standard and slack types, a secret is auto-generated if not provided.
Webhook secrets
When a schedule has a webhook_url, Meter auto-generates a secret with a whsec_ prefix. The secret is sent in the X-Webhook-Secret header on every webhook delivery. Verify this header to ensure requests are from Meter.
See the Webhooks Guide for verification examples.
Retry behavior
Failed deliveries are retried up to 5 times with exponential backoff: 15 minutes, 30 minutes, 1 hour, 2 hours, 4 hours.
2xx : Success, no retry
4xx : Permanent failure, no retry
5xx / timeout / connection error : Retries with backoff
Error responses
Status Description 400Invalid request (missing webhook_url) 401Invalid or missing API key 422Invalid URL format 500Internal server error 503Service temporarily unavailable
See REST API Errors for detailed error handling.
Next steps
Webhooks Guide Learn how to handle webhook notifications
Schedules Set up scheduled scraping with webhooks