Outbound Webhooks
ButtrBase sends signed webhook events to your endpoints when platform events occur.
Registration
POST /api/webhooks
Registers a webhook endpoint.Input: ~~~json { "org_uuid": "org-uuid-12345", "url": "https://myapp.com/webhooks", "events": ["user.created", "subscription.activated"], "secret": "my-webhook-secret" } ~~~
Payload Signature
Each webhook payload is signed using HMAC-SHA256 with your webhook secret:
~~~
X-ButtrBase-Signature: sha256=
Verify the signature in your handler:
~~~js const expectedSig = crypto .createHmac('sha256', webhookSecret) .update(rawBody) .digest('hex');
if (signature !== sha256=${expectedSig}) {
return res.status(401).send('Invalid signature');
}
~~~
Retry Policy
Failed deliveries are retried up to 5 times with exponential backoff (1s, 2s, 4s, 8s, 16s).
Event Catalog
| Event | Trigger |
|-------|---------|
| user.created | New user registered |
| user.deleted | User deleted |
| subscription.activated | Subscription became active |
| subscription.cancelled | Subscription cancelled |
| payment.succeeded | Payment processed |
| payment.failed | Payment failed |
Error Reference
| Status | Code | Meaning |
|--------|------|---------|
| 400 | validation_error | Request body failed validation |
| 401 | unauthorized | Missing or invalid Authorization header |
| 403 | forbidden | Insufficient permissions |
| 404 | not_found | Resource does not exist |
| 409 | conflict | Resource already exists or constraint violated |
| 422 | unprocessable | Semantic validation failure |
| 429 | rate_limited | Request rate exceeded |
| 500 | internal_error | Unexpected server error |