Outbound Webhooks
Last updated: 2026-02-16
This document covers enterprise event delivery from Bounded Health to external systems.
1. What this provides
- Employer-scoped webhook subscriptions
- Signed payloads (
HMAC-SHA256) - Queue-backed delivery retries
- Delivery history and failure tracking
- Test-delivery endpoint for go-live validation
2. Subscription management endpoints
All webhook management endpoints require:
- Clerk session auth, or
- API key auth with
webhook:manage
Endpoints:
GET /api/employer/webhooksPOST /api/employer/webhooksGET /api/employer/webhooks/{webhookId}PATCH /api/employer/webhooks/{webhookId}DELETE /api/employer/webhooks/{webhookId}POST /api/employer/webhooks/{webhookId}/test
3. Event catalog
Current event types:
test.pingtapering.proposedtapering.approvedtapering.declinedsimulation.completedcohort.uploadedauthorization.reviewedexport.readyinvoice.paid
4. Payload contract
All webhook payloads follow this shape:
json
{
"id": "uuid",
"event": "cohort.uploaded",
"timestamp": "2026-02-16T13:45:10.000Z",
"apiVersion": "2026-02-01",
"employerId": "emp_...",
"data": {}
}
5. Signature verification
Headers sent by Bounded Health:
x-webhook-signature:sha256=<hex-hmac>x-webhook-idx-webhook-eventx-webhook-versionx-webhook-timestamp
Signing algorithm:
- HMAC SHA-256
- Input: exact raw request body bytes
- Secret: subscription signing secret returned at creation time
Node.js verification example:
ts
import crypto from "crypto";
export function verifySignature(rawBody: string, signatureHeader: string, secret: string): boolean {
const expected = `sha256=${crypto.createHmac("sha256", secret).update(rawBody).digest("hex")}`;
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signatureHeader));
}
6. Delivery and retry behavior
- Webhook jobs are delivered asynchronously from queue workers
- Per-attempt timeout: 10 seconds
- Retry attempts: up to 5 with exponential backoff
- Response body captured (truncated) for diagnostics
- Delivery log written for every attempt
- On repeated final-attempt failures,
failureCountincrements - Subscription auto-disables when
failureCount >= maxFailures
7. Test endpoint behavior
POST /api/employer/webhooks/{webhookId}/test sends a direct test event:
- Returns success/failure status and latency
- Writes a delivery log entry
- Returns:
404if subscription not found400if subscription is inactive200withsuccess: falseif endpoint responds non-2xx
8. Production recommendations
- Use dedicated endpoint URLs per environment
- Enforce idempotency by de-duplicating on webhook
id - Return fast
2xxand process asynchronously in your backend - Monitor:
- delivery success rate
- median and p95 latency
- disablement events due to repeated failure
- Rotate signing secrets on a schedule
9. Go-live validation checklist
- Create subscription with HTTPS URL only
- Store signing secret in your secret manager
- Run
/testendpoint and validate signature verification - Trigger one real domain event and verify payload mapping
- Confirm your retry and dead-letter handling is active