//Outbound Webhooks

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 |