Webhooks and events
A webhook is Kontier calling your system when something happens, so you do not have to poll for it. You register an endpoint, choose the events you care about, and verify the signature on every delivery.
Verify the signature
Every delivery is signed with a secret you hold. Check it before you trust the body: an unverified endpoint is a URL anyone who learns it can post to.
Verify the X-Webhook-Signature-V1 header together with X-Webhook-Timestamp.
Verifying the signature has the exact
construction.
Retries mean be idempotent
A delivery that does not get a 2xx is retried. That means your handler will sometimes see the same event twice, and it must reach the same result the second time.
Deduplicate on the envelope's idempotency_key. It stays the same across retries
and across endpoints, while id is new for every delivery. Return 2xx as soon as
you have safely recorded the event, and do the slow work afterwards, because a
handler that takes too long is a handler that gets retried.
Wrong types are refused
You cannot subscribe to an event that does not exist. Registration validates
every value in event_types against the catalog below and rejects anything
outside it with a 400.
This matters more than it sounds. Delivery matches event types exactly, so an accepted typo would register cleanly and then deliver nothing, forever, with no feedback. Registration is the last point at which anyone can tell you.
Listed means emitted
An event appears below only if it is actually emitted. Constants that exist in the code but are never constructed are deliberately excluded, because subscribing to one would silently deliver nothing.
Every event type carries its own payload shape revision, delivered as the envelope's payload_version and currently 1 for all of them. Versions advance per event, so one event's payload can change without touching any other's. The live number for each type is in the OpenAPI webhooks section and in GET /v1/webhook-endpoints/event-catalog; see Payload versions for how to handle a bump.
Every event
143 events across 30 families. The list is generated from the
webhooks section of the OpenAPI document, so it is the complete set rather than
a selection; each event's full description and payload schema is there too.
GET /v1/webhook-endpoints/event-catalog returns the same list at runtime.
allowance
Included allowances (2 events).
| Event | Fires when |
|---|---|
allowance.given_back | A correcting document (a void, a reversal, a refund, a credit note or a corrective) took back part or all of an issued invoice, and the allowance units that invoice drew came back to the allowance lots they were drawn from - in the same share as the quantity taken back. |
allowance.rolled_over | Unused allowance carries into the next period. |
approval
Approval requests on parked operations (10 events).
| Event | Fires when |
|---|---|
approval.applied | The operation an approved request released has run. |
approval.apply_failed | The operation an approved request released failed to run. |
approval.request_approved | An approval request is approved by a person. |
approval.request_cancelled | An approval request is withdrawn by its requester, or retired because its subject was voided, ended or changed under the approver. |
approval.request_created | An operator action is parked and needs a human decision. |
approval.request_expired | An approval request is not decided before its deadline and is withdrawn. |
approval.request_rejected | An approval request is rejected by a person, with their reason. |
approval.request_retried | An operator re-armed a request's failed run: the approved operation, or the release of what it parked. |
approval.withdraw_failed | Releasing what a closed request had parked failed. |
approval.withdrawn | What a rejected, cancelled or expired request had parked was released. |
catalog
Catalog versions going live (1 event).
| Event | Fires when |
|---|---|
catalog.version_published | A version of a plan, product, rate table, price formula or tax rule goes live: by an operator's publish, a scheduled release, or a cascade from something it follows. |
connection
Connections to payment gateways, sending accounts and integrations (1 event).
| Event | Fires when |
|---|---|
connection.health_changed | A payment gateway, sending account or integration starts or stops working. |
customer
Customer records (4 events).
| Event | Fires when |
|---|---|
customer.created | A customer is created (with their default wallet). |
customer.currency_changed | A customer's default billing currency changes. |
customer.mode_changed | A customer's wallet mode (prepaid/postpaid) changes. |
customer.type_changed | A customer's type (business/consumer) changes. |
dispute
Chargebacks and disputes (1 event).
| Event | Fires when |
|---|---|
dispute.changed | A payment provider reports a dispute (a chargeback) on a charge, or moves one's status or outcome. |
document
Generated documents (2 events).
| Event | Fires when |
|---|---|
document.generated | A document artifact is written to archival storage. |
document.requested | A document render is requested (invoice, credit note or dunning letter). |
dunning
Dunning cases and steps (7 events).
| Event | Fires when |
|---|---|
dunning.case.closed | A dunning case closes: paid (the charge to another payment method of the customer, or their top-ups, paid it) or reversed (the provider reported the dispute won after it was lost). |
dunning.case.opened | A dunning case opens: a lost chargeback could not take back, from the customer's wallet, money a reversal or a refund had returned there, because the wallet had spent it. |
dunning.case.reopened | A paid dunning case is owed again: the customer charged back the charge to another of their payment methods that had paid it. |
dunning.step.cancel | A dunning cancel step fires. |
dunning.step.email | A dunning email step fires. |
dunning.step.grace | A dunning grace step fires. |
dunning.step.suspend | A dunning suspend step fires. |
e_invoicing
Structured e-invoices (2 events).
| Event | Fires when |
|---|---|
e_invoicing.document.generated | An e-invoice document is generated. |
e_invoicing.document.quarantined | An e-invoice document fails validation and is quarantined. |
firing
The promotion ledger (1 event).
| Event | Fires when |
|---|---|
firing.recorded | One row of the promotion ledger: what a promotion did to money, on which line, invoice or hold. |
integration
Integrations (1 event).
| Event | Fires when |
|---|---|
integration.run_failed | An integration's sync, delivery, action or callback fails: an invoice did not reach the books, a message was not posted, a file was not produced. |
invoice
The invoice and payment lifecycle (8 events).
| Event | Fires when |
|---|---|
invoice.corrected | A document is corrected. |
invoice.drafted | A document exists in draft — from the subscription pipeline, an operator, an accepted quote or a fired milestone. |
invoice.finalized | A document is issued: its lines become the legal text, its stamps go on and its number is minted. |
invoice.payment_attempt_failed | A single gateway payment attempt fails (retryable). |
invoice.payment_failed_terminal | Payment retries are exhausted. |
invoice.payment_recorded | Money or credit settled against a document. |
invoice.reservation_released | A draft sat unfinished past the organization's draft-reservation window and the promotion budget it was holding went back to the promotion's ceiling. |
invoice.written_off | A document is declared uncollectible. |
jobs
Background jobs (1 event).
| Event | Fires when |
|---|---|
jobs.dead_lettered | A background job stops retrying and will not run again without intervention. |
marketplace
Marketplace sellers, sales, payouts and statements (13 events).
| Event | Fires when |
|---|---|
marketplace.payout.paid | A payout is marked transferred and the seller's payable falls by the net. |
marketplace.sale.agreed | A sale is struck: the supply model and the commission are frozen and it waits for the buyer's charge. |
marketplace.sale.cancelled | A sale is unwound before completion and the buyer is being refunded. |
marketplace.sale.chargeback_reassigned | An operator moves a lost chargeback between the seller and the platform, changing whose money bears it. |
marketplace.sale.completed | A sale completes: the seller's payable is released, the documents are issued and the commission is invoiced. |
marketplace.sale.funded | The buyer's gross is in custody and the completion deadline is set. |
marketplace.sale.refunded | A refund reaches the whole gross and the sale is terminal. |
marketplace.seller.closed | A seller is closed for good, with no open sale and nothing left owed to it. |
marketplace.seller.created | A customer takes on a seller role. |
marketplace.seller.reinstated | A seller's suspension is lifted and it may sell again. |
marketplace.seller.suspended | New sales are refused from this seller. |
marketplace.seller.verified | A seller passes the organisation's verification check and may now be offered a listing. |
marketplace.statement.finalized | A seller's period is closed, numbered and frozen, and the statement is on its way. |
meter
Usage metering (1 event).
| Event | Fires when |
|---|---|
meter.threshold_breached | A meter evaluation crosses a configured threshold. |
organization
Organizations, delegations and holds (5 events).
| Event | Fires when |
|---|---|
organization.closed | An organization is terminal: every effect applies and its API keys and outgoing delegations are revoked. |
organization.delegation_granted | Members of an organization holding a named role may now act inside another one below it, until the expiry if there is one. |
organization.delegation_revoked | A delegation between two organizations ended: withdrawn by either end, or because the grantor was closed. |
organization.hold_placed | A windowed restriction now applies to this organization. |
organization.hold_released | A restriction stopped applying. |
payment
Payments (1 event).
| Event | Fires when |
|---|---|
payment.changed | A payment is created or its state changes. |
payment_method
Payments (4 events).
| Event | Fires when |
|---|---|
payment_method.attached | A payment method is saved for a customer: through the customer portal, on a quote, at checkout, at the provider, or by an operator. From then on the customer can be charged off-session. A method the provider reports again is not sent twice. |
payment_method.default_set | A payment method becomes the customer's default for automatic payments or for top-ups; default_for says which. |
payment_method.removed | A saved payment method is removed (by an operator, by the customer in the portal, or detached at the provider) and can no longer be charged. |
payment_method.updated | An operator changes a saved payment method; changes says what moved, each before and after. |
plan
Plans (5 events).
| Event | Fires when |
|---|---|
plan.cloned | A plan is copied into a new draft plan. |
plan.created | A plan is created (as a draft). |
plan.deleted | A plan is deleted. |
plan.subscribers_migrated | Subscribers are migrated to a new plan version. |
plan.updated | A plan's live fields change (name, descriptions, external id, metadata, price cadence). |
product
Products (7 events).
| Event | Fires when |
|---|---|
product.activated | A product is activated. |
product.archived | A product is archived. |
product.copied | A product is copied. |
product.created | A product is created. |
product.deleted | A product is deleted. |
product.updated | A product's auditable fields change. |
product.version_rebased | A pending product version is rebased onto a new head. |
promotion
Promotions (5 events).
| Event | Fires when |
|---|---|
promotion.created | A promotion is drafted. |
promotion.ended | A promotion ends, by its window, by reaching a ceiling, or by an operator. |
promotion.narrowed | A live promotion's window, ceilings or audience move inward. |
promotion.published | A promotion goes live and its rule is frozen. |
promotion.terms_changed | A live promotion is edited in a way that is not only a narrowing: a ceiling lifted or raised, a customer named in, an audience removed or swapped, its words or its narrowing policy. |
quote
Quotes (11 events).
| Event | Fires when |
|---|---|
quote.approved | A quote's pending approval is granted. |
quote.created | A quote is created (DRAFT). |
quote.declined | A buyer declines a quote. |
quote.expired | A sent/viewed quote passes its expiry date. |
quote.orchestrated | A signed quote is orchestrated into a subscription. |
quote.orchestration_requested | An operator re-arms a signed quote whose orchestration failed, asking for another attempt. |
quote.rejected | A quote's pending approval is rejected. |
quote.reminded | An operator sends the buyer a reminder about a live quote. |
quote.sent | A quote is released to the buyer. |
quote.signed | A buyer signs a quote. |
quote.viewed | A buyer opens a sent quote for the first time since it was sent or amended. |
redemption
Customers holding a promotion (3 events).
| Event | Fires when |
|---|---|
redemption.created | A customer comes to hold a promotion, through a coupon, an enrolment or an automatic match. |
redemption.ended | A customer's hold on a promotion ends: they left, it was revoked, the window closed, a ceiling was reached, or a pending bundle expired. |
redemption.status_changed | A hold moves between active and dormant as the customer's eligibility changes. |
reserve_outcome
Wallet reservations (3 events).
| Event | Fires when |
|---|---|
reserve_outcome.captured | A reservation is captured by the usage event that named its hold: the wallet is debited and a paid invoice is issued for the capture. |
reserve_outcome.failed | A reservation outcome fails. |
reserve_outcome.queued | A metered reservation outcome is queued (pending). |
sepa_mandate
SEPA Direct Debit mandates (4 events). The payload is the mandate as GET /v1/sepa-mandates/{mandate_id} returns it, IBAN masked; see SEPA mandates.
| Event | Fires when |
|---|---|
sepa_mandate.created | A mandate is recorded for a customer, through any channel. On your own SEPA rail sepa_mandate.activated follows in the same transaction; on a payment provider's rail it starts pending. |
sepa_mandate.activated | A mandate can be collected on: at once on your own rail, or once the payment provider confirmed it. |
sepa_mandate.revoked | A mandate ends: revoked by the customer, an operator, the provider or the bank, replaced by a newer one, ended with its payment method, or by the customer's erasure. |
sepa_mandate.failed | The payment provider refused to set up a pending mandate; sync_error says why. |
signing
Electronic signatures (9 events).
| Event | Fires when |
|---|---|
signing.countersign_requested | Every party has signed and the organisation's own signature is outstanding. |
signing.envelope_cancelled | A signature request is withdrawn, or superseded by a newer one (reason SUPERSEDED). |
signing.envelope_completed | Every required signer has signed. |
signing.envelope_expired | A live signature request passes its expiry date. |
signing.envelope_sent | A signature request is released: the document is frozen and the first signer is notified. |
signing.reminder_sent | A signer is reminded about an outstanding signature request. |
signing.signer_declined | A signer refuses, with their reason. |
signing.signer_signed | One signer signs. |
signing.signer_viewed | A signer opens the document for the first time. |
subscription
The subscription lifecycle (17 events).
| Event | Fires when |
|---|---|
subscription.activated | A subscription transitions to ACTIVE. |
subscription.billing_blocked | The invoice pipeline REFUSED to price an elapsed billing window, so the period was not billed and did not advance. |
subscription.billing_unblocked | A blocked billing window cleared: a later attempt priced it and the block was removed. |
subscription.cancelled | A subscription is cancelled: emitted by its stop, with the cause — USER_REQUEST, DUNNING_TERMINAL or AGREEMENT_TERM_ENDED. |
subscription.created | A subscription is created. |
subscription.dunning_entered | A subscription enters dunning (stage WARNED). |
subscription.dunning_stage_changed | Dunning escalates (WARNED, GRACED, SUSPENDED). |
subscription.event_fired | A phase that ends on a metric crossed its threshold. |
subscription.paused | A subscription is paused. |
subscription.payment_failed | A subscription invoice payment fails. |
subscription.phase_entered | A phase's window opened and billing started reading it. |
subscription.recovered | A dunning subscription recovers after payment clears. |
subscription.renewal_upcoming | A committed subscription term is approaching its renewal date (pre-renewal notice). |
subscription.resumed | A paused subscription resumes. |
subscription.revision_published | A draft revision of the deal went live and the previous one was superseded. |
subscription.status_changed | The subscription moved between active, paused and cancelled. |
subscription.stopped | A subscription ended. |
tag
Tags (4 events).
| Event | Fires when |
|---|---|
tag.applied | A tag is applied to an entity. |
tag.deleted | A tag is deleted. |
tag.removed | A tag is removed from an entity. |
tag.renamed | A tag is renamed. |
tax
Tax thresholds (2 events).
| Event | Fires when |
|---|---|
tax.oss_threshold_approaching | EU OSS revenue nears the 10k EUR threshold. |
tax.oss_threshold_exceeded | EU OSS revenue crosses the 10k EUR threshold. |
wallet
Prepaid wallets (8 events).
| Event | Fires when |
|---|---|
wallet.apply_to_invoice | An invoice finalize requests wallet settlement. |
wallet.auto_topup_triggered | A wallet balance trips its auto-topup threshold. |
wallet.hold_expired | A wallet hold expires and releases its funds. |
wallet.low_balance | A debit takes a wallet's balance across its low-balance threshold (once per crossing). |
wallet.payment_skipped | Wallet settlement is skipped (no wallet, insufficient funds, currency mismatch, ...). |
wallet.promotional_balance_expired | A wallet's promotional balance passes its expiry date and is forfeited. |
wallet.topped_up | Money is credited to a wallet's cash balance, whatever its source: a top-up paid at the payment provider (hosted checkout or a saved card), the automatic top-up, money the customer paid in that an operator records, a refund to the balance (naming its credit note), or an operator's credit under another source. |
wallet.transferred | Funds move between two wallets. |
There is no invoice.paid and no payment.failed
An invoice being paid arrives as invoice.payment_recorded. A failed payment
arrives as invoice.payment_attempt_failed for each failed attempt,
invoice.payment_failed_terminal when retries are exhausted, and
subscription.payment_failed for a subscription invoice. Neither
invoice.paid nor payment.failed is a webhook event, and registering either is
refused.
Reference
| Topic | When you need it |
|---|---|
| Webhooks | Registering an endpoint, signatures, retries and replay |
| Payment gateways | Callbacks inbound to Kontier, the opposite direction |
| Invoices | What the invoice family describes |
| Subscriptions | The largest event family |
| Webhooks API | Registering an endpoint and rotating a secret |