Skip to main content

Overview

Webhooks notify your systems, in near real time, about Dunning business facts: charge paid, agreement accepted, dispute opened, notification delivered. Instead of polling the API from time to time, you register an HTTPS endpoint and receive each event as a JSON POST.

Webhooks

How it works​

  1. A fact happens (e.g. payment identified).
  2. The event is persisted immutably — nothing is fire-and-forget.
  3. For each subscribing endpoint, the system schedules a delivery with an HMAC signature and sends it with automatic retry; each attempt is recorded with the request and response captured.

Registering an endpoint​

On the dashboard's Webhooks screen (or via POST /v1/webhook-endpoints), provide:

  • URL: must be https://. URLs pointing to internal networks are rejected at registration (INVALID_WEBHOOK_URL, anti-SSRF protection).
  • Description (optional): what this endpoint is for.
  • Events: pick from the catalog, grouped by category, with "select all" per group. An empty list subscribes to all events, including ones created in the future (the listing shows an "All events" badge).
  • Authentication (optional): credentials Dunning presents to your endpoint (Basic, Bearer or a custom header), in addition to the HMAC signature that is always included. Details in Security.

At creation, the endpoint's secret (prefix whsec_) is displayed only once. It signs every delivery and can be rotated at any time.

What arrives at your endpoint​

Each delivery is a POST with the payload:

{
"event": "charge.paid",
"timestamp": "2026-07-23T12:00:00.000Z",
"organization_id": "3f8a...",
"workspace_id": "5e8d...",
"data": { "id": "...", "status": "paid", "...": "the serialized resource" }
}

workspace_id is the workspace of the event's resource. A workspace event reaches only the endpoints registered in that workspace; an organization event (workspace_id: null, such as workspace.created) reaches the endpoints of every workspace.

And the headers:

Content-Type: application/json
User-Agent: Kobana-Dunning-Webhooks/1.0
X-Kobana-App: dunning
X-Kobana-Environment: production
X-Kobana-Webhook-Id: 7c1e9d2a-… (UUID do endpoint cadastrado)
X-Kobana-Event: charge.paid
X-Kobana-Event-Id: 3d1f0c9a-… (UUID do evento — o mesmo em todos os retries)
X-Kobana-Delivery-Id: 9b2e4a10-… (UUID da entrega — único por evento × endpoint)
X-Kobana-Timestamp: 1753272000 (unix, segundos — momento da assinatura)
X-Kobana-Signature: v1,<base64 do HMAC-SHA256 de "delivery_id.timestamp.body">
webhook-id / webhook-timestamp / webhook-signature (os mesmos valores, layout Standard Webhooks)

Respond 2xx to acknowledge receipt. Any other response (including redirects, which are not followed) counts as a failure and enters the retry cycle.

Testing the endpoint​

After registering, fire a test event with POST /v1/webhook-endpoints/{id}/test: a webhook.test event travels the real pipeline (queue, signature, capture, retry) all the way to your consumer — without waiting for a business event to happen.

Best practices​

  • Respond fast, process later: queue the payload and return 200 immediately (the delivery timeout is 10 seconds).
  • Treat it as at-least-once: retries can deliver the same event more than once; deduplicate by X-Kobana-Event-Id (stable across attempts).
  • Always verify the signature, including the timestamp tolerance window (how to).
  • Monitor the deliveries screen: failures and exhausted deliveries are visible per endpoint, with manual redelivery.

In this section​

  • Events — the full catalog with a sample payload, resource by resource.
  • Security — HMAC signature, verification and request authentication.
  • Deliveries and retry — capture, backoff, DLQ and manual redelivery.