Skip to main content

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.
POST /api/webhooks/test

Request body

{
  "webhook_url": "https://your-app.com/webhooks/meter"
}
FieldTypeRequiredDescription
webhook_urlstringYesThe webhook URL to test

Response

{
  "success": true,
  "status_code": 200,
  "message": "Webhook delivered successfully"
}
FieldTypeDescription
successbooleanWhether the webhook was delivered successfully (2xx response)
status_codeintegerHTTP status code returned by your endpoint (0 if request failed)
messagestringHuman-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"
  }'

Webhook payload formats

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"}
}
FieldTypeDescription
job_idUUIDID of the scrape job
schedule_idUUIDID of the schedule that triggered the job
statusstringAlways completed for success webhooks
urlstringThe URL that was scraped
resultsarrayExtracted data from the page
item_countintegerNumber of items extracted
has_changesbooleanWhether content changed since last run
content_hashstringHash of the extracted content
completed_atdatetimeWhen the job completed
metadataobjectCustom 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"}
}
FieldTypeDescription
job_idUUIDID of the scrape job
schedule_idUUIDID of the schedule that triggered the job
statusstringAlways failed for failure webhooks
urlstringThe URL that failed to scrape
errorstringError message describing what went wrong
completed_atdatetimeWhen the job failed
metadataobjectCustom 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:
TypeDescriptionSecret required
standardFull JSON payload (default)Yes (auto-generated)
slackFormatted Slack incoming webhook messageYes (auto-generated)
slack_workflowSlack Workflow Builder trigger payloadNo
discordFormatted Discord webhook embedNo

Auto-detection rules

The webhook type is auto-detected from the URL when not explicitly set:
URL patternDetected type
Contains hooks.slack.com/services/slack
Contains hooks.slack.com/triggers/slack_workflow
Contains discord.com/api/webhooks/ or discordapp.com/api/webhooks/discord
Everything elsestandard
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

StatusDescription
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