Webhooks

Receive real-time notifications when invoices, quotes, items, or customers change.

Overview

Webhooks let your services react to changes in Corebill without polling. When a subscribed event fires, Corebill sends an HTTP POST to your endpoint with a JSON payload and a signature header you can verify.

Webhooks fire for changes made through the REST API and through the dashboard UI -- the source is recorded on each delivery so you can distinguish them.

Manage endpoints from Developers > Webhooks in the dashboard.

Available Events

EventWhen it fires
customer.createdA new customer was created
customer.updatedA customer was updated
customer.deletedA customer was deleted (soft delete)
item.createdA catalog item was created
item.updatedA catalog item was updated
item.deletedA catalog item was deleted
quote.createdA quote was created
quote.updatedA quote was updated
quote.deletedA quote was deleted
quote.sentA quote was sent to the customer
quote.approvedA quote was approved
quote.rejectedA quote was rejected
quote.convertedA quote was converted to an invoice
invoice.createdAn invoice was created
invoice.updatedAn invoice was updated
invoice.deletedAn invoice was deleted
invoice.sentAn invoice was sent to the customer
invoice.payment_recordedA partial payment was recorded
invoice.paidThe invoice was fully paid
invoice.cancelledAn invoice was cancelled
invoice.refundedAn invoice was refunded

Payload

jsonJSON
1{
2 "id": "evt_a1b2c3d4e5f6",
3 "event": "invoice.paid",
4 "created_at": "2026-04-15T14:30:00Z",
5 "webhook_id": "wh_xyz",
6 "data": {
7 "id": "inv_abc123",
8 "object": "invoice",
9 "invoice_number": "INV-2026-000001",
10 "status": "paid",
11 "total": 5800,
12 "amount_paid": 5800,
13 "amount_due": 0,
14 "customer_id": "cus_abc123",
15 "..."
16 },
17 "metadata": {}
18}

The data object is the same shape returned by the REST API for that resource.

Headers

HeaderDescription
X-Webhook-SignatureHMAC-SHA256 hex digest of the raw body, signed with your endpoint secret
X-Webhook-EventEvent type (e.g. invoice.paid)
X-Webhook-IdThe webhook endpoint ID
X-Event-IdThe system event ID
X-Webhook-DeliveryThe delivery ID (unique per attempt batch)
X-Webhook-AttemptAttempt number (1, 2, ...)
User-AgentCorebill-Webhooks/1.0

Verifying the Signature

Always verify the signature before trusting a webhook. Use the raw request body (do not parse and re-stringify it).

JavaScript
1import crypto from 'crypto'
2
3function verifyWebhook(rawBody, signature, secret) {
4 const expected = crypto
5 .createHmac('sha256', secret)
6 .update(rawBody)
7 .digest('hex')
8
9 return crypto.timingSafeEqual(
10 Buffer.from(expected),
11 Buffer.from(signature)
12 )
13}
14
15// Express example
16app.post('/webhooks/corebill', express.raw({ type: 'application/json' }), (req, res) => {
17 const signature = req.headers['x-webhook-signature']
18 const valid = verifyWebhook(req.body, signature, process.env.COREBILL_WEBHOOK_SECRET)
19
20 if (!valid) return res.status(401).send('invalid signature')
21
22 const event = JSON.parse(req.body.toString())
23 // handle event.event and event.data
24 res.status(200).send('ok')
25})

Responding

Return a 2xx status code within 10 seconds. Anything else (or a timeout) is treated as a failure and Corebill will retry.

Keep handlers fast: enqueue work to a background job and respond immediately.

Retries

Failed deliveries are retried with exponential backoff:

AttemptDelay
1Immediate
21 minute
35 minutes
425 minutes
52 hours

After 5 failed attempts the delivery is marked failed. You can replay it manually from Developers > Webhooks > Deliveries in the dashboard.

Idempotency

The same event can be delivered more than once (for example after a retry or a manual replay). Use the id field of the event envelope as an idempotency key on your side -- if you've already processed evt_xyz, ignore subsequent deliveries with the same id.

Testing

You can replay any past delivery from the dashboard to debug your handler without waiting for a real event:

  1. Go to Developers > Webhooks > Deliveries
  2. Pick a delivery
  3. Click Replay

The replay produces a fresh X-Webhook-Delivery and a new attempt counter, but the event payload is identical to the original.