LedgerBee Developer
  • Getting started
  • Conventions
  • Products
  • API Reference
Subscriptions
Products & Pricing
Billing documents
WebhooksMCP (AI agents)
Customer Portal
Products

Webhooks

Register HTTPS endpoints to receive signed event notifications. Manage endpoints under Marketplace → Webhooks in the LedgerBee app, or via the API — the Webhook Endpoints tag in the API Reference (create, list, update, delete, roll-secret, and a test delivery; scopes webhook-endpoints-read / webhook-endpoints-write).

Endpoint URLs must be public HTTPS — plain http and private/loopback hosts are rejected at creation. Creating an endpoint returns a signing secret of the form whsec_…, shown once; store it to verify every delivery.

Delivery envelope

Every delivery POSTs a JSON envelope — and the whole envelope is what gets signed:

Code
{ "id": "…", // the delivery id — same value as the webhook-id header "type": "subscription.started", "timestamp": "2026-06-01T12:00:00.000Z", "data": { … } // topic-specific payload }

Signing — Standard Webhooks

Every delivery is signed following the Standard Webhooks specification. Each request carries three headers:

  • webhook-id — unique message id; matches id in the body
  • webhook-timestamp — send time in unix seconds (use it for a replay window; reject timestamps far outside your clock)
  • webhook-signature — v1,<base64 HMAC-SHA256> over {id}.{timestamp}.{rawBody} (space-separated entries; verify against each)

Verifying a delivery

Do not hand-roll the HMAC check. Use one of the Standard Webhooks drop-in libraries with the endpoint secret (returned once when you create the endpoint or roll its secret). Verify against the raw request body — don't re-serialize the parsed JSON; whitespace changes break the HMAC:

Code
import { Webhook } from 'standardwebhooks'; const wh = new Webhook(endpointSecret); // "whsec_..." from create/roll-secret app.post('/ledgerbee-webhook', express.raw({ type: 'application/json' }), (req, res) => { let event; try { event = wh.verify(req.body, req.headers); // throws on bad signature / stale timestamp } catch { return res.sendStatus(400); // reject unverified payloads — do not process them } handle(event); // event === the parsed { id, type, timestamp, data } res.sendStatus(200); });

Retries

A non-2xx response or a timeout is retried up to 8 total attempts over roughly 21 hours, with exponential backoff (30s → 2m → 8m → 32m → ~2h → ~8.5h → 10h). Every retry carries the same webhook-id — but is re-signed with the new send time, so verify against the headers of the delivery you received, and deduplicate on webhook-id. Deliveries can arrive out of order. After the schedule is exhausted the delivery is marked failed in the endpoint's delivery log (Marketplace → Webhooks).

Reconciling subscription events

Every subscription.* event's data carries partnerReferenceId — the clientReferenceId passed when binding an embedded checkout. It's your join key: match the event to your own order without storing LedgerBee ids first. If a delivery is missed (endpoint down, not yet subscribed), recover over the API instead of replaying: GET /v1/subscriptions?partnerReferenceId=<yours> — see Subscriptions.

Best practices

  • Verify the signature before trusting the payload.
  • Return 2xx quickly; do heavy work asynchronously. The response body is ignored.
  • Expect retries and rare duplicates — make handling idempotent on webhook-id.
  • Store the secret securely; roll it from Marketplace → Webhooks if exposed (deliveries re-sign with the new secret immediately).
  • Use the test delivery (UI button or POST /v1/webhook-endpoints/{id}/test) to wire up verification before real traffic arrives.

Event types

Subscribe an endpoint to any of the topics below. Each delivery carries the topic string in the envelope type field and the topic-specific payload in data — see the delivery envelope for the wrapper.

Subscription

subscription.assigned

Fired when a subscription is assigned to a customer (may be future-dated / upcoming).

FieldTypeDescription
subscriptionIdstring (uuid)Stable id of the subscription (the chain head id, fixed at creation and unchanged across plan / direction / cadence changes and cancellation). Correlate events to a subscription on this id.
versionIdstring (uuid)Internal version-chain row the event was emitted on. Advanced/debug only — it drifts across changes; correlate on subscriptionId or partnerReferenceId, not this.
customerIdstring (uuid)Id of the customer the subscription was assigned to.
partnerReferenceIdstring or nullYour clientReferenceId from embedded checkout, echoed back for reconciliation. Null when none was set.
assignedAtstring (date-time)ISO 8601 timestamp of when the subscription was assigned.

subscription.started

Fired when a subscription becomes active — grant entitlement/access on this event, not on assigned.

FieldTypeDescription
subscriptionIdstring (uuid)Stable id of the subscription (the chain head id, fixed at creation and unchanged across plan / direction / cadence changes and cancellation). Correlate events to a subscription on this id.
versionIdstring (uuid)Internal version-chain row the event was emitted on. Advanced/debug only — it drifts across changes; correlate on subscriptionId or partnerReferenceId, not this.
customerIdstring (uuid)Id of the customer that owns the subscription.
partnerReferenceIdstring or nullYour clientReferenceId from embedded checkout, echoed back for reconciliation. Null when none was set.
startedAtstring (date-time)ISO 8601 timestamp of when the subscription became active.

subscription.updated

Fired when a config property changes without a structural transition (e.g. name, payment method, billing direction).

FieldTypeDescription
subscriptionIdstring (uuid)Stable id of the subscription (the chain head id, fixed at creation and unchanged across plan / direction / cadence changes and cancellation). Correlate events to a subscription on this id.
versionIdstring (uuid)Internal version-chain row the event was emitted on. Advanced/debug only — it drifts across changes; correlate on subscriptionId or partnerReferenceId, not this.
customerIdstring (uuid)Id of the customer that owns the subscription.
partnerReferenceIdstring or nullYour clientReferenceId from embedded checkout, echoed back for reconciliation. Null when none was set.
changedFieldsstring[]Names of the subscription fields changed in this update.
updatedAtstring (date-time)ISO 8601 timestamp of when the update was applied.

subscription.transitioned

Fired on a structural change: plan replace, product edit, billing cadence change, or realign.

FieldTypeDescription
subscriptionIdstring (uuid)Stable id of the subscription (the chain head id, fixed at creation and unchanged across plan / direction / cadence changes and cancellation). Correlate events to a subscription on this id.
versionIdstring (uuid)Internal version-chain row the event was emitted on. Advanced/debug only — it drifts across changes; correlate on subscriptionId or partnerReferenceId, not this.
customerIdstring (uuid)Id of the customer that owns the subscription.
partnerReferenceIdstring or nullYour clientReferenceId from embedded checkout, echoed back for reconciliation. Null when none was set.
transitionTypeplan_replaced | products_edited | billing_cadence_changed | billing_realignedWhich kind of structural change occurred.
transitionedAtstring (date-time)ISO 8601 timestamp of when the transition was applied.

subscription.paused

Fired when a subscription is paused.

FieldTypeDescription
subscriptionIdstring (uuid)Stable id of the subscription (the chain head id, fixed at creation and unchanged across plan / direction / cadence changes and cancellation). Correlate events to a subscription on this id.
versionIdstring (uuid)Internal version-chain row the event was emitted on. Advanced/debug only — it drifts across changes; correlate on subscriptionId or partnerReferenceId, not this.
customerIdstring (uuid)Id of the customer that owns the subscription.
partnerReferenceIdstring or nullYour clientReferenceId from embedded checkout, echoed back for reconciliation. Null when none was set.
pausedAtstring (date-time)ISO 8601 timestamp of when the subscription was paused.

subscription.resumed

Fired when a subscription resumes from a pause.

FieldTypeDescription
subscriptionIdstring (uuid)Stable id of the subscription (the chain head id, fixed at creation and unchanged across plan / direction / cadence changes and cancellation). Correlate events to a subscription on this id.
versionIdstring (uuid)Internal version-chain row the event was emitted on. Advanced/debug only — it drifts across changes; correlate on subscriptionId or partnerReferenceId, not this.
customerIdstring (uuid)Id of the customer that owns the subscription.
partnerReferenceIdstring or nullYour clientReferenceId from embedded checkout, echoed back for reconciliation. Null when none was set.
resumedAtstring (date-time)ISO 8601 timestamp of when the subscription resumed.

subscription.trial_ended

Fired when a subscription trial ends and normal billing begins (the sub stays active).

FieldTypeDescription
subscriptionIdstring (uuid)Stable id of the subscription (the chain head id, fixed at creation and unchanged across plan / direction / cadence changes and cancellation). Correlate events to a subscription on this id.
versionIdstring (uuid)Internal version-chain row the event was emitted on. Advanced/debug only — it drifts across changes; correlate on subscriptionId or partnerReferenceId, not this.
customerIdstring (uuid)Id of the customer that owns the subscription.
partnerReferenceIdstring or nullYour clientReferenceId from embedded checkout, echoed back for reconciliation. Null when none was set.
endedAtstring (date-time)ISO 8601 timestamp of when the trial ended.

subscription.cancellation_scheduled

Fired when a future cancellation is scheduled for a subscription (still active until then).

FieldTypeDescription
subscriptionIdstring (uuid)Stable id of the subscription (the chain head id, fixed at creation and unchanged across plan / direction / cadence changes and cancellation). Correlate events to a subscription on this id.
versionIdstring (uuid)Internal version-chain row the event was emitted on. Advanced/debug only — it drifts across changes; correlate on subscriptionId or partnerReferenceId, not this.
customerIdstring (uuid)Id of the customer that owns the subscription.
partnerReferenceIdstring or nullYour clientReferenceId from embedded checkout, echoed back for reconciliation. Null when none was set.
effectiveDatestring (date-time) or nullWhen the cancellation takes effect, if known.
scheduledAtstring (date-time)ISO 8601 timestamp of when the cancellation was scheduled.

subscription.cancellation_cleared

Fired when a previously scheduled cancellation is cleared.

FieldTypeDescription
subscriptionIdstring (uuid)Stable id of the subscription (the chain head id, fixed at creation and unchanged across plan / direction / cadence changes and cancellation). Correlate events to a subscription on this id.
versionIdstring (uuid)Internal version-chain row the event was emitted on. Advanced/debug only — it drifts across changes; correlate on subscriptionId or partnerReferenceId, not this.
customerIdstring (uuid)Id of the customer that owns the subscription.
partnerReferenceIdstring or nullYour clientReferenceId from embedded checkout, echoed back for reconciliation. Null when none was set.
clearedAtstring (date-time)ISO 8601 timestamp of when the scheduled cancellation was cleared.

subscription.churned

Fired when a subscription is cancelled/finalized — revoke entitlement on this event.

FieldTypeDescription
subscriptionIdstring (uuid)Stable id of the subscription (the chain head id, fixed at creation and unchanged across plan / direction / cadence changes and cancellation). Correlate events to a subscription on this id.
versionIdstring (uuid)Internal version-chain row the event was emitted on. Advanced/debug only — it drifts across changes; correlate on subscriptionId or partnerReferenceId, not this.
customerIdstring (uuid)Id of the customer that owned the subscription.
partnerReferenceIdstring or nullYour clientReferenceId from embedded checkout, echoed back for reconciliation. Null when none was set.
reasonstring or nullFree-text cancellation reason, if one was supplied.
churnedAtstring (date-time)ISO 8601 timestamp of when the subscription was cancelled.

subscription.billed

Fired once per (child) subscription when a billing run produces its invoice.

FieldTypeDescription
subscriptionIdstring (uuid)Stable id of the subscription (the chain head id, fixed at creation and unchanged across plan / direction / cadence changes and cancellation). Correlate events to a subscription on this id.
versionIdstring (uuid)Internal version-chain row the event was emitted on. Advanced/debug only — it drifts across changes; correlate on subscriptionId or partnerReferenceId, not this.
customerIdstring (uuid)Id of the customer that owns the subscription.
partnerReferenceIdstring or nullYour clientReferenceId from embedded checkout, echoed back for reconciliation. Null when none was set.
invoiceIdstring (uuid)Id of the invoice produced by the billing run.
invoiceNumberstringHuman-facing invoice number.
amountstringTotal invoice amount, as a decimal string.
currencystringISO 4217 currency code of the invoice.
billedAtstring (date-time)ISO 8601 timestamp of when the invoice was produced.

subscription.payment_succeeded

Fired when a card charge for the subscription clears — the success pair of the charge_failed error signal.

FieldTypeDescription
subscriptionIdstring (uuid)Stable id of the subscription (the chain head id, fixed at creation and unchanged across plan / direction / cadence changes and cancellation). Correlate events to a subscription on this id.
versionIdstring (uuid)Internal version-chain row the event was emitted on. Advanced/debug only — it drifts across changes; correlate on subscriptionId or partnerReferenceId, not this.
customerIdstring (uuid)Id of the customer that owns the subscription.
partnerReferenceIdstring or nullYour clientReferenceId from embedded checkout, echoed back for reconciliation. Null when none was set.
invoiceIdstring (uuid)Id of the invoice the charge paid.
invoiceNumberstringHuman-facing number of the invoice the charge paid.
amountstringCharged amount, as a decimal string.
currencystringISO 4217 currency code of the charge.
occurredAtstring (date-time)ISO 8601 timestamp of when the charge cleared.

subscription.error

Fired when a delivery/processing problem occurs for a subscription (e.g. undeliverable recipient).

FieldTypeDescription
subscriptionIdstring (uuid)Stable id of the subscription (the chain head id, fixed at creation and unchanged across plan / direction / cadence changes and cancellation). Correlate events to a subscription on this id.
versionIdstring (uuid)Internal version-chain row the event was emitted on. Advanced/debug only — it drifts across changes; correlate on subscriptionId or partnerReferenceId, not this.
customerIdstring (uuid)Id of the customer that owns the subscription.
partnerReferenceIdstring or nullYour clientReferenceId from embedded checkout, echoed back for reconciliation. Null when none was set.
errorTyperecipient_undeliverable | charge_failedWhich problem occurred — see the subscription.error sub-events table for the full set and meaning.
messagestringHuman-readable description of the problem.
occurredAtstring (date-time)ISO 8601 timestamp of when the problem occurred.

The errorType field discriminates which problem occurred — it is one of:

errorTypeMeaning
recipient_undeliverableA document recipient for the subscription is undeliverable (e.g. the email hard-bounced); the document was not delivered.
charge_failedA card charge (first or recurring) for the subscription failed; the subscription is moved to AWAITING_PAYMENT so you can gate access. The raw provider decline is not exposed on the payload.

Billing

billing.invoice_sent

Fired when an invoice document is sent to the customer.

FieldTypeDescription
invoiceIdstring (uuid)Id of the invoice that was sent.
invoiceNumberstringHuman-facing invoice number.
customerIdstring (uuid)Id of the customer the invoice was sent to.
subscriptionIdstring (uuid) or nullSubscription the invoice relates to, or null for a standalone invoice.
amountstringTotal invoice amount, as a decimal string.
currencystringISO 4217 currency code of the invoice.
sentAtstring (date-time)ISO 8601 timestamp of when the invoice was sent.

billing.credit_note_sent

Fired when a credit note document is sent to the customer.

FieldTypeDescription
creditNoteIdstring (uuid)Id of the credit note that was sent.
creditNoteNumberstringHuman-facing credit note number.
customerIdstring (uuid)Id of the customer the credit note was sent to.
subscriptionIdstring (uuid) or nullSubscription the credit note relates to, or null for a standalone credit note.
amountstringTotal credit note amount, as a decimal string.
currencystringISO 4217 currency code of the credit note.
sentAtstring (date-time)ISO 8601 timestamp of when the credit note was sent.

Customer

customer.created

Fired when a customer is created (payload flags whether it was a portal self-signup).

FieldTypeDescription
customerIdstring (uuid)Id of the created customer.
selfSignupbooleanTrue when the customer was created via portal self-signup; false for operator/API/import creation.
createdAtstring (date-time)ISO 8601 timestamp of when the customer was created.

Card

card.added

Fired when a card is successfully saved for a customer (provider-opaque).

FieldTypeDescription
cardIdstring (uuid)Id of the saved card (LedgerBee CustomerPaymentMethod id).
customerIdstring (uuid)Id of the customer the card was saved for.
cardMaskstring or nullMasked card number, if known.
cardTypestring or nullCard network/brand, if known — never the payment provider.
expiryMonthinteger or nullCard expiry month (1–12), if known.
expiryYearinteger or nullCard expiry year (4-digit), if known.
isDefaultbooleanTrue when this card is the customer’s default after being saved.
addedAtstring (date-time)ISO 8601 timestamp of when the card was saved.

card.removed

Fired when a saved card is removed in-app or cancelled at the provider.

FieldTypeDescription
cardIdstring (uuid)Id of the removed card.
customerIdstring (uuid)Id of the customer the card belonged to.
cardMaskstring or nullMasked card number, if known.
cardTypestring or nullCard network/brand, if known.
reasonremoved_by_customer | removed_by_providerWhy the card was removed: removed_by_customer = removed in-app (portal/operator); removed_by_provider = cancelled out-of-band at the provider.
removedAtstring (date-time)ISO 8601 timestamp of when the card was removed.

card.updated

Fired when a saved card’s details change (network auto-update or refresh).

FieldTypeDescription
cardIdstring (uuid)Id of the updated card.
customerIdstring (uuid)Id of the customer that owns the card.
cardMaskstring or nullMasked card number after the update, if known.
cardTypestring or nullCard network/brand after the update, if known.
expiryMonthinteger or nullCard expiry month (1–12) after the update, if known.
expiryYearinteger or nullCard expiry year (4-digit) after the update, if known.
isDefaultbooleanWhether this card is the customer’s default.
changedFieldsstring[]Names of the card fields that changed in this update.
updatedAtstring (date-time)ISO 8601 timestamp of when the update was applied.

card.expiring

Fired when a saved card is approaching expiry.

FieldTypeDescription
cardIdstring (uuid)Id of the expiring card.
customerIdstring (uuid)Id of the customer that owns the card.
cardMaskstring or nullMasked card number, if known.
cardTypestring or nullCard network/brand, if known.
expiryMonthinteger or nullCard expiry month (1–12), if known.
expiryYearinteger or nullCard expiry year (4-digit), if known.
signaledAtstring (date-time)ISO 8601 timestamp of when the expiry signal was raised.

card.expired

Fired when a saved card is observed to have expired.

FieldTypeDescription
cardIdstring (uuid)Id of the expired card.
customerIdstring (uuid)Id of the customer that owns the card.
cardMaskstring or nullMasked card number, if known.
cardTypestring or nullCard network/brand, if known.
expiryMonthinteger or nullCard expiry month (1–12), if known.
expiryYearinteger or nullCard expiry year (4-digit), if known.
expiredAtstring (date-time)ISO 8601 timestamp of when the card was observed expired.

card.default_changed

Fired when the customer’s default card changes (explicit or auto-default).

FieldTypeDescription
cardIdstring (uuid)Id of the card that is now the customer’s default.
customerIdstring (uuid)Id of the customer whose default card changed.
previousDefaultCardIdstring (uuid) or nullId of the card that was previously default, or null if the customer had no default before.
changedAtstring (date-time)ISO 8601 timestamp of when the default changed.

card.backup_changed

Fired when the customer’s designated backup card is set, replaced, or cleared.

FieldTypeDescription
cardIdstring (uuid) or nullId of the card that is now the customer’s designated backup, or null when the designation was cleared.
customerIdstring (uuid)Id of the customer whose backup card changed.
previousBackupCardIdstring (uuid) or nullId of the card that was previously the backup, or null if the customer had no backup before.
changedAtstring (date-time)ISO 8601 timestamp of when the backup designation changed.

card.add_failed

Fired when a card-save attempt fails (decline or authentication failure).

FieldTypeDescription
customerIdstring (uuid)Id of the customer the failed card-save was for.
reasonstringMachine/short reason for the failure (decline or authentication failure).
failedAtstring (date-time)ISO 8601 timestamp of when the card-save attempt failed.

Quote

quote.sent

Fired when a quote is sent to the customer.

FieldTypeDescription
quoteIdstring (uuid)Id of the quote that was sent.
quoteNumberstring or nullHuman-facing quote number (allocated on send).
customerIdstring (uuid)Id of the customer the quote was sent to.
sentAtstring (date-time)ISO 8601 timestamp of when the quote was sent.

quote.converted

Fired when a quote is converted into an order confirmation or an invoice.

FieldTypeDescription
quoteIdstring (uuid)Id of the quote that was converted.
quoteNumberstring or nullHuman-facing quote number.
targetTypeinvoice | orderConfirmationWhat the quote was converted into.
targetIdstring (uuid)Id of the document the conversion produced (an invoice or order confirmation).
customerIdstring (uuid)Id of the customer the documents belong to.
convertedAtstring (date-time)ISO 8601 timestamp of when the conversion happened.

Order confirmation

order_confirmation.sent

Fired when an order confirmation is sent to the customer.

FieldTypeDescription
orderConfirmationIdstring (uuid)Id of the order confirmation that was sent.
orderConfirmationNumberstring or nullHuman-facing order confirmation number (allocated on send).
customerIdstring (uuid)Id of the customer the order confirmation was sent to.
sentAtstring (date-time)ISO 8601 timestamp of when the order confirmation was sent.

order_confirmation.converted

Fired when an order confirmation is converted into an invoice.

FieldTypeDescription
orderConfirmationIdstring (uuid)Id of the order confirmation that was converted.
orderConfirmationNumberstring or nullHuman-facing order confirmation number.
targetTypeinvoiceOrder confirmations only ever convert into an invoice.
targetIdstring (uuid)Id of the invoice the conversion produced.
customerIdstring (uuid)Id of the customer the documents belong to.
convertedAtstring (date-time)ISO 8601 timestamp of when the conversion happened.

Project

project.created

Fired when a project is created (payload carries the owned dimension id for correlation with the dimensions API).

FieldTypeDescription
projectIdstring (uuid)Id of the created project.
namestringProject name at creation time.
dimensionIdstring (uuid)Id of the dimension the project owns; usable with the dimensions API.
externalReferencestring or nullPartner-supplied external reference, null when not set.
createdAtstring (date-time)ISO 8601 timestamp of when the project was created.

project.updated

Fired when a project's fields are updated (payload lists the changed field names). Also fires on un-archive.

FieldTypeDescription
projectIdstring (uuid)Id of the updated project.
changedFieldsstring[]Names of the project fields the update changed.
updatedAtstring (date-time)ISO 8601 timestamp of the update.

project.archived

Fired when a project is archived (its dimension is deactivated; postings history is preserved).

FieldTypeDescription
projectIdstring (uuid)Id of the archived project.
archivedAtstring (date-time)ISO 8601 timestamp of the archive action.
Last modified on June 14, 2026
Document templatesMCP (AI agents)
On this page
  • Delivery envelope
  • Signing — Standard Webhooks
  • Verifying a delivery
  • Retries
  • Reconciling subscription events
  • Best practices
  • Event types
    • Subscription
    • Billing
    • Customer
    • Card
    • Quote
    • Order confirmation
    • Project
JSON
TypeScript