Webhooks
A webhook tells your system that something happened in Kontier: an invoice was finalised, a payment failed, a subscription was cancelled. You register a URL, choose which events you care about, and Kontier posts to it.
Use them instead of polling. An invoice becomes overdue at a moment you cannot predict, and asking every minute is both slower and more expensive than being told.
Registering an endpoint
url and event_types are required. Nothing else is.
Code
Subscribe to what you will act on, not everything. GET /v1/webhook-endpoints/event-catalog lists every subscribable type; there are
115 of them.
At least once
This is the design fact everything else follows from.
A delivery that fails is retried. A delivery that succeeds but whose response Kontier never sees is also retried, because from the sender's side those two look identical. Your endpoint will therefore receive the same event twice occasionally, and it must not double-act.
Make handlers idempotent: key on the event's ID, record what you have
processed, and make a repeat a no-op. This is the same reasoning as the required
idempotency_key on usage ingest, from the other direction.
Return 2xx fast, then work
Kontier treats a slow response as a failure and retries. Acknowledge with a 2xx immediately, queue the work, and process it outside the request. An endpoint that does its work inline is an endpoint that gets duplicate deliveries under load.
Verifying the signature
Every delivery is signed. Your endpoint is public, so anyone can post to it; the signature is what distinguishes Kontier from anyone else.
Verify it on every request, before doing anything with the body. Secrets are
managed separately at /v1/webhook-secrets and can be rotated without
downtime: POST /v1/webhook-secrets/{id}/rotate lets you accept both the old and
new secret while you deploy.
When something goes wrong
| Endpoint | What it gives you |
|---|---|
GET /webhook-endpoints/{id}/deliveries | Every attempt, with status and response |
POST .../deliveries/{delivery_id}/replay | Requeue one delivery by hand |
Replay is the tool for the case where your endpoint was down for an hour, or a bug meant you dropped events you should have kept. It re-sends the original payload rather than a fresh one, so late processing still sees what happened at the time.
Dashboard and API names
| In the dashboard | In the API |
|---|---|
| Organization → Integrations → Webhooks | /v1/webhook-endpoints |
| Events | event_types[] |
| Deliveries | GET /webhook-endpoints/{id}/deliveries |
| Replay | POST .../deliveries/{id}/replay |
| Signing secret | /v1/webhook-secrets, rotatable |
Where webhooks go next
- React to failures.
payment.failedis the event most worth wiring first; it is what tells you dunning has started. - Keep your own copy. Persist the events you care about rather than relying on the delivery log for history.
- Check the catalog before subscribing. Event names are specific, and guessing one silently subscribes you to nothing.
Reference
| Topic | When you need it |
|---|---|
| Dunning | What the payment-failure events mean |
| Invoices | The lifecycle behind the invoice events |
| Webhooks API | Endpoints, secrets, deliveries and replay |