Home  ›  Developers  ›  Webhooks

Webhooks catalog

Push-style integration is the right pattern. Subscribe once, receive every state change forever. 32 event types at launch covering invoicing, payments, payroll, and tax. HMAC-SHA256 signatures. Exponential-backoff retries. 30-day replay window.

Contents

  1. Why webhooks (not polling)
  2. Event payload shape
  3. Signature verification
  4. Retry policy
  5. Replay & manual redelivery
  6. Managing webhook endpoints
  7. Event catalog — 32 events
  8. Security best practices

1. Why webhooks (not polling)

Polling the API to check for state changes is wasteful: 99% of requests return "no change," and the 1% that matter arrive minutes late. Webhooks invert the model — HIBR pushes events to your endpoint within 5 seconds of the underlying state change.

For UAE-specific workflows, webhooks matter especially for:

2. Event payload shape

Every webhook delivery is an HTTPS POST with a stable JSON payload structure:

# Standard event envelope
POST https://your-endpoint.com/hibr-webhook HTTP/1.1
Content-Type: application/json
Hibr-Event: invoice.paid
Hibr-Event-Id: evt_01HFQB...
Hibr-Signature: t=1729000080,v1=5257a86...
Hibr-Webhook-Endpoint: wh_01HFQA...

{
  "id": "evt_01HFQB...",
  "object": "event",
  "type": "invoice.paid",
  "created": "2026-10-15T09:32:14Z",
  "api_version": "2026-10-01",
  "livemode": true,
  "data": {
    "object": {
      / Full invoice resource at the moment of the event
      "id": "inv_01HFQB...",
      "object": "invoice",
      "status": "paid",
      ...
    },
    "previous_attributes": {
      / Only changed fields, for diff calculation
      "status": "open"
    }
  }
}

Key fields:

HIBR expects your endpoint to respond with HTTP 2xx within 10 seconds. Slower than 10 seconds counts as a failed delivery and triggers retry. Anything other than 2xx counts as a failed delivery.

3. Signature verification

Every webhook is signed with HMAC-SHA256 using a secret shared at subscription time. Verify the signature before processing the payload — otherwise an attacker who knows your endpoint URL could send forged events.

Signature header format

Hibr-Signature: t=1729000080,v1=5257a86a9eb1d77a4d3c7e2f9b8a6c5e4d3b2a1f0e9d8c7b6a5f4e3d2c1b0a9f8

Verification procedure

  1. Extract t and v1 from the Hibr-Signature header.
  2. Verify timestamp tolerance — reject if t is more than 5 minutes old (replay protection).
  3. Recompute the expected signature: HMAC-SHA256(secret, "{t}.{raw_request_body}").
  4. Constant-time compare against v1. Reject if mismatch.
# Node.js example
const crypto = require('crypto');

function verifyWebhook(rawBody, signature, secret) {
  const parts = Object.fromEntries(signature.split(',').map(p => p.split('=')));
  const t = parts.t, v1 = parts.v1;

  / Replay protection — 5-minute window
  if (Math.abs(Date.now()/1000 - parseInt(t)) > 300) return false;

  const expected = crypto
    .createHmac('sha256', secret)
    .update(`${t}.${rawBody}`)
    .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(v1)
  );
}
Use the raw request body for signature verification. Many web frameworks (Express, Django, Laravel) parse JSON before your handler sees it. Re-serializing the parsed object produces different bytes than the original. Use middleware that preserves the raw body, or compute the signature on the original byte stream before parsing.

4. Retry policy

If your endpoint fails to respond with 2xx within 10 seconds, HIBR retries with exponential backoff. Up to 8 attempts spanning 72 hours.

Attempt 1
Immediate
Attempt 2
After 30 s
Attempt 3
After 5 min
Attempt 4
After 30 min
Attempt 5
After 2 hours
Attempt 6
After 6 hours
Attempt 7
After 24 hours
Attempt 8
After 48 hours

After attempt 8, the event is marked permanently failed. Permanent failures are retrievable via the replay endpoint (§5) for 30 days.

Endpoints that fail 100 consecutive deliveries are automatically disabled, with an email notification to the developer contact. Re-enable from the dashboard.

5. Replay & manual redelivery

Every event delivered (or attempted) is retrievable for 30 days. Useful for:

GET /v1/eventsList events (filterable by type, created.gte, delivery_status)
GET /v1/events/{event_id}Retrieve a single event with full payload
POST /v1/events/{event_id}/redeliverTrigger immediate redelivery to all subscribed endpoints
POST /v1/events/{event_id}/redeliver?endpoint=wh_xxxRedeliver to a specific endpoint

6. Managing webhook endpoints

Webhook endpoints are first-class resources. Manage them via API or in the dashboard.

POST /v1/webhook-endpointsCreate an endpoint
GET /v1/webhook-endpointsList endpoints
GET /v1/webhook-endpoints/{id}Retrieve one
PATCH /v1/webhook-endpoints/{id}Update (URL, event subscriptions, enabled state)
DELETE /v1/webhook-endpoints/{id}Delete
POST /v1/webhook-endpoints/{id}/rotate-secretRotate the signing secret without changing the URL

Endpoint object

{
  "id": "wh_01HFQA...",
  "object": "webhook_endpoint",
  "url": "https://your-server.com/hibr",
  "description": "Production payment processor",
  "enabled_events": ["invoice.paid", "payment.succeeded"],
  "status": "enabled",
  "created": "2026-10-15T09:32:14Z",
  "secret": "whsec_..." / only on creation + rotate
}

7. Event catalog

32 event types at launch, grouped by resource. Subscribe to specific events or use wildcards (e.g., invoice.*).

Invoices

invoice.createdNew invoice created (draft state)
invoice.updatedInvoice modified before posting
invoice.postedInvoice posted to the ledger (immutable from here)
invoice.sentInvoice emailed to the customer
invoice.viewedCustomer opened the invoice PDF via portal link
invoice.paidInvoice fully paid
invoice.overdueInvoice past due date
invoice.voidedInvoice voided (with reversing entries posted)

Bills & expenses

bill.createdNew bill (purchase invoice) recorded
bill.approvedBill passes approval workflow
bill.paidBill marked paid
credit_note.createdCredit note issued (sales or purchase)

Payments

payment.succeededPayment received and matched to invoice(s)
payment.failedPayment attempt failed (Stripe, gateway, bank refusal)
payment.refundedFull or partial refund processed
bank_feed.transaction.createdNew transaction received from bank feed
bank_feed.reconciliation.matchedBank transaction matched to an invoice or bill

Tax

vat_return.draft.readyVAT 201 draft generated, ready for review
vat_return.submittedVAT 201 submitted to FTA
vat_return.acceptedFTA accepted the submission
vat_return.rejectedFTA rejected — includes error reason from FTA
ct_return.draft.readyCT-201 draft generated
ct_return.submittedCT-201 submitted to FTA
e_invoice.sentPINT-AE e-invoice delivered via PEPPOL
e_invoice.acknowledgedRecipient's accounting system acknowledged receipt
e_invoice.failedDelivery failed — includes failure reason

Payroll

payroll_run.createdNew payroll cycle initiated
payroll_run.approvedPayroll approved + ready for WPS
wps_file.generatedSIF file generated
wps_file.submittedSIF submitted to WPS agent bank
wps_file.acceptedBank confirmed processing
wps_file.rejectedBank rejected the file — includes row-level errors
employee.offboardedEmployee terminated, gratuity calculation triggered

8. Security best practices

About event ordering: HIBR makes a best effort to deliver events in chronological order of the underlying state change, but does not guarantee strict ordering. If event A precedes event B in time, A may arrive at your endpoint after B in unusual circumstances (retry windows, endpoint slowness). Your handler should be tolerant — use the created timestamp on the event payload for ordering logic, not arrival time.

Want to test webhooks pre-launch?

Sandbox at sandbox-api.hibr.ai opens in August 2026. You'll be able to create webhook endpoints, generate test events, and verify your signature-verification logic before production launch.

Reserve founder slot →