Webhooks API
Subscribe to events in your metering pipeline.
Event types
| Event type | Description |
|---|---|
usage_spike | Unusual usage increase detected for a customer |
quota_threshold | Customer approaching or exceeding a quota limit |
billing_period_end | A billing period has ended for a customer |
export_ready | A requested usage export is ready for download |
List webhooks
GET/v1/webhooks
json
[
{
"id": "01HQXYZ...",
"url": "https://your-app.com/webhooks",
"events": ["usage_spike", "quota_threshold"],
"active": true,
"created_at": "2024-01-15T10:00:00Z"
}
]Create a webhook
POST/v1/webhooks
| Field | Type | Required | Description |
|---|---|---|---|
url | string | Yes | The URL to deliver webhook events to |
events | string[] | Yes | Array of event types to subscribe to: "usage_spike", "quota_threshold", "billing_period_end", "export_ready" |
json
{
"url": "https://your-app.com/webhooks",
"events": ["usage_spike", "quota_threshold"]
}A secret is auto-generated and returned. Use it to verify webhook signatures.
Update a webhook
PATCH/v1/webhooks/:id
json
{ "url": "https://new-url.com/webhooks", "active": false }Delete a webhook
DELETE/v1/webhooks/:id
Webhook payload
Deliveries are sent as POST requests with a JSON body:
json
{
"event_type": "quota_threshold",
"tenant_id": "01HQXYZ...",
"timestamp": "2024-01-15T10:30:00Z",
"data": {
"meter_id": "01HQABC...",
"customer_id": "01HQDEF...",
"current_usage": 10500.0,
"limit": 10000.0
}
}Deduplication
Meterd deduplicates webhook deliveries using a composite key of meter_id:customer_id:percent_tier (where percent tier is bucketed in 10% increments). You won't receive repeated quota_threshold notifications at 81%, 82%, 83% — you get one when the customer crosses the 80% tier.
Signature verification
Each delivery includes an X-Meterd-Signature header. Verify it by computing HMAC-SHA256 over the raw request body using your webhook secret.
Verify signature
python
import hmac, hashlib
def verify(payload_bytes, signature, secret):
expected = hmac.new(secret.encode(), payload_bytes, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, signature)Retry policy
Failed deliveries (non-2xx responses) are retried with exponential backoff up to 3 times. Delivery status is tracked and visible in the dashboard.