LedgerBee Developer
  • Getting started
  • Conventions
  • Products
  • Configuration
  • API Reference
Information
Accounts
    List accountsget
API Key
    Get current API keyget
Authority Extracts
    Submit authority extract datapost
Billing Groups
    Form a billing grouppostGet a billing groupgetAdd members to a billing grouppostRemove a member from a billing groupdeleteCheck billing group eligibilitypost
Budgets
    List budgetsgetGet a budgetgetGet the budget vs actuals comparisongetList a budget's frozen baselinesgetGet a frozen baseline with its snapshot cellsgetList a budget's re-baseline proposalsgetList a budget's scenariosgetResolve a budget's grid under a scenariogetGet the variance report vs a frozen baselinegetGet the runway headlineget
Checkout
    Confirm the checkoutpostQuote a first periodpostIntegration readinessgetMint a checkout sessionpostRehydrate a sessiongetRelease the card hold (edit-after-card)postPoll card statusgetOpen the card windowpostOpen a card-update window for a live subscriptionpost
Company
    Get company detailsget
Connected app OAuth
    JSON Web Key Set used to verify OAuth access-token signaturesgetRFC 8414 authorization-server metadata for the connected-app OAuth servergetRFC 9728 protected-resource metadata for an MCP resourcegetRFC 9728 protected-resource metadata for an MCP resourcegetOpenID Connect discovery document for the connected-app OAuth serverget
Credit Notes
    List credit notesgetCreate a credit notepostGet a credit notegetGet the delivery status of a credit notegetDownload the credit note PDFgetSend a credit note to the customerpostCredit a whole invoicepost
Customers
    List customersgetCreate a customerpostGet a customergetUpdate a customerpatchList a customer's contactsgetList a customer's departmentsgetList customer groupsget
Dimensions
    List all dimensionsgetCreate a new dimension categorypostGet a dimensiongetUpdate a dimension categoryputDelete a dimension categorydeleteList distribution keys (paginated)getCreate a distribution keypostGet a distribution keygetList dimension values (paginated)getCreate a new dimension valuepostUpdate a dimension valueputDelete a dimension valuedelete
Document Templates
    List document templatesget
Download Links
    Mint a download link for a document PDFgetDownload a minted linkget
Draft Journal Entries
    Create multiple draft journal entries in batchpostList draft journal entriesgetCreate a draft journal entrypostGet a draft journal entrygetDelete a draft journal entrydeleteBook a draft journal entrypost
Draft Journal Entries (v2)
    Create draft journal entries in batch (v2)postList draft journal entries (v2)getCreate a draft journal entry (v2)postGet a draft journal entry (v2)getDelete a draft journal entry (v2)deleteUpdate a draft journal entry (v2)patchBook a draft journal entry (v2)post
Entitlements
    List entitlementsgetCreate an entitlementpostGet an entitlementgetDelete an entitlementdeleteUpdate an entitlementpatch
Invoices
    List invoicesgetCreate a draft invoicepostGet an invoicegetGet the delivery status of an invoicegetDownload the invoice PDFgetSend an invoice to the customerpost
Journal Categories
    List journal categoriesgetCreate a journal categorypostUpdate a journal categoryputDelete a journal categorydelete
Journal Entries
    List journal entriesgetGet a journal entrygetUpdate a journal entry — correct the reference and/or set your external system idpatchGet attachments for a journal entrygetPreview a correction without posting itpostMove postings to different accounts, keeping the document intactpostReverse a posted entry and open a draft to re-enter itpostReverse posted journal entries in batchpostReverse a posted journal entrypost
Journal Entries (v2)
    Create a journal entry (v2)postCreate journal entries in batch (v2)post
MCP
    LedgerBee Developer MCP Serverpost
Meters
    List meter subscriptions by IDgetReport usagepostList meter subscriptions by nameget
Open Entries
    List a counterparty’s open entriesget
Order Confirmations
    List order confirmationsgetCreate a draft order confirmationpostGet an order confirmationgetUpdate a draft order confirmationpatchConvert an order confirmation into an invoicepostDownload an order confirmation as PDFgetSend an order confirmationpost
Payment Methods
    List saved payment methods for a customergetCancel a saved card on the payment providerdeleteUnassign a payment method from a customerdeleteGenerate a link for the customer to save a card for future paymentspostSet a saved payment method as the customer defaultput
Portal Plans
    List the full plan cataloguegetGet a plangetResolve the gated pricing catalogue for an identified buyer (partner display)post
Portal SSO
    Get a tenant's SSO signing keys (JWKS)getMint a checkout-vouch token (partner-vouched anonymous checkout)postMint a customer-portal SSO handoff referencepostProvision a customer + grant portal access (partner JIT provisioning)postRevoke (force-refresh) a user's customer-portal sessionspost
Product Groups
    List product groupsgetCreate a product grouppostGet a product groupgetDelete a product groupdeleteUpdate a product grouppatch
Product Prices
    Create a product pricepostGet a product pricegetDelete a product pricedeleteUpdate a product pricepatchActivate a product pricepostArchive a product pricepostDisable a product pricepostSet a price as the product defaultpost
Products
    List productsgetCreate a productpostGet a productgetDelete a productdeleteUpdate a productpatchArchive a productpost
Projects
    List all projectsgetCreate or update a project by external referenceputCreate a projectpostGet a projectgetUpdate a projectputGet project profitgetAdd a subprojectpostUpdate a subprojectputDelete a subprojectdelete
Quotes
    List quotesgetCreate a draft quotepostGet a quotegetUpdate a draft quotepatchConvert a quotepostDownload a quote as PDFgetSend a quotepost
Settlements
    List a counterparty’s settlementsgetSettle open entries against each otherpostGet a settlementgetCheck what settling these entries would dopost
Subscriptions
    List customer subscriptionsgetAssign a subscription to a customerpostGet a customer subscription by its stable idgetUpdate a customer subscriptionpatchRetry a failed card paymentpostList a subscription's pending scheduled changesgetCancel a single pending scheduled changedeleteCancel a customer subscriptionpostList subscription plansgetCreate a subscription planpostArchive a subscription planpost
Suppliers
    List suppliersgetCreate a supplierpostList supplier contactsgetList supplier departmentsgetList supplier groupsget
VAT Codes
    List VAT codesget
Vendors
    List vendorsgetCreate a vendorpostList vendor contactsgetList vendor departmentsgetList vendor groupsget
Webhook Endpoints
    List webhook endpointsgetCreate a webhook endpointpostRetrieve a webhook endpointgetUpdate a webhook endpointputDelete a webhook endpointdeleteRoll the signing secretpostSend a test eventpost
Schemas
LedgerBee Public API
LedgerBee Public API

Checkout

Download schema

Confirm the checkout

POST
https://api.ledgerbee.com/api
/v1/checkout/confirm
x-api-key (header)
or
OAuth 2.0

Consumes the session and writes everything, transactionally: the customer (created, or your existingCustomerId reused), the consent evidence (recorded against the SESSION's pinned versions with PARTNER_ASSERTED provenance), the subscription, and the first charge. Synchronous — the subscription id is in the response.

x-api-idempotency-key is REQUIRED (400 IDEMPOTENCY_KEY_REQUIRED without it). A retry with the same key replays the full original response; a concurrent duplicate answers 409 IDEMPOTENT_REQUEST_IN_PROGRESS; the same key reused for a DIFFERENT session answers 422 IDEMPOTENCY_KEY_REUSED.

Consent is assertion (you presented the pinned documents in your UI): termsAccepted: true is required, and recurringConsentAccepted: true on the CARD rail. On CARD, confirm requires the session's card to be CARD_READY — or a cardHandoffToken carried from an expired session.

Refusals to build the retry loop around: a 410 means the pinned plan/terms changed or the session expired (re-mint); PORTAL_CHECKOUT_AUTHORIZED_AMOUNT_CHANGED means the engine re-run no longer matches the pinned amount (card-release → re-quote → re-mint → re-confirm).

Invoice rail: the first invoice is billed asynchronously (billingPending: true). A tenant that serves no hosted portal sends invoice emails WITHOUT an online pay-now link — payment instructions ride the invoice document itself.

Required Scope

  • checkout

Confirm the checkout › Headers

x-api-idempotency-key
​string · maxLength: 255

Optional idempotency key for safely retrying mutating requests.

Confirm the checkout › Request Body

CheckoutConfirmRequest
sessionId
​string · required

The session to confirm. Single-use: consumed whatever the outcome.

paymentMethod
​string · enum · required

The payment rail the buyer chose.

Enum values:
CARD
INVOICE
termsAccepted
​boolean · required

Your assertion that the buyer accepted the pinned terms on your surface. Must be true — false/absent refuses with PORTAL_CHECKOUT_CONSENT_REQUIRED.

acceptedAt
​string · required

When the buyer accepted (ISO 8601). Evidence, not authority — implausible instants (future, or older than an hour) are replaced with the server’s own clock.

recurringConsentAccepted
​boolean

Your assertion that the buyer accepted recurring billing. REQUIRED true on the CARD rail.

cardHandoffToken
​string

A card handoff token carried from an EXPIRED session (the edit-after-card loop) — the captured card survives into this confirm. Defaults to the card window this session opened.

Confirm the checkout › Responses

CheckoutConfirmResponse
subscriptionId
​string · uuid · required

The created subscription.

reference
​string | null · required

Your reference, echoed.

billingPending
​boolean · required

True when the first invoice is billed asynchronously after this response (INVOICE rail, and CARD confirms whose charge is queued). Listen for subscription.billed / poll the subscription.

POST/v1/checkout/confirm
curl https://api.ledgerbee.com/api/v1/checkout/confirm \ --request POST \ --header 'Content-Type: application/json' \ --header 'x-api-key: <api-key>' \ --data '{ "sessionId": "string", "paymentMethod": "CARD", "termsAccepted": true, "recurringConsentAccepted": true, "acceptedAt": "string", "cardHandoffToken": "string" }'
Example Request Body
{ "sessionId": "string", "paymentMethod": "CARD", "termsAccepted": true, "recurringConsentAccepted": true, "acceptedAt": "string", "cardHandoffToken": "string" }
json
application/json
Example Responses
{ "subscriptionId": "00000000-0000-0000-0000-000000000000", "reference": "reference", "billingPending": true }
json
application/json

Quote a first period

POST
https://api.ledgerbee.com/api
/v1/checkout/quote
x-api-key (header)
or
OAuth 2.0

Pure read: first-period pricing including exact VAT for the buyer you describe, the terms bodies and recurring-billing disclosure context, start-date rules, allowedPaymentMethods, and cardPaymentsEnabled — which is chargeability-aware, so a card step is never offered in a currency the window would refuse. firstPeriodChargeable: false means a zero first period (free trial / 100% discount): adapt your copy ("no charge today"); the card window still opens save-only.

country is required so VAT resolves exactly; consumer-facing prices MUST be displayed including VAT (render the gross figures). A vatNumber is accepted for BUSINESS buyers only and is checked against the country's published format.

A STRIPE_CROSS_CURRENCY_NOT_ENABLED refusal later in the flow is a configuration issue on your Stripe account (enable cross-currency charges or add a bank account in that currency on Stripe), never a buyer error — cardPaymentsEnabled: false here is how you avoid offering that dead end.

Required Scope

  • checkout

Quote a first period › Headers

x-api-idempotency-key
​string · maxLength: 255

Optional idempotency key for safely retrying mutating requests.

Quote a first period › Request Body

CheckoutQuoteRequest
planVersionId
​string · uuid · required

The plan version to quote (from the catalogue).

planItemId
​string · uuid · required

The pricing-card item on that version.

country
​string · required

Buyer country, ISO 3166-1 alpha-2 — REQUIRED so VAT resolves exactly.

Example: DK
customerType
​string · enum · required

Whether the buyer is a business or a private person.

Enum values:
BUSINESS
PRIVATE_PERSON
vatNumber
​string

The buyer’s VAT number (BUSINESS only — refused otherwise).

startDate
​string

Requested start date (YYYY-MM-DD). Defaults to today; never in the past.

currency
​string

Presentment currency (ISO 4217). Must be in the card’s availableCurrencies; refused with PORTAL_CHECKOUT_CURRENCY_NOT_AVAILABLE otherwise. Absent → the card’s own currency.

Example: DKK
​CheckoutQuantitySelection[]

Buyer-chosen quantities for quantity-bearing products.

language
​string · enum

Language for display texts, terms and the disclosure.

Enum values:
en
da

Quote a first period › Responses

CheckoutQuoteResponse
quote
​object · required

First-period quote — the SAME payload the hosted portal renders (display parity is structural): plan title/description + display lines, pricing (subtotal, per-rate VAT breakdown, total, currency), quantity rows, terms bodies, the resolved start date, allowed payment methods and cardPaymentsEnabled.

firstPeriodChargeable
​boolean · required

False when the first period nets to zero (free trial / 100% discount). The card window still opens save-only — the card is stored for the first real charge and nothing is authorized ("no charge today").

POST/v1/checkout/quote
curl https://api.ledgerbee.com/api/v1/checkout/quote \ --request POST \ --header 'Content-Type: application/json' \ --header 'x-api-key: <api-key>' \ --data '{ "planVersionId": "3f2b6f1e-8c4d-4e0b-9d5a-7a1c2e3f4b5d", "planItemId": "3f2b6f1e-8c4d-4e0b-9d5a-7a1c2e3f4b5d", "country": "DK", "customerType": "BUSINESS", "vatNumber": "string", "startDate": "string", "currency": "DKK", "quantities": [ { "priceId": "3f2b6f1e-8c4d-4e0b-9d5a-7a1c2e3f4b5d", "quantity": 0 } ], "language": "en" }'
Example Request Body
{ "planVersionId": "3f2b6f1e-8c4d-4e0b-9d5a-7a1c2e3f4b5d", "planItemId": "3f2b6f1e-8c4d-4e0b-9d5a-7a1c2e3f4b5d", "country": "DK", "customerType": "BUSINESS", "vatNumber": "string", "startDate": "string", "currency": "DKK", "quantities": [ { "priceId": "3f2b6f1e-8c4d-4e0b-9d5a-7a1c2e3f4b5d", "quantity": 0 } ], "language": "en" }
json
application/json
Example Responses
{ "quote": {}, "firstPeriodChargeable": true }
json
application/json

Integration readiness

GET
https://api.ledgerbee.com/api
/v1/checkout/readiness
x-api-key (header)
or
OAuth 2.0

One object, a machine-readable state per tenant precondition — the "am I integrated?" preflight, replacing error-by-error discovery. Make this the first call of your integration.

Preconditions for a working checkout: the Subscription license, at least one published plan with a sellable item, and — for the card rail — an active Stripe Connect account. Hosted card windows additionally need your return origin on your embeddableOrigins allowlist. LedgerBee-hosted terms are NOT a precondition: generalTermsPublished is informational — when you host terms in LedgerBee they ride the quote/session and confirm records per-version acceptance; when you don't, you host your own terms and confirm records your acceptance assertion.

Customer groups are NOT a readiness item: they are per-request data. Discover them via GET /v1/customers/groups.

Required Scope

  • checkout

Integration readiness › Responses

CheckoutReadinessResponse
subscriptionLicense
​boolean · required

Whether you hold the Subscription license — without it nothing is checkoutable.

publishedPlans
​number · required

Number of published plans.

checkoutablePlans
​number · required

Number of published plans with a sellable item — checkoutable on this surface.

generalTermsPublished
​boolean · required

Informational, never a gate: whether published GENERAL terms exist in LedgerBee. When true, quote and session responses carry them and confirm records per-version acceptance evidence; when false, you host your own terms and confirm records your acceptance assertion.

​CheckoutReadinessStripeConnect · required
embeddableOrigins
​string[] · required

The configured embeddableOrigins allowlist — required for HOSTED card windows’ returnUrl.

GET/v1/checkout/readiness
curl https://api.ledgerbee.com/api/v1/checkout/readiness \ --header 'x-api-key: <api-key>'
Example Responses
{ "subscriptionLicense": true, "publishedPlans": 0, "checkoutablePlans": 0, "generalTermsPublished": true, "stripeConnect": { "connected": true, "status": "status", "settlementCurrency": "settlementCurrency", "allowCrossCurrencyCharges": true, "chargeableCurrencies": [ "string" ] }, "embeddableOrigins": [ "string" ] }
json
application/json

Mint a checkout session

POST
https://api.ledgerbee.com/api
/v1/checkout/session
x-api-key (header)
or
OAuth 2.0

Mints the single-use session the rest of the flow runs against, PINNING what your buyer was shown: the plan version, the terms + disclosure versions, the resolved pricing and currency, quantities, VAT inputs and start date. Confirm re-runs the billing engine against those pinned inputs and refuses a drifted amount — you never bill a number the engine wouldn't produce, and a tenant republish affects new sessions only.

The buyer is plain request data — no tokens, no buyer verification. customerGroupId is REQUIRED (discover groups via GET /v1/customers/groups). Pass existingCustomerId for a returning buyer so they keep one customer record. Pass reference (your order/cart id) and every checkout.* webhook echoes it back.

The session expires after expiresInMinutes (default 30). An expired session answers 410 — re-mint and, if a card was already captured, carry its cardHandoffToken into the fresh session's confirm so the buyer never re-enters card details.

Required Scope

  • checkout

Mint a checkout session › Headers

x-api-idempotency-key
​string · maxLength: 255

Optional idempotency key for safely retrying mutating requests.

Mint a checkout session › Request Body

CheckoutSessionRequest
planVersionId
​string · uuid · required

The plan version to check out (from the catalogue).

planItemId
​string · uuid · required

The pricing-card item on that version.

​object · required

The buyer — plain request data; no tokens, no ceremony.

startDate
​string

Requested start date (YYYY-MM-DD). Defaults to today; never in the past.

currency
​string

Presentment currency (ISO 4217); must be in the card’s availableCurrencies.

​CheckoutQuantitySelection[]

Buyer-chosen quantities.

expiresInMinutes
​number · min: 5 · max: 1440

Session TTL in minutes. Default 30.

reference
​string

Your own order/cart id (Stripe client_reference_id parity) — echoed on session reads, the confirm response and every checkout.* webhook payload.

language
​string · enum

Language for display texts, terms and the disclosure.

Enum values:
en
da

Mint a checkout session › Responses

CheckoutSessionResponse
sessionId
​string · required

The opaque session id — your handle for every later call.

expiresAt
​string · required

When the session expires (ISO 8601). Expired sessions answer 410.

reference
​string | null · required

Your reference, echoed.

quote
​object · required

The same first-period quote payload POST /v1/checkout/quote returns.

​object · required

What the session pinned — render exactly this.

firstPeriodChargeable
​boolean · required

False when the pinned first period nets to zero (save-only card window).

POST/v1/checkout/session
curl https://api.ledgerbee.com/api/v1/checkout/session \ --request POST \ --header 'Content-Type: application/json' \ --header 'x-api-key: <api-key>' \ --data '{ "planVersionId": "3f2b6f1e-8c4d-4e0b-9d5a-7a1c2e3f4b5d", "planItemId": "3f2b6f1e-8c4d-4e0b-9d5a-7a1c2e3f4b5d", "buyer": { "customerType": "BUSINESS", "name": "Acme ApS", "email": "buyer@example.com", "customerGroupId": "3f2b6f1e-8c4d-4e0b-9d5a-7a1c2e3f4b5d", "country": "DK", "vatNumber": "DK12345678", "address": "string", "postalCode": "string", "city": "string", "billingEmail": "billing@example.com", "existingCustomerId": "3f2b6f1e-8c4d-4e0b-9d5a-7a1c2e3f4b5d" }, "startDate": "string", "currency": "string", "quantities": [ { "priceId": "3f2b6f1e-8c4d-4e0b-9d5a-7a1c2e3f4b5d", "quantity": 0 } ], "expiresInMinutes": 5, "reference": "string", "language": "en" }'
Example Request Body
{ "planVersionId": "3f2b6f1e-8c4d-4e0b-9d5a-7a1c2e3f4b5d", "planItemId": "3f2b6f1e-8c4d-4e0b-9d5a-7a1c2e3f4b5d", "buyer": { "customerType": "BUSINESS", "name": "Acme ApS", "email": "buyer@example.com", "customerGroupId": "3f2b6f1e-8c4d-4e0b-9d5a-7a1c2e3f4b5d", "country": "DK", "vatNumber": "DK12345678", "address": "string", "postalCode": "string", "city": "string", "billingEmail": "billing@example.com", "existingCustomerId": "3f2b6f1e-8c4d-4e0b-9d5a-7a1c2e3f4b5d" }, "startDate": "string", "currency": "string", "quantities": [ { "priceId": "3f2b6f1e-8c4d-4e0b-9d5a-7a1c2e3f4b5d", "quantity": 0 } ], "expiresInMinutes": 5, "reference": "string", "language": "en" }
json
application/json
Example Responses
{ "sessionId": "sessionId", "expiresAt": "expiresAt", "reference": "reference", "quote": {}, "pinned": { "currency": "DKK", "netMajor": 0, "totalGrossMajor": 0, "startDate": "startDate", "disclosureVersion": "disclosureVersion", "disclosureText": "disclosureText", "acceptedTermsVersionIds": [ "string" ], "expiresInMinutes": 0 }, "firstPeriodChargeable": true }
json
application/json

Rehydrate a session

GET
https://api.ledgerbee.com/api
/v1/checkout/session/{id}
x-api-key (header)
or
OAuth 2.0

PEEK a live session after a partner-side reload: the buyer payload, the pinned quote summary, your reference, and whether a card window was opened. 410 when expired or already consumed.

Required Scope

  • checkout

Rehydrate a session › path Parameters

id
​string · required

The opaque session id (64 hex chars).

Rehydrate a session › Responses

CheckoutSessionView
sessionId
​string · required

The opaque session id.

expiresAt
​string · required

When the session expires (ISO 8601).

reference
​string | null · required

Your reference, echoed.

planVersionId
​string · uuid · required

The pinned plan version.

planItemId
​string · uuid · required

The pinned pricing-card item.

buyer
​object · required

The buyer payload the session was minted with.

​CheckoutPinned · required
firstPeriodChargeable
​boolean · required

False when the pinned first period nets to zero.

cardWindowOpened
​boolean · required

Whether a card window has been opened on this session.

GET/v1/checkout/session/{id}
curl https://api.ledgerbee.com/api/v1/checkout/session/:id \ --header 'x-api-key: <api-key>'
Example Responses
{ "sessionId": "sessionId", "expiresAt": "expiresAt", "reference": "reference", "planVersionId": "00000000-0000-0000-0000-000000000000", "planItemId": "00000000-0000-0000-0000-000000000000", "buyer": {}, "pinned": { "currency": "DKK", "netMajor": 0, "totalGrossMajor": 0, "startDate": "startDate", "disclosureVersion": "disclosureVersion", "disclosureText": "disclosureText", "acceptedTermsVersionIds": [ "string" ], "expiresInMinutes": 0 }, "firstPeriodChargeable": true, "cardWindowOpened": true }
json
application/json

Release the card hold (edit-after-card)

POST
https://api.ledgerbee.com/api
/v1/checkout/session/{id}/card-release
x-api-key (header)
or
OAuth 2.0

The edit-after-card loop's first step: when the buyer changes quantities, start date or VAT inputs AFTER the card step, confirm refuses the now-stale pinned amount — call this, then re-quote, re-mint and re-confirm.

SAVE_ONLY: the captured card SURVIVES (carry its cardHandoffToken into the fresh session's confirm — the buyer never re-enters card details; the first charge is sized at billing). RECAPTURE_REQUIRED: the card could not be preserved — discard it and open a fresh card window.

Required Scope

  • checkout

Release the card hold (edit-after-card) › path Parameters

id
​string · required

The opaque session id (64 hex chars).

Release the card hold (edit-after-card) › Headers

x-api-idempotency-key
​string · maxLength: 255

Optional idempotency key for safely retrying mutating requests.

Release the card hold (edit-after-card) › Responses

CheckoutCardReleaseResponse
status
​string · enum · required

SAVE_ONLY: the card survives — re-quote, re-mint and confirm; the first charge is sized at billing. RECAPTURE_REQUIRED: discard the card and open a fresh window.

Enum values:
SAVE_ONLY
RECAPTURE_REQUIRED
POST/v1/checkout/session/{id}/card-release
curl https://api.ledgerbee.com/api/v1/checkout/session/:id/card-release \ --request POST \ --header 'x-api-key: <api-key>'
Example Responses
{ "status": "SAVE_ONLY" }
json
application/json

Poll card status

GET
https://api.ledgerbee.com/api
/v1/checkout/session/{id}/card-status
x-api-key (header)
or
OAuth 2.0

Poll after the buyer completes the card form: PENDING → keep polling, CARD_READY → confirm may proceed (the captured card's display details are included — show the buyer WHICH card will be charged), EXPIRED → the window lapsed, open a fresh one. The checkout.card_ready webhook is the push alternative; this poll stays authoritative.

Required Scope

  • checkout

Poll card status › path Parameters

id
​string · required

The opaque session id (64 hex chars).

Poll card status › Responses

CheckoutCardStatusResponse
status
​string · enum · required

PENDING: keep polling (or listen for checkout.card_ready). CARD_READY: confirm may proceed. EXPIRED: the window lapsed — open a fresh one.

Enum values:
PENDING
CARD_READY
EXPIRED
card
​object | null

The captured card (CARD_READY only).

GET/v1/checkout/session/{id}/card-status
curl https://api.ledgerbee.com/api/v1/checkout/session/:id/card-status \ --header 'x-api-key: <api-key>'
Example Responses
{ "status": "PENDING", "card": { "label": "Visa •••• 4242", "cardType": "cardType", "cardMask": "cardMask", "accountIdentifier": "accountIdentifier" } }
json
application/json

Open the card window

POST
https://api.ledgerbee.com/api
/v1/checkout/session/{id}/card-window
x-api-key (header)
or
OAuth 2.0

Opens the Stripe card surface for the session — the ONLY place a card is ever entered (your systems never touch card data). The tenant's active Stripe Connect account is the card rail; there is no provider selection. Refused with CARD_PROVIDER_NOT_CONNECTED when Stripe isn't connected.

uiMode: 'embedded' (default) returns a clientSecret — mount Stripe's embedded Checkout on your page with Stripe.js (loadStripe(publishableKey, { stripeAccount })). uiMode: 'hosted' returns a redirectUrl to checkout.stripe.com; returnUrl is then REQUIRED and its origin must be on your embeddableOrigins allowlist. The flow is identical either way: the card lands asynchronously — poll card-status (or listen for checkout.card_ready), then confirm.

A zero first period still opens the window SAVE-ONLY: the card is stored for the first real charge and nothing is authorized ("no charge today").

Required Scope

  • checkout

Open the card window › path Parameters

id
​string · required

The opaque session id (64 hex chars).

Open the card window › Headers

x-api-idempotency-key
​string · maxLength: 255

Optional idempotency key for safely retrying mutating requests.

Open the card window › Request Body

CheckoutCardWindowRequest
uiMode
​string · enum

How the buyer meets Stripe's card form: 'embedded' (default) returns a client secret you mount on your page with Stripe.js; 'hosted' returns a redirect URL to checkout.stripe.com.

Enum values:
embedded
hosted
returnUrl
​string

Where Stripe sends the buyer back after a HOSTED window. REQUIRED for hosted (its origin must be on your embeddableOrigins allowlist); refused for embedded, which completes in-page.

Open the card window › Responses

CheckoutCardWindowResponse
mode
​string · enum · required

STRIPE_EMBEDDED → mount with clientSecret; REDIRECT → navigate the buyer to redirectUrl.

Enum values:
STRIPE_EMBEDDED
REDIRECT
handoffToken
​string · required

The card handoff token. It outlives the session: carry it into a fresh session’s confirm after an expiry and the buyer never re-enters card details.

expiresAt
​string · required

When the provider window expires (ISO 8601).

clientSecret
​string

Stripe embedded Checkout client secret (STRIPE_EMBEDDED only).

publishableKey
​string

Publishable key for Stripe.js (STRIPE_EMBEDDED only).

stripeAccountId
​string

The connected Stripe account id for Stripe.js (STRIPE_EMBEDDED only).

redirectUrl
​string

The hosted window URL to send the buyer to (REDIRECT only).

POST/v1/checkout/session/{id}/card-window
curl https://api.ledgerbee.com/api/v1/checkout/session/:id/card-window \ --request POST \ --header 'Content-Type: application/json' \ --header 'x-api-key: <api-key>' \ --data '{ "uiMode": "embedded", "returnUrl": "string" }'
Example Request Body
{ "uiMode": "embedded", "returnUrl": "string" }
json
application/json
Example Responses
{ "mode": "STRIPE_EMBEDDED", "clientSecret": "clientSecret", "publishableKey": "publishableKey", "stripeAccountId": "stripeAccountId", "redirectUrl": "redirectUrl", "handoffToken": "handoffToken", "expiresAt": "expiresAt" }
json
application/json

Open a card-update window for a live subscription

POST
https://api.ledgerbee.com/api
/v1/checkout/subscriptions/{id}/card-window
x-api-key (header)
or
OAuth 2.0

The partner-UI path for updating the card on an EXISTING subscription — same uiMode contract as the checkout card window, rendered to the buyer in your page. The window is save-only and binds to the buyer's stored payment profile; when the new card lands (Stripe webhook), it REPLACES the card on file for that subscription. The buyer's emailed manage link remains the compliance floor and keeps working unchanged.

Required Scope

  • checkout

Open a card-update window for a live subscription › path Parameters

id
​string · uuid · required

The subscription id (any id in its version chain).

Open a card-update window for a live subscription › Headers

x-api-idempotency-key
​string · maxLength: 255

Optional idempotency key for safely retrying mutating requests.

Open a card-update window for a live subscription › Request Body

CheckoutCardWindowRequest
uiMode
​string · enum

How the buyer meets Stripe's card form: 'embedded' (default) returns a client secret you mount on your page with Stripe.js; 'hosted' returns a redirect URL to checkout.stripe.com.

Enum values:
embedded
hosted
returnUrl
​string

Where Stripe sends the buyer back after a HOSTED window. REQUIRED for hosted (its origin must be on your embeddableOrigins allowlist); refused for embedded, which completes in-page.

Open a card-update window for a live subscription › Responses

CheckoutCardWindowResponse
mode
​string · enum · required

STRIPE_EMBEDDED → mount with clientSecret; REDIRECT → navigate the buyer to redirectUrl.

Enum values:
STRIPE_EMBEDDED
REDIRECT
handoffToken
​string · required

The card handoff token. It outlives the session: carry it into a fresh session’s confirm after an expiry and the buyer never re-enters card details.

expiresAt
​string · required

When the provider window expires (ISO 8601).

clientSecret
​string

Stripe embedded Checkout client secret (STRIPE_EMBEDDED only).

publishableKey
​string

Publishable key for Stripe.js (STRIPE_EMBEDDED only).

stripeAccountId
​string

The connected Stripe account id for Stripe.js (STRIPE_EMBEDDED only).

redirectUrl
​string

The hosted window URL to send the buyer to (REDIRECT only).

POST/v1/checkout/subscriptions/{id}/card-window
curl https://api.ledgerbee.com/api/v1/checkout/subscriptions/:id/card-window \ --request POST \ --header 'Content-Type: application/json' \ --header 'x-api-key: <api-key>' \ --data '{ "uiMode": "embedded", "returnUrl": "string" }'
Example Request Body
{ "uiMode": "embedded", "returnUrl": "string" }
json
application/json
Example Responses
{ "mode": "STRIPE_EMBEDDED", "clientSecret": "clientSecret", "publishableKey": "publishableKey", "stripeAccountId": "stripeAccountId", "redirectUrl": "redirectUrl", "handoffToken": "handoffToken", "expiresAt": "expiresAt" }
json
application/json

BudgetsCompany