Webhooks
Outbound webhooks (signed, with retry/backoff and secret rotation) notify you of case and invoice events so you don’t have to poll. Configuration lives under Admin → Webhooks; the signing contract follows Standard Webhooks.
Invoice event types: invoice.issued, invoice.sent, invoice.paid, invoice.overdue,
invoice.credited, invoice.collections, payment.received. The envelope carries an
invoice: { "id": "…", "sekvensnummer": n } block — sort by it per invoice; gaps are
legal, duplicates never are (webhook-id is your dedup key). Payloads carry amounts,
dates, ids and your own externalReference — never personal data.
Customer events: customer.past_due, customer.settled (see Gating services on unpaid
balances), with a customer: { "id", "sekvensnummer" } block.
Subscription events, with a subscription: { "id", "sekvensnummer" } block:
subscription.created / updated / paused / resumed / cancelled / ended,
subscription.invoiced (a period was billed — payload carries the invoiceId),
subscription.payment_succeeded / payment_failed (the stored-card charge — the event
the service-gating pattern rests on: on payment_failed the invoice simply continues in
the reminder flow, and customer.past_due follows if it stays unpaid), and
subscription.payment_method.attached / detached / expiring.
Webhooks can be lost or arrive out of order: treat them as a signal to fetch, and use
GET /v1/invoices/{id} as the truth.
Managing endpoints via API
Section titled “Managing endpoints via API”Everything the portal’s webhook page can do, headless (webhooks:manage):
| Method | Path | Notes |
|---|---|---|
| GET | /v1/webhook-endpoints | All endpoints (max 10 per organisation) — never includes secrets |
| POST | /v1/webhook-endpoints | Register. Response carries secret (whsec_…) exactly once — store it; lost = rotate. HTTPS only, no credentials in the URL, private/internal hosts rejected |
| GET | /v1/webhook-endpoints/{id} | |
| PATCH | /v1/webhook-endpoints/{id} | Partial: eventTypes, active, description. The URL cannot be changed — register a new endpoint instead |
| DELETE | /v1/webhook-endpoints/{id} | Final; queued deliveries disappear with it |
| POST | /v1/webhook-endpoints/{id}/rotate-secret | New secret; the old one keeps signing for 24 h (two signatures in the header) so in-flight deliveries survive the switch |
| POST | /v1/webhook-endpoints/{id}/test | Queue a Ping with no real data — proves your endpoint and signature verification. 202 |
Catch-up and replay
Section titled “Catch-up and replay”If your endpoint has been down, you never depend on support to get your data back:
| Method | Path | Scope | Notes |
|---|---|---|---|
| GET | /v1/events | events:read | Pull feed over the same event log webhooks deliver from. ?since= (ISO-8601), ?type=, cursor-paginated, ascending (oldest first). Each item has exactly the webhook delivery shape — reuse your webhook handler |
| POST | /v1/webhook-endpoints/{id}/replay | webhooks:manage | Body { "since": "…" } (at most 90 days back). Re-queues failed/given-up deliveries and enqueues events that never got queued (endpoint created later, our downtime). Delivered events are never re-sent. Response: { requeued, enqueued, possiblyMore } (cap 10,000 per call — call again if possiblyMore) |
The feed is the truth-side companion to webhooks: webhooks push the signal, GET /v1/events?since= closes any gap.