Skip to content

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.

Everything the portal’s webhook page can do, headless (webhooks:manage):

MethodPathNotes
GET/v1/webhook-endpointsAll endpoints (max 10 per organisation) — never includes secrets
POST/v1/webhook-endpointsRegister. 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-secretNew 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}/testQueue a Ping with no real data — proves your endpoint and signature verification. 202

If your endpoint has been down, you never depend on support to get your data back:

MethodPathScopeNotes
GET/v1/eventsevents:readPull 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}/replaywebhooks:manageBody { "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.