Schemas
CompanyFiscalYear
startDateFirst day of the fiscal year, inclusive (YYYY-MM-DD)
endDateLast day of the fiscal year, inclusive (YYYY-MM-DD)
statusWhether the year is still open for posting
CompanyAccounting
baseCurrencyThe company's base (functional) currency, ISO 4217. Every figure a report labels a base-currency total is denominated in this.
currentFiscalYearThe fiscal year containing today. Null when no accounting year covers today — a company mid-setup, or one whose years stop short of the current date.
CompanyResponse
idUnique identifier for the company, uuidv7 based
nameCompany name
emailPrimary email address
addressStreet address
The company's accounting configuration: base currency and the fiscal year covering today.
vatVAT / company registration number, as registered
billingEmailBilling email address
cityCity
postalCodePostal code
countryCodeCountry code (ISO 3166-1 alpha-2)
phonePhone number
preferredLanguagePreferred language code
contactPersonFirstNameContact person first name
contactPersonLastNameContact person last name
RateLimitTierResponse
nameName of the rate limit tier
ttlTime-to-live in milliseconds for this rate limit tier (0 means no time limit)
limitMaximum number of requests allowed within the TTL window (-1 means unlimited)
ApiKeyInfoResponse
Available rate limit tiers for this API key
expiresAtExpiration date and time of the API key
ipWhitelistList of IP addresses allowed to use this API key
scopesList of scopes granted to this API key
AccountResponse
idThe unique identifier of the account
nameName of the account
accountNumberAccount type number
publicAccountIdPublic account id that the account maps to
ledgerTypeType of ledger account. Only BALANCE_SHEET and PROFIT_AND_LOSS accounts can be used in journal entries.
accountClassificationAccount classification (ASSET, LIABILITY, EQUITY, REVENUE, EXPENSE)
controlAccountTypeControl account type. ACCOUNTS_RECEIVABLE requires customerId on journal entries, ACCOUNTS_PAYABLE requires vendorId. Null for regular accounts.
PublicAuthorityExtractIngestRequest
The extract items — one object per extract (momsindberetning, erhvervsselvangivelse, udbytteindberetning, e-indkomst, skattekonto, lønsum, …). Each item is stored as received.
senderThe delivering system, e.g. 'revibot'.
batchIdThe sender's own id for this batch. Folded into the idempotency claim, so an x-api-idempotency-key reused across two DIFFERENT batches is refused (422) instead of silently replaying the first batch's response.
CustomerGroupResponse
idThe unique identifier of the customer group
numberCustomer group number
nameName of the customer group
accountIdThe ledger account ID associated with this customer group. Present with the customers-read scope; omitted for checkout-only keys.
accountNumberThe ledger account number associated with this customer group
accountNameThe ledger account name associated with this customer group
Key-value metadata attached to the customer group
discountDeprecated - always 0. No pricing path applies it. Present with the customers-read scope; omitted for checkout-only keys.
CustomerDepartmentResponse
idThe unique identifier of the department
nameName of the department
isDefaultWhether this is the default department for the customer
isActiveWhether the department is active
poNumberPurchase order number
eanNumberEAN number for e-invoicing
addressStreet address
cityCity
postalCodePostal code
countryCodeTwo-letter country code (ISO 3166-1 alpha-2)
CustomerContactResponse
idThe unique identifier of the contact
nameName of the contact
isDefaultForCustomerWhether this is the default contact for the customer
emailEmail address
phonePhone number
CustomerResponse
idThe unique identifier of the customer
customerNumberCustomer number
customerTypeCustomer type
nameName of the customer
vatZoneVAT zone classification
customerGroupIdCustomer group ID
isActiveWhether the customer is active
billingRelationshipBilling relationship. self = this customer is billed directly. parent_pays = the parent customer (set via parentCustomerId) is billed instead.
includeChildDetailsPdfWhether to attach a zip of per-child detail PDFs when sending consolidated invoices. Only relevant for parent customers in single_invoice mode.
selfServiceDetailsEnabledWhether this customer's portal users may fill in their own billing details (VAT number, street, postal code, city), both on the portal's Company settings page and during checkout, instead of only confirming a read-only copy of the record. Country and customer type stay operator-owned either way, which is what keeps them inside the VAT regime the operator assigned.
customerGroupNumberCustomer group number
customerGroupNameCustomer group name
emailEmail address
phonePhone number
addressStreet address
cityCity
postalCodePostal code
countryCodeTwo-letter country code (ISO 3166-1 alpha-2)
vatNumberVAT registration number
websiteWebsite URL
externalSystemIdExternal system identifier for tracking the customer across other systems
creditLimitCredit limit
openingBalanceOpening balance in the company base currency (signed: positive = the customer owes us)
paymentTermsPayment terms in days
paymentTermTypePayment term type
defaultCurrencyDefault currency code
parentCustomerIdParent customer ID. When set, this customer is a child in a parent-child billing relationship. Set together with billingRelationship to change how this customer is billed.
consolidationModeConsolidation mode for a parent customer. single_invoice = all child subscriptions are consolidated onto one parent invoice on billingDay. per_child_invoice = each child receives its own invoice. Only meaningful on parent customers.
billingDayDay of month (1-28) when the parent consolidated invoice is generated. Required for single_invoice consolidation mode.
parentInvoiceTemplateIdParent single invoice PDF template override
Key-value metadata attached to the customer
CreateCustomerRequest
customerTypeSpecifies whether the customer is a business or a private person
nameCustomer name
vatZoneVAT zone classification
customerGroupIdCustomer group ID
countryCodeTwo-letter country code
defaultCurrency^[A-Za-z]{3}$ · requiredThe currency this customer is invoiced in, ISO 4217 alpha-3.
customerNumberUnique customer number. Omit it, or send an empty value, to have the next number assigned from the company customer sequence; the assigned number comes back on the response.
emailEmail address
phonePhone number
addressStreet address
cityCity
postalCodePostal code
vatNumberVAT registration number
websiteWebsite URL
externalSystemIdExternal system identifier for tracking the customer across other systems
notesAdditional notes
creditLimitCredit limit
openingBalanceOpening balance in the company base currency, seeding receivables that predate LedgerBee. Signed: positive = the customer owes us, negative = a credit position.
paymentTermsPayment terms in days
paymentTermTypePayment term type
isActiveWhether the customer is active
parentCustomerIdParent customer ID. Set when creating this customer as a child in a parent-child billing relationship. Must be combined with billingRelationship = parent_pays to route billing to the parent. Send null to create a standalone customer.
billingRelationshipBilling relationship. self (default) = this customer is billed directly. parent_pays = the parent customer (set via parentCustomerId) is billed instead.
consolidationModeConsolidation mode (parent customers only). single_invoice = all child subscriptions consolidated onto one invoice on billingDay. per_child_invoice = each child receives its own invoice.
billingDayDay of month (1-28) for the parent consolidated invoice. Required for single_invoice consolidation.
includeChildDetailsPdfWhether to attach a zip of per-child detail PDFs when sending consolidated invoices
selfServiceDetailsEnabledWhether this customer's portal users may fill in their own billing details (VAT number, street, postal code, city), both on the portal's Company settings page and during checkout, instead of only confirming a read-only copy of the record. Country and customer type stay operator-owned either way, which is what keeps them inside the VAT regime the operator assigned.
parentInvoiceTemplateIdParent single invoice PDF template override. Send null to clear.
Key-value metadata to attach to the customer. At most 50 entries; keys up to 128 characters, string values up to 500 characters.
CreateCustomerResponse
idThe unique identifier of the created customer
customerNumberCustomer number
SubscriptionTransitionItem
customerSubscriptionIdThe subscription to move onto the new billing arrangement: the id GET /v1/subscriptions returns, the same stable id every subscription endpoint takes.
UpdateCustomerRequest
customerTypeCustomer type
customerNumberUnique customer number
nameCustomer name
vatZoneVAT zone classification
customerGroupIdCustomer group ID
emailEmail address. Send null or empty string to clear.
phonePhone number
addressStreet address
cityCity
postalCodePostal code
countryCodeTwo-letter country code
vatNumberVAT registration number
websiteWebsite URL
externalSystemIdExternal system identifier for tracking the customer across other systems
notesAdditional notes
creditLimitCredit limit
openingBalanceOpening balance in the company base currency, seeding receivables that predate LedgerBee. Signed: positive = the customer owes us, negative = a credit position.
paymentTermsPayment terms in days
paymentTermTypePayment term type
defaultCurrency^[A-Za-z]{3}$The currency this customer is invoiced in, ISO 4217 alpha-3. Omit it, or send a blank one, to leave the stored currency alone.
isActiveWhether the customer is active
parentCustomerIdParent customer ID. Send null to detach from parent. Changing this field on a customer with active subscriptions will transition those subscriptions to the parent's billing day with a clean cut at today's date: advance-billed subscriptions receive a credit note for the remaining days of the current period, and arrears-billed subscriptions are invoiced up to the transition date. When transitioning, subscriptionTransitions must list every active subscription on this customer as explicit acknowledgement that they will be migrated.
billingRelationshipBilling relationship. Change to parent_pays together with parentCustomerId to route billing to the parent.
consolidationModeConsolidation mode (parent customers only). Send null to clear.
billingDayDay of month (1-28) for the parent consolidated invoice. Send null to clear.
includeChildDetailsPdfWhether to attach a zip of per-child detail PDFs when sending consolidated invoices
selfServiceDetailsEnabledWhether this customer's portal users may fill in their own billing details (VAT number, street, postal code, city), both on the portal's Company settings page and during checkout, instead of only confirming a read-only copy of the record. Country and customer type stay operator-owned either way, which is what keeps them inside the VAT regime the operator assigned.
parentInvoiceTemplateIdParent single invoice PDF template override. Send null to clear.
Subscription transitions — required when changing parentCustomerId, billingRelationship, or consolidationMode on a customer with active subscriptions, and when changing billingDay or consolidationMode on a single_invoice parent (then it must cover every child customer's subscriptions). Lists every active subscription as explicit acknowledgement that each one is migrated to the new billing arrangement with a clean cut at today's date. Entries for subscriptions that need no transition are accepted and ignored.
Key-value metadata. When provided, REPLACES the customer metadata wholesale — send the complete desired map; an empty object clears all entries. Omit the field to leave metadata unchanged. At most 50 entries; keys up to 128 characters, string values up to 500 characters.
DimensionValue
idUnique identifier of the dimension value
nameDisplay name of the dimension value
parentIdParent dimension value ID for hierarchical structures. Null for root-level values. Use this to create nested structures like "Sales > Europe > Denmark".
Child dimension values (nested structure). Only populated in list responses.
Dimension
idUnique identifier of the dimension category
nameDisplay name of the dimension category
isUniqueWhen true, only one value from this dimension can be assigned to a journal entry (mutually exclusive). When false, multiple values can be assigned (additive tags). Example: A "Department" dimension is typically unique (one department per entry), while a "Tags" dimension might allow multiple values.
Available dimension values within this category, organized as a hierarchical tree. Root values have parentId as null, nested values reference their parent.
PublicDimensionValueListItem
idUnique identifier of the dimension value
nameName of the value
parentIdParent value id for hierarchical dimensions. Absent on root values. Rebuild the tree client-side.
PublicListDimensionValuesResponse
Dimension values as a FLAT page ordered by name; use parentId to rebuild hierarchy
totalTotal number of values in this dimension
pageCurrent page number (1-indexed)
limitMaximum number of items per page
totalPagesTotal number of pages available
PublicDistributionKeyAllocation
valueIdThe dimension value this share is allocated to
valueNameName of the target dimension value
percentageShare of the amount, in percent with up to six decimal places. All shares sum to exactly 100.
sortOrderDisplay order of the allocation row (0-based)
PublicDistributionKey
idUnique identifier of the distribution key
nameDisplay name
isAdHocTrue for a one-document split created inline on a draft. Ad-hoc keys are excluded from listings unless includeAdHoc=true, and their lifecycle is system-managed.
isActiveFalse once the key is archived (a posted ad-hoc key archives automatically)
The allocations, in display order. Percentages sum to exactly 100.
PublicListDistributionKeysResponse
Distribution keys, ordered by name
totalTotal number of keys matching the query
pageCurrent page number (1-indexed)
limitMaximum number of items per page
totalPagesTotal number of pages available
PublicCreateDistributionKeyAllocation
valueIdThe dimension value to allocate to. Must belong to this dimension.
percentageShare in percent, up to six decimal places. All allocations must sum to exactly 100.
sortOrderDisplay order of the allocation row (0-based)
PublicCreateDistributionKey
Allocations that must sum to exactly 100%. Between 2 and 100 entries.
nameDisplay name. Required for a reusable key; omit it on an ad-hoc key, which names itself from its allocations server-side.
isAdHocTrue to create a one-document split. Ad-hoc keys are hidden from listings by default and their lifecycle is system-managed: archived when the document they are applied to posts, deleted with the draft that owned them, and swept if left orphaned. Reference the returned id from a draft’s tagIds to apply the split.
CreateDimensionRequest
nameDisplay name for the dimension category. Must be unique within your company. Choose a descriptive name that clearly indicates the categorization purpose.
isUniqueWhether only one value from this dimension can be assigned to a journal entry. Set to true for mutually exclusive categories (e.g., Department - an entry belongs to exactly one department). Set to false for additive tags (e.g., Tags - an entry can have multiple tags). This constraint is enforced when assigning dimension values to journal entries.
DimensionResponse
idUnique identifier of the created/updated dimension category
nameDisplay name of the dimension category
isUniqueWhether only one value from this dimension can be assigned per journal entry
UpdateDimensionRequest
nameNew display name for the dimension category. Must be unique within your company. Changing the name does not affect existing dimension value assignments.
isUniqueUpdate the uniqueness constraint for this dimension category. Changing from false to true will fail if any journal entries currently have multiple values assigned from this category. Plan this change carefully as it affects data validation.
CreateDimensionValueRequest
dimensionIdID of the dimension category this value belongs to. The category must exist and belong to your company.
nameDisplay name for the dimension value. Must be unique within the dimension category. Choose descriptive names that will be clear when selecting values in the UI.
parentIdParent dimension value ID for creating hierarchical structures. Leave null or omit for root-level values. The parent must exist within the same dimension category. Example: Create "Europe" first, then create "Denmark" with parentId set to Europe's ID.
DimensionValueResponse
idUnique identifier of the created/updated dimension value
nameDisplay name of the dimension value
dimensionIdID of the dimension category this value belongs to
dimensionNameName of the dimension category this value belongs to
dimensionIsUniqueWhether the parent category enforces single selection
parentIdParent dimension value ID, if this is a nested value
UpdateDimensionValueRequest
nameNew display name for the dimension value. Must be unique within the dimension category. Changing the name does not affect existing journal entry assignments.
parentIdNew parent dimension value ID. Set to null to move to root level. The parent must exist within the same dimension category and cannot create circular references (e.g., A cannot be parent of B if B is already an ancestor of A).
AttachmentRequest
filenameFilename with extension
contentBase64-encoded file content. Note: Base64 encoding adds ~33% overhead. Individual files should not exceed 10MB before encoding.
mimeTypeMIME type of the file
DraftSplitEntryLine
typeTransaction type for this line (debit or credit)
amountAmount for this line (must be non-negative)
accountIdAccount ID for this line (UUID). Optional for drafts — empty lines (type + amount with no account) are persisted as placeholders and must be completed in the platform UI before booking. Cannot be a heading or total account when provided.
vatCodeIdVAT/Tax code ID for this line (UUID)
descriptionOptional per-line memo (max 500 characters). Persisted on the draft line and carried onto the booked ledger transaction when the draft is booked.
tagIdsDimension tag IDs to attach to this specific line. Per-line tagIds MUST come from single-select (dimension) categories — multi-select tags belong at the entry-level tagIds instead.
CreateDraftJournalEntryRequest
accountIdPrimary account ID (UUID). Cannot be a heading or total account. For typed entries (supplier_invoice, customer_invoice, etc.), must have appropriate account classification.
dateDate of the journal entry in YYYY-MM-DD format
amountAmount of the transaction (must be positive)
contraAccountIdContra account ID (UUID). Optional for drafts — partial drafts (primary line only) are allowed and must be completed in the platform UI before booking. Cannot be a heading or total account.
entryTypeEntry type determines the journal type and enforces account classification rules. Account classification requirements: supplier_invoice: account=EXPENSE|ASSET, contraAccount=LIABILITY; supplier_payment: account=LIABILITY, contraAccount=ASSET; customer_invoice: account=ASSET, contraAccount=REVENUE; customer_payment: account=ASSET, contraAccount=ASSET; journal: no restrictions. Legacy values "invoice" and "payment" map to supplier types.
typeTransaction type (debit or credit)
descriptionDescription of the journal entry
referenceReference number or identifier
currency^[A-Za-z]{3}$ISO 4217 alpha-3 currency code.
customerIdCustomer ID (UUID) for customer-related entries
supplierIdSupplier ID (UUID). Required for supplier_invoice / supplier_payment entry types, and for any posting that touches an accounts-payable control account.
tagIdsTag/Dimension IDs to attach to the journal entry
vatCodeIdVAT/Tax code ID (UUID). Applied to the primary account unless split entries are used.
File attachments (base64-encoded). Maximum 10 attachments per entry. Total request size limit is 15MB.
Split entry lines for multi-account drafts. Each line may omit accountId to act as a placeholder; the draft is persisted with NULL on those lines and the user completes them in the platform UI. Booking still requires every line to carry a real account and the entry to balance.
externalSystemIdYour own system's id for this draft. Carried onto the booked journal entry. Not unique — several drafts/entries may share one id. Filter the list endpoint by externalSystemId.
vendorIdDeprecated — use supplierId. Legacy alias for the supplier reference; still accepted, but sending both supplierId and vendorId with different values returns 400.
CreateDraftJournalEntryBatchRequest
Array of draft journal entries to create (1-100 entries per batch)
DraftJournalEntryLine
typeWhich side of the entry this line sits on
accountIdAccount this line posts to. Absent on a placeholder line — one persisted with an amount and a side but no account yet, which must be completed before the draft can be booked.
amountAmount for this line in transaction currency. Absent on a line persisted without one, which must be completed before the draft can be booked — reported as absent rather than as 0, so an unfinished line is never mistaken for a zero-value one.
vatCodeIdVAT/Tax code ID
descriptionPer-line memo
tagIdsTag/Dimension IDs attached to this line. Per-line dimensions override the entry-level tagIds on this specific ledger transaction.
DraftSplitEntryLineResponse
accountIdAccount ID
typeTransaction type (debit or credit)
amountAmount for this line in transaction currency
vatCodeIdVAT/Tax code ID
descriptionPer-line memo
tagIdsTag/Dimension IDs attached to this line. Per-line dimensions override the entry-level tagIds on this specific ledger transaction.
DraftJournalEntryResponse
idDraft journal entry ID
dateDate in YYYY-MM-DD format
amountHow large this draft is, in your company base currency — the one your company reports in. A draft entered as EUR 1,000 by a company reporting in DKK is 7450 here.
Do not display this number together with currency. That field names the currency the draft was entered in (EUR in the example), while this number is in DKK, so the pair reads as EUR 7,450 — about seven times what the draft is actually for. originalAmount is the figure that belongs beside currency.
Reads 0 on a draft that holds no figure in this currency. The minAmount and maxAmount filters on the list endpoint run on this field, so a draft reading 0 here is excluded whenever either filter is applied.
The deprecated v1 create takes a request field of the same name carrying the figure the draft is entered in, so a EUR draft sent as amount: 1000 is returned with amount: 7450 — the request field and this one are in different currencies under one name.
originalAmountHow large this draft is, in the currency it was entered in — the currency currency names, and the one lines[].amount uses. A draft entered as EUR 1,000 is 1000 here, whatever your company reports in.
This is the figure to display beside currency. amount is the same draft in your company base currency: on that EUR draft this field reads 1000 and amount reads 7450. Reads 0 on a draft that carries no amount yet.
currencyThe currency this draft was entered in — EUR for a supplier invoice received in EUR. This is not the currency amount is in; originalAmount is the figure in this currency.
journalTypeJournal type
Every line of the draft — the field to read. Always present, an empty array included, so a client never has to distinguish absent from empty. The name matches the lines the v2 draft endpoints take, so a v2 draft reads back through the field it was written with. The deprecated v1 create still takes splitEntries, so a v1 client sends these lines back under that name.
statusAlways "DRAFT" for draft journal entries
createdAtCreation timestamp
updatedAtLast update timestamp
documentDateDocument date (date on the invoice/voucher). Null when not set.
descriptionDescription
referenceReference number
externalSystemIdYour own system's id for this draft, when set. Not unique. null when unset or cleared.
typeTransaction type (debit or credit)
accountIdPrimary account ID
contraAccountIdContra account ID
customerIdCustomer ID
supplierIdSupplier ID
vatCodeIdVAT/Tax code ID
tagIdsTag/Dimension IDs
documentRefsDocument IDs attached to the draft
exchangeRateWhat one unit of currency is worth in your company base currency. 7.45 on a EUR draft of a company reporting in DKK means 1 EUR buys 7.45 DKK.
This is the rate the draft is converted at, not a factor between the two amounts on this response. amount is built from the draft lines rather than from originalAmount, so multiplying originalAmount by this rate does not reliably reproduce it — on a draft whose sides disagree the two figures differ with no rate involved at all. A draft already entered in your own currency carries 1. Null only while a foreign-currency draft has no rate yet — booking gives it one.
exchangeRateDateDate the exchangeRate was captured for. Null whenever exchangeRate is.
vendorIdDeprecated — use supplierId. Legacy alias, emitted with the same value.
Deprecated — use lines. Present only on drafts that need it: a plain one-debit-one-credit draft with no per-line memo or dimensions reports its accounts through accountId / contraAccountId and omits this field entirely. It also reports a placeholder line's account as "", which the write side rejects. lines is populated either way and round-trips.
CreateDraftJournalEntryBatchResponse
totalCreatedNumber of draft entries successfully created
Details of all created draft journal entries
ListDraftJournalEntriesResponse
List of draft journal entries
totalTotal number of matching drafts
pageCurrent page number
limitItems per page
totalPagesTotal number of pages
JournalEntryLine
accountIdAccount this line posts to
typeWhich side of the entry this line sits on
accountAmountAmount posted to the account, in that account's own currency (accountCurrency). For an account operating in the company base currency this equals functionalAmount.
accountCurrencyThe account's operating currency — the currency accountAmount is denominated in.
functionalAmountAmount posted, converted to the company's base currency. This is the figure to sum when comparing or aggregating across accounts — summing accountAmount across accounts of different currencies would add unlike units.
isVatLineTrue when this line is VAT that the platform derived from another line, rather than a line you posted. Derived VAT lines are included so the lines of an entry balance; vatSourceLineIndex points at the line they came from.
originalAmountThis line's amount in the entry's originalCurrency — the third currency layer, alongside accountAmount (the account currency) and functionalAmount (the company base). On an entry posted in the base currency all three agree. Do not sum this to get the entry total. It is absent on a derived VAT line — the platform computes VAT in base currency and stores no document figure for it — so the sum falls short by the VAT whenever a line is VAT-coded. Use the entry-level originalAmount for the document total, or sum functionalAmount for the base-currency total. Also absent on historical lines that stored no document amount.
vatSourceLineIndexIndex into this same lines array of the line this VAT was derived from. Set only when isVatLine is true, and omitted in the rare case where the source line is not part of this entry.
vatCodeIdVAT/Tax code in effect for this line. A VAT line derived within this entry stores no code of its own — the code belongs to the line it was derived from — so this reports that source line's code. A VAT line derived from a line in a different entry carries its own code and is reported directly. Absent on a line with no VAT.
descriptionPer-line memo, separate from the entry-level description
tagIdsDimension tag IDs attached to this specific line
JournalEntryResponse
idUnique identifier of the created journal entry
entryNumberEntry number assigned to the journal entry
dateDate of the journal entry
amountAmount of the line accountId names, in that line's account currency (currency). On a two-line entry this is the entry total. On a wider entry it is one line of several — sum lines[].functionalAmount on either side for the total.
currencyCurrency amount is denominated in — the operating currency of that first line's account.
journalTypeJournal type
typeTransaction type
statusStatus of the journal entry
accountIdOne non-VAT line of the entry, paired with contraAccountId as a two-line summary. On a two-line entry the pair describes the whole entry. On a wider one it describes two of its lines and nothing about the rest — read lines for the full picture. Which two are picked is not part of this contract and differs by endpoint (a read takes them in posting order; the draft-booking response takes a debit and a credit), so do not infer a line's position from it.
createdAtTimestamp when the entry was created
documentDateDocument date (date on the invoice/voucher). Null for legacy entries.
originalAmountWhat you posted, in the currency you posted it in — the document figure, before any conversion. Distinct from amount, which is denominated in the ACCOUNT currency (currency): a EUR entry against DKK accounts reports originalAmount: 200 / originalCurrency: "EUR" and amount: 1492.24 / currency: "DKK". Null on historical entries that stored no document amount.
originalCurrencyThe currency the entry was posted in: what originalAmount is denominated in, and what exchangeRate converts FROM. Present independently of originalAmount — an entry can name a currency and store no document amount, which is the historical shape, and the currency still says what its rate converts from. Null only on an entry that names no currency at all.
exchangeRateRate converting originalCurrency to the company base currency — 7.45 on a EUR entry of a DKK-based company means 1 EUR = 7.45 DKK, so originalAmount * exchangeRate is the base-currency total that lines[].functionalAmount sums to. Reported whether you supplied it on create or the platform resolved it, which is what lets you compute the difference against the rate your own settlement later used. 1 on an entry posted in the base currency, since that is the conversion that was applied and stored. Null only on historical entries that stored no rate at all.
exchangeRateDateDate the exchangeRate was captured for. Null whenever exchangeRate is.
descriptionDescription of the journal entry
referenceReference number
externalSystemIdYour own system's id for this entry, when set. Not unique — several entries may share one id.
contraAccountIdThe other half of the accountId pair, when the entry has a second non-VAT line. Same caveat: it is one line, not a summary of every line other than accountId.
Every line of the entry, including VAT lines the platform derived. This is the complete picture: accountId, contraAccountId, amount, currency and vatCodeId above all describe one line, or two, and nothing about the rest. Debits and credits balance across the array on functionalAmount. The order is stable for a given entry — normally the order the lines were posted in — but match lines by account rather than by position, and use vatSourceLineIndex to link a VAT line to its source.
customerIdCustomer ID if applicable
supplierIdSupplier ID if applicable
vatCodeIdVAT/Tax code on the line accountId names, if it has one. Lines can carry different codes — read lines[].vatCodeId for the per-line codes.
tagIdsTag IDs attached to the entry as a whole. Per-line dimensions are on lines[].tagIds.
documentRefsDocument IDs attached to the entry
vendorIdDeprecated — use supplierId. Legacy alias, emitted with the same value.
SplitEntryLine
accountIdAccount ID for this line (UUID). Cannot be a heading or total account.
typeTransaction type for this line (debit or credit)
amountAmount for this line (must be non-negative)
vatCodeIdVAT/Tax code ID for this line (UUID)
descriptionOptional per-line memo (max 500 characters). Stored on the booked ledger transaction for this line, separate from the entry-level description.
tagIdsDimension tag IDs to attach to this specific line. Per-line tagIds MUST come from single-select (dimension) categories — multi-select tags belong at the entry-level tagIds instead. Each dimension category may appear at most once per line. The booked ledger transaction is tagged with these IDs and VAT derivatives inherit automatically. Validation: a non-dimension tag rejects with JOURNAL_TAG_LINE_TAG_NOT_A_DIMENSION; a repeated category rejects with JOURNAL_TAG_DUPLICATE_LINE_DIMENSION_CATEGORY.
CreateDraftJournalEntryV2Request
entryTypeJournal type. For CUSTOMER_INVOICE / CUSTOMER_PAYMENT / SUPPLIER_INVOICE / SUPPLIER_PAYMENT the AR/AP leg is appended automatically; do not include it in lines.
datePosting date (YYYY-MM-DD).
originalAmountFace value of the document — what the counterparty is invoiced or pays. NOT the sum of lines. On CUSTOMER_INVOICE / CUSTOMER_PAYMENT / SUPPLIER_INVOICE / SUPPLIER_PAYMENT this value IS the appended AR/AP leg (its absolute value), so an account that appears on both sides of the entry — a clearing or pass-through account — must not be counted into it. Sign carries direction: positive = invoice / payment, negative = credit-note / refund.
Counter-side lines (revenue / expense / bank / outlay). For locked types do NOT include the AR/AP leg. The cap is per ENTRY, not per request or per journal category — nothing accumulates across entries, so a company with many unposted drafts is never refused for that reason.
customerIdCustomer reference. Required for CUSTOMER_* types.
supplierIdSupplier reference. Required for SUPPLIER_* types.
descriptionOptional human-readable description.
referenceInvoice number / external reference.
externalSystemIdYour own system's id for this draft. Carried onto the booked journal entry. Not unique — several drafts/entries may share one id. Filter the list endpoint by externalSystemId.
currency^[A-Za-z]{3}$ISO 4217 alpha-3 currency code.
exchangeRateExchange rate from currency to the company base currency, e.g. 7.4612 for EUR to DKK. Must be greater than zero; a non-positive rate is rejected whatever the entry currency, so the same body is accepted or refused identically for every tenant. Omit the field to have the rate resolved from the rate feed at the posting date — supplying one lets an integrator that already converted the amount itself post both legs of a settlement against the same rate. Not applied when the entry is already denominated in the company base currency, where the conversion is the identity.
tagIdsTag IDs applied at the entry level.
journalCategoryIdJournal category ID (UUID). Must belong to the API key's app company; cross-tenant or unknown IDs are rejected with 400 JOURNAL_CATEGORY_NOT_FOUND. When omitted the entry uses the company's default category.
Inline file attachments (base64-encoded). Same shape and limits as v1: maximum 10 attachments per entry, a 10MB ceiling on each file measured AFTER base64 decoding (over it is rejected with DOCUMENT_UPLOAD_FILE_TOO_LARGE), and a 15MB ceiling on the total request body (JSON + base64 payload). Either can be the binding one: base64 inflates a payload by about a third, so two 6MB files each clear the per-file bound and exceed the request one. Each attachment becomes a Document linked to the created journal entry — equivalent to what GET /api/v1/journal-entries/:id/attachments returns. An invalid MIME type rejects at DTO validation with 400 SHARED_VALIDATION_FAILED; malformed base64 reaches the service and rejects with 400 JOURNAL_ENTRY_INVALID_ATTACHMENT_TYPE. Either rejects the whole entry, and in a batch the whole batch rolls back.
vendorIdDeprecated — use supplierId. Legacy alias; sending both with different values returns 400.
CreateDraftJournalEntryV2BatchRequest
Array of 1–100 draft journal entries, carrying at most 10000 lines in total across the batch. Wrapped in a single transaction; one bad entry rolls back the whole batch.
CreateDraftJournalEntryV2BatchResponse
totalCreatedNumber of drafts created (= entries.length on success).
Created draft journal entries, ordered to match the request entries[].
UpdateDraftJournalEntryV2Request
datePosting date (YYYY-MM-DD).
originalAmountFace value of the document — what the counterparty is invoiced or pays. NOT the sum of lines. On CUSTOMER_INVOICE / CUSTOMER_PAYMENT / SUPPLIER_INVOICE / SUPPLIER_PAYMENT this value IS the appended AR/AP leg (its absolute value), so an account that appears on both sides of the entry — a clearing or pass-through account — must not be counted into it. Sign carries direction: positive = invoice / payment, negative = credit-note / refund.
customerIdCustomer reference. null clears it; omitting keeps it. Changing it reshapes the entry — requires lines and re-runs the per-entryType validation (CUSTOMER_* types cannot clear their counterparty).
supplierIdSupplier reference. null clears it; omitting keeps it. Changing it reshapes the entry — requires lines and re-runs the per-entryType validation (SUPPLIER_* types cannot clear their counterparty).
descriptionOptional human-readable description.
referenceInvoice number / external reference.
externalSystemIdYour own system's id. null clears the value; omitting the field keeps it.
currency^[A-Za-z]{3}$ISO 4217 alpha-3 currency code.
exchangeRateExchange rate from currency to the company base currency, e.g. 7.4612 for EUR to DKK. Must be greater than zero; a non-positive rate is rejected whatever the entry currency, so the same body is accepted or refused identically for every tenant. Omit the field to have the rate resolved from the rate feed at the posting date — supplying one lets an integrator that already converted the amount itself post both legs of a settlement against the same rate. Not applied when the entry is already denominated in the company base currency, where the conversion is the identity.
Counter-side lines (revenue / expense / bank / outlay). For locked types do NOT include the AR/AP leg. The cap is per ENTRY, not per request or per journal category — nothing accumulates across entries, so a company with many unposted drafts is never refused for that reason.
tagIdsTag IDs applied at the entry level.
journalCategoryIdJournal category ID (UUID). Must belong to the API key's app company; cross-tenant or unknown IDs are rejected with 400 JOURNAL_CATEGORY_NOT_FOUND. When omitted the entry uses the company's default category.
vendorIdDeprecated — use supplierId. Legacy alias for the supplier reference (null clears it); sending both supplierId and vendorId with different values returns 400.
UpdateJournalEntryRequest
referenceCorrected reference. For invoices this is the invoice number (the anchor is renumbered with it); for payments it is the invoice number the payment settles. Only unmatched entries of the four entity document types accept a reference correction.
externalSystemIdYour own system's id for this journal entry. Settable on any journal type regardless of match state. Not unique — several entries may carry the same id (e.g. one partner document booked as several entries); filter GET /journal-entries by externalSystemId to find all of them. null clears the value; omitting the field keeps it. reference does not accept null — it is a matching key, not clearable metadata.
UpdateJournalEntryResponse
idJournal entry ID.
referenceThe reference after the update.
externalSystemIdThe external system id after the update.
ReverseJournalEntryRequest
journalEntryIdUUID of the posted journal entry to reverse.
reversalDateDate for the reversal posting (YYYY-MM-DD). When omitted, the reversal is dated to the original entry so it lands in the same period. Must fall in an open posting period.
reasonFree-text reason appended to the reversal description for audit purposes.
ReverseJournalEntryResponse
reversalIdUnique identifier of the posted reversal journal entry.
BatchReverseJournalEntriesRequest
journalEntryIdsIDs of the journal entries to reverse (1–100). All reversals run in one transaction; one failure rolls back the whole batch. Duplicate IDs are de-duplicated.
reversalDateDate for every reversal posting (YYYY-MM-DD). When omitted, each reversal is dated to its own original entry so the pair lands in the same period.
reasonFree-text reason appended to every reversal description for audit purposes.
BatchReverseJournalEntriesResultItem
originalIdOriginal journal entry ID supplied in the request.
reversalIdUnique identifier of the posted reversal journal entry.
BatchReverseJournalEntriesResponse
totalReversedNumber of reversals posted. Equals the count of unique IDs in the request on success.
Result rows pairing each original ID with its newly created reversal ID.
ReclassifyJournalEntryLine
ledgerTransactionIdUUID of the ledger transaction (posting line) to move. Read these from GET /api/v1/journal-entries/{id}.
newAccountIdUUID of the ledger account the line should be posted to instead.
newVatCodeIdUUID of the VAT code to apply to the line. Omit to keep the line's current code; pass null to remove VAT from the line. Changing it re-splits the line's gross amount, so the net posted to the account moves.
PreviewJournalEntryCorrectionRequest
correctionTypeWhich correction to preview.
correctionDate^\d{4}-\d{2}-\d{2}$Date the correction posts on (YYYY-MM-DD). When omitted, the correction is dated to the original entry so the pair lands in the same period. Must fall in an open posting period.
reasonFree-text reason appended to the correction description for audit purposes.
Line changes to preview (max 100). Required for reclassify, ignored by the other two types.
JournalEntryCorrectionPreviewLine
accountNumberAccount number the line posts to.
accountNameAccount name.
amountLine amount, in the currency named by currency.
typeWhich side of the entry the line sits on.
currencyThe line's currency - its ledger account's own.
vatCodeNameVAT code applied to the line, when it carries one.
isChangedTrue when this line differs from the original entry. Only set on a reclassification preview.
isVatTransactionTrue when the line is a VAT leg generated from another line.
JournalEntryCorrectionPreviewEnteredAs
amountThe amount as originally keyed.
currencyThe currency it was keyed in.
exchangeRateThe rate it was converted at.
JournalEntryCorrectionPreviewEntry
descriptionDescription the entry would carry.
dateDate the entry would post on (YYYY-MM-DD).
entryTypeWhich entry of the correction this is.
isDraftTrue when this entry would be created as a draft rather than posted.
The postings the entry would carry.
totalDebitSum of the debit lines, in totalCurrency.
totalCreditSum of the credit lines, in totalCurrency.
totalCurrencyThe currency the two totals are stated in. Each line carries its own account's currency, so the totals are summed in the company's base currency and this names it - never read the currency off a line.
What the operator originally keyed, when that differs from the currency the lines are shown in. Display only.
JournalEntryCorrectionPreviewResponse
The reversal that would neutralise the original.
The entry as it stands today, for comparison. Present on a reclassification preview.
The replacement entry. Absent for reverseOnly, which posts no replacement.
ReverseAndCorrectJournalEntryRequest
correctionDate^\d{4}-\d{2}-\d{2}$Date the correction posts on (YYYY-MM-DD). When omitted, the correction is dated to the original entry so the pair lands in the same period. Must fall in an open posting period.
reasonFree-text reason appended to the correction description for audit purposes.
ReverseAndCorrectJournalEntryResponse
reversalIdUnique identifier of the posted reversal journal entry.
draftIdUnique identifier of the unlocked DRAFT holding the replacement entry. Nothing is posted from it until the draft is booked - edit it via the drafts endpoints, then book it.
ReclassifyJournalEntryRequest
The lines to move (1-100). Lines not listed are copied to the replacement entry unchanged.
correctionDate^\d{4}-\d{2}-\d{2}$Date the correction posts on (YYYY-MM-DD). When omitted, the correction is dated to the original entry so the pair lands in the same period. Must fall in an open posting period.
reasonFree-text reason appended to the correction description for audit purposes.
ReclassifyJournalEntryResponse
reversalIdUnique identifier of the posted reversal of the original entry.
newEntryIdUnique identifier of the posted replacement entry carrying the new account and VAT coding.
ListJournalEntriesResponse
List of journal entries
totalTotal number of matching entries
pageCurrent page number
limitNumber of items per page
totalPagesTotal number of pages
JournalEntryAttachmentResponse
idUnique identifier of the attachment/document
filenameOriginal filename of the attachment
contentTypeMIME type of the attachment
fileSizeFile size in bytes
contentBase64-encoded file content
createdAtTimestamp when the attachment was created
JournalEntryAttachmentsListResponse
journalEntryIdJournal entry ID the attachments belong to
List of attachments
CreateJournalEntryV2Dto
entryTypeJournal type. For CUSTOMER_INVOICE / CUSTOMER_PAYMENT / SUPPLIER_INVOICE / SUPPLIER_PAYMENT the AR/AP leg is appended automatically; do not include it in lines.
datePosting date (YYYY-MM-DD).
originalAmountFace value of the document — what the counterparty is invoiced or pays. NOT the sum of lines. On CUSTOMER_INVOICE / CUSTOMER_PAYMENT / SUPPLIER_INVOICE / SUPPLIER_PAYMENT this value IS the appended AR/AP leg (its absolute value), so an account that appears on both sides of the entry — a clearing or pass-through account — must not be counted into it. Sign carries direction: positive = invoice / payment, negative = credit-note / refund.
Counter-side lines (revenue / expense / bank / outlay). For locked types do NOT include the AR/AP leg. The cap is per ENTRY, not per request or per journal category — nothing accumulates across entries, so a company with many unposted drafts is never refused for that reason.
customerIdCustomer reference. Required for CUSTOMER_* types.
supplierIdSupplier reference. Required for SUPPLIER_* types.
descriptionOptional human-readable description.
referenceInvoice number / external reference.
externalSystemIdYour own system's id for this entry. Leading and trailing whitespace is trimmed before storage, and a value that is only whitespace is stored as no id at all — the list filter trims what it is given too, so an untrimmed value would be stored under an id no lookup could match. It is a lookup key, not a deduplication key: LedgerBee enforces no uniqueness on it and never compares it between requests, so several entries may carry the same id and repeating a request creates another entry. Filter GET /journal-entries by externalSystemId to find what an earlier run posted. For retries that must not post twice, send x-api-idempotency-key.
currency^[A-Za-z]{3}$ISO 4217 alpha-3 currency code.
exchangeRateExchange rate from currency to the company base currency, e.g. 7.4612 for EUR to DKK. Must be greater than zero; a non-positive rate is rejected whatever the entry currency, so the same body is accepted or refused identically for every tenant. Omit the field to have the rate resolved from the rate feed at the posting date — supplying one lets an integrator that already converted the amount itself post both legs of a settlement against the same rate. Not applied when the entry is already denominated in the company base currency, where the conversion is the identity.
tagIdsTag IDs applied at the entry level.
journalCategoryIdJournal category ID (UUID). Must belong to the API key's app company; cross-tenant or unknown IDs are rejected with 400 JOURNAL_CATEGORY_NOT_FOUND. When omitted the entry uses the company's default category.
Inline file attachments (base64-encoded). Same shape and limits as v1: maximum 10 attachments per entry, a 10MB ceiling on each file measured AFTER base64 decoding (over it is rejected with DOCUMENT_UPLOAD_FILE_TOO_LARGE), and a 15MB ceiling on the total request body (JSON + base64 payload). Either can be the binding one: base64 inflates a payload by about a third, so two 6MB files each clear the per-file bound and exceed the request one. Each attachment becomes a Document linked to the created journal entry — equivalent to what GET /api/v1/journal-entries/:id/attachments returns. An invalid MIME type rejects at DTO validation with 400 SHARED_VALIDATION_FAILED; malformed base64 reaches the service and rejects with 400 JOURNAL_ENTRY_INVALID_ATTACHMENT_TYPE. Either rejects the whole entry, and in a batch the whole batch rolls back.
vendorIdDeprecated — use supplierId. Legacy alias; sending both with different values returns 400.
CreateJournalEntryV2BatchRequest
Array of 1–100 journal entries, carrying at most 10000 lines in total across the batch. Wrapped in a single transaction; one bad entry rolls back the whole batch.
CreateJournalEntryV2BatchResponse
totalCreatedNumber of journal entries created (= entries.length on success).
Created journal entries, ordered to match the request entries[].
JournalCategoryResponse
idThe unique identifier of the journal category
nameName of the journal category
isDefaultWhether this is the default journal category
allowedJournalTypesJournal entry types that may be posted into this category. A category created without an explicit list carries all eleven. See the endpoint description for what each value means.
CreateJournalCategoryRequest
nameName of the journal category. Must be unique within your company.
allowedJournalTypesJournal entry types that may be posted into this category. Posting an entry of a type not listed here is rejected. Omit this field to allow every type — the same set a company’s first category is created with. An empty array is rejected: it would describe a category nothing could ever be posted into. See the endpoint description for what each value means and which entryType reaches it. Send the field or leave it out — an explicit null is rejected.
isDefaultMake this the default category. Your company always has exactly one default, so passing true moves the flag off the category that currently holds it. Defaults to false.
UpdateJournalCategoryRequest
nameNew name for the journal category. Must be unique within your company.
allowedJournalTypesReplaces the set of journal entry types that may be posted into this category. The list cannot be empty, and omitting the field here leaves the current set unchanged (unlike on create, where omitting it means every type). Entries already posted are unaffected.
isDefaultPass true to make this the default category, which moves the flag off the category that currently holds it. Passing false is only accepted when another category is already the default — to move the default, mark its successor rather than clearing the incumbent.
MeterSubscriptionProductDTO
idProduct ID
nameProduct name
productNumberProduct number
MeterSubscriptionDTO
idSubscription ID
nameSubscription name
statusSubscription status
Products in this subscription that use the meter
MeterSubscriptionsResponseDTO
meterIdMeter ID
meterNameMeter name
Subscriptions with products using this meter
PaymentMethodResponse
idUnique identifier of the payment method
customerIdCustomer ID this payment method belongs to
providerPayment provider
labelHuman-readable label for the payment method
isDefaultWhether this is the default payment method for the customer
statusCurrent status of the payment method
createdAtWhen the payment method was created
cardMaskMasked card number
cardTypeCard type as reported by the provider
expiryMonthCard expiry month
expiryYearCard expiry year
CreateCardSaveLinkRequest
providerPayment provider to use for saving the card
PaymentLinkResponse
urlURL to the payment provider window. Send this to your customer.
expiresAtWhen the payment link expires
PublicSubscriptionPlanPhaseProduct
priceIdPrice ID of the product
quantityQuantity for the product
customPriceCustom unit price override
PublicSubscriptionPlanIntervalDiscount
billingIntervalBilling interval the discount applies to
billingIntervalCountBilling interval count (e.g. 1 = monthly, 6 = every 6 months)
discountTypeDiscount type: flat (subtract amount) or period_total (set the period’s target total)
valueDiscount value (NET, excluding VAT)
descriptionOptional description shown on the invoice
PublicSubscriptionPlanPhase
idPhase ID
sequenceSequence order of the phase (1-based)
discountTypeType of discount applied during the phase
Products for this phase
namePhase name
discountValueDiscount value for the phase
durationValuePhase duration value
durationUnitPhase duration unit
Per-billing-interval (period) discounts configured for this phase
PublicSubscriptionPlanResponse
idSubscription plan ID
nameSubscription plan name
isActiveWhether the subscription plan is active
currencyCurrency code (ISO 4217)
defaultBillingDirectionDefault billing direction for new customer subscriptions
Phases configured for this plan
createdAtDate the plan was created
updatedAtDate the plan was last updated
descriptionSubscription plan description
PublicListSubscriptionPlansResponse
List of subscription plans
totalTotal number of subscription plans matching the query
pageCurrent page number (1-indexed)
limitMaximum number of items per page
totalPagesTotal number of pages available
PublicCreateSubscriptionPlanPhaseProduct
priceIdPrice ID of an existing product price to include in this phase
quantityQuantity for the product (defaults to 1)
customPriceCustom unit price override for this line (defaults to the price’s own amount)
PublicCreateSubscriptionPlanIntervalDiscount
billingIntervalBilling interval the discount applies to
billingIntervalCountBilling interval count (e.g. 1 = monthly, 6 = every 6 months)
discountTypeDiscount type: flat (subtract amount) or period_total (set the period’s target total)
valueDiscount value (NET, excluding VAT). For flat: amount to subtract; for period_total: the target total.
descriptionOptional description shown on the invoice
PublicCreateSubscriptionPlanPhase
Products included in this phase. At least one is required.
nameDisplay name for the phase
discountTypeType of discount applied across the whole phase. Defaults to none when omitted or null.
discountValueDiscount value for the phase. Percentage (0-100), fixed amount, or total target depending on discountType.
Per-billing-interval (period) discounts. Use these to discount specific cadences (e.g. a flat amount off the yearly price) independently of the phase-level discount. At most one discount per period type (billing interval + count), and each must target a period type a product in this phase bills at — so the count is bounded by the phase’s distinct product period types.
durationValueLength of the phase. Omit on the last phase to leave it open-ended.
durationUnitUnit for the phase duration
PublicCreateSubscriptionPlanRequest
nameSubscription plan name. Must be unique within your company.
Phases defining the plan’s billing structure. At least one phase is required.
descriptionSubscription plan description
currencyCurrency code (ISO 4217). Omit to bill in the company's own base currency.
defaultBillingDirectionDefault billing direction applied to new customer subscriptions created from this plan
PublicCancelSubscriptionRequest
idCustomer subscription ID to cancel
strategyCancellation strategy
effectiveDateEffective churn date (ISO 8601). Required when strategy is SPECIFIC_DATE.
refundBehaviorRefund behavior when canceling immediately
cancellationReasonOptional reason for cancelling the subscription
EntitlementRef
idEntitlement ID
nameEntitlement name
keyStable integration key
PublicCustomerSubscriptionResponse
idCustomer subscription ID
customerIdCustomer ID
customerNameCustomer name
subscriptionNameSubscription name
startDateStart date (ISO 8601)
statusStatus of the customer subscription
currencyCurrency code (ISO 4217)
billingDirectionBilling direction: ADVANCE bills at period start, ARREARS at period end
effectiveBillingDirectionEffective billing direction for the current period. Can differ from billingDirection if the direction was changed mid-period.
Entitlements currently granted by the subscription
planIdSubscription plan ID (null for ad-hoc subscriptions)
endDateEnd date (ISO 8601)
scheduledChurnDateScheduled churn date (ISO 8601)
trialDaysNumber of trial days granted
cancellationReasonReason provided when the subscription was cancelled
effectiveNextBillingDateThe date the NEXT invoice will be created (ISO 8601). This is an invoicing schedule marker, not a payment marker — it does not say what the customer has paid for; see paidThroughDate.
paidThroughDateThe date the subscription is paid through (ISO 8601): the first day not yet paid for. It is the end of the contiguous run of settled service periods starting at the earliest billed period, so an unpaid period caps it rather than being skipped. Null when the earliest billed period is not settled (or nothing is billed yet). Payment timing never shifts this backwards: a late payment settles exactly the period its invoice stated.
commitmentEndDateEnd date of the customer commitment period (ISO 8601)
originalStartDateOriginal start date from source system for migrated subscriptions (ISO 8601)
paymentMethodIdAssigned payment method ID
automaticBillingWhether automatic billing is enabled
partnerReferenceIdYour reconciliation reference (the clientReferenceId you passed at embedded-checkout bind time), echoed back so you can match this subscription to your order. Null for any subscription not created through a partner-bound checkout.
billingGroupIdThe billing group this subscription bills on, or null when it bills on its own. A grouped subscription is charged on the group’s card, so its own paymentMethodId is null and automaticBilling is false. A subscription that has joined a group but not yet reached its first shared billing date already reports the group.
PublicCustomerSubscriptionListItem
idCustomer subscription ID
customerIdCustomer ID
customerNameCustomer name
subscriptionNameSubscription plan name
statusStatus of the customer subscription
startDateStart date (ISO 8601)
currencyCurrency code (ISO 4217)
customerNumberCustomer number
planIdSubscription plan ID (null for ad-hoc subscriptions)
effectiveNextBillingDateThe date the NEXT invoice will be created (ISO 8601). This is an invoicing schedule marker, not a payment marker — it does not say what the customer has paid for; see paidThroughDate.
paidThroughDateThe date the subscription is paid through (ISO 8601): the first day not yet paid for. It is the end of the contiguous run of settled service periods starting at the earliest billed period, so an unpaid period caps it rather than being skipped. Null when the earliest billed period is not settled (or nothing is billed yet). Payment timing never shifts this backwards: a late payment settles exactly the period its invoice stated.
partnerReferenceIdYour reconciliation reference (the clientReferenceId you passed at embedded-checkout bind time), echoed back so you can match this subscription to your order. Null for any subscription not created through a partner-bound checkout. Filter the list by partnerReferenceId to recover a missed webhook.
billingGroupIdThe billing group this subscription bills on, or null when it bills on its own. A subscription that has joined a group but not yet reached its first shared billing date already reports the group.
PublicListCustomerSubscriptionsResponse
List of customer subscriptions
totalTotal number of customer subscriptions matching the query
pageCurrent page number (1-indexed)
limitMaximum number of items per page
totalPagesTotal number of pages available
PublicAssignSubscriptionProductOverride
priceIdPrice ID of the product to override
quantityQuantity to assign (overrides the plan template quantity). Not valid on usage-metered prices. Omit when the override only carries prepaid-commitment settings.
committedQuantityPrepaid usage commitment: quantity billed up front each period (usage-metered prices on advance billing only). Actual consumption is trued up at period end. Null = no commitment; 0 is a valid zero commitment.
usageCarryoverModeHow the next period derives its committed quantity from the settled period: reset (authored quantity), track_actual (last actual), ratchet_up (grow only), ratchet_down (shrink only). Null reads as reset.
underageModeWhat happens to underage (actual below committed) at settlement: forfeit (kept) or refund (credited). Null reads as forfeit.
minimumCommittedQuantityFloor for downward carryover (0 <= floor <= committedQuantity). Null = no floor.
committedUnitPriceFlat per-unit price for the committed units, replacing the price tier ladder on the commitment line only. Consumption above the commitment still walks the ladder, starting from the step the committed quantity occupies. Requires reset carryover + forfeit underage. Null = ladder-priced; 0 is a valid free commitment.
discardPreAssignmentUsageDon't bill usage events dated before this assignment for this subscription (usage-metered prices only; other subscriptions on the same meter still bill them). Persists a per-price usage window floor at the assignment date.
PublicAssignSubscriptionRequest
customerIdCustomer ID to assign the subscription to
planIdSubscription plan ID
startDateStart date (ISO 8601)
endDateEnd date (ISO 8601)
billingCycleAnchorBilling cycle anchor date (ISO 8601). When the billing cycle should align to. Defaults to startDate if not provided.
prorationBehaviorHow to handle proration from startDate to billingCycleAnchor
trialDaysTrial period in days
billingDirectionBilling direction for this subscription
customerDepartmentIdCustomer department ID for invoice delivery
departmentContactOverrideIdContact override ID for department invoice delivery
Optional quantity overrides for products in the plan
automaticBillingWhether to enable automatic billing
collectViaLeverandorserviceCollect each billing cycle via Leverandørservice (Danish direct debit) instead of a card charge. DKK-only. Requires the tenant to hold the Leverandørservice license, a configured creditor number, and a registered mandate for the customer.
joinBillingGroupIdCreate the subscription straight onto this billing group of the same customer. The group replaces billingCycleAnchor with its own billing date, and the assignment and the join commit together, so a refused join creates no subscription. startDate and prorationBehavior still decide the period up to the group's date. Cannot be combined with formBillingGroupWithSubscriptionId.
formBillingGroupWithSubscriptionIdCreate the subscription and form a NEW billing group with this existing subscription of the same customer as the lead: the lead's next billing date replaces billingCycleAnchor, and its terms are written onto the new subscription. The assignment and the formation commit together. Cannot be combined with joinBillingGroupId.
paymentMethodIdDeprecated and non-functional. Cards are attached by the buyer with their consent (card-save link / portal checkout); any value here is rejected. Field retained only so the request is validated cleanly.
PublicScheduledChange
changeIdIdentifier of this queued change. Ephemeral — valid only until the change activates or is cancelled, so re-fetch rather than caching it.
kindThe kind of queued change: one of replace_plan, edit_products, change_direction, or churn.
effectiveDateThe date (YYYY-MM-DD) the change takes effect.
planIdThe plan the subscription moves to when the change activates (null for ad-hoc / non-plan changes).
subscriptionNameThe plan name the change moves to.
PublicRetryPaymentResponseDTO
statusAlways "succeeded" — a failed retry returns a coded error instead.
subscriptionIdThe stable subscription id the retry ran against.
invoiceIdId of the outstanding invoice the cleared charge paid.
PublicUpdateSubscriptionRequest
paymentMethodIdThe card linked to the subscription. Send null to remove it. You may also echo back the card already linked (a no-op, so a full-object round-trip works), but you cannot attach or change to a different card - cards are attached by the buyer with their consent, so any value other than the currently-linked card or null is rejected with a 400.
automaticBillingWhether to automatically charge the saved card during billing
PublicBillingGroupEligibilityRequest
modeform asks whether leadSubscriptionId and memberSubscriptionIds could form a group; join asks whether subscriptionIds could join billingGroupId.
leadSubscriptionIdform: the subscription whose terms the group would take.
memberSubscriptionIdsform: the subscriptions that would join, 0 to 19. Omitted or empty asks whether the lead could lead a group at all.
billingGroupIdjoin: the group to join.
subscriptionIdsjoin: the subscriptions that would join, 1 to 19.
PublicBillingGroupRefusal
codeThe error code the write would answer with.
subscriptionIdThe subscription the refusal is about, or null for a refusal about the whole set (the member limit, a dissolved group).
PublicBillingGroupEligibilityResponse
eligibleTrue when the write would be accepted today.
Every refusal, at most one per subscription plus at most one about the set. Empty when eligible. A subscription refused for two reasons reports the first; the second appears once the first is fixed.
PublicFormBillingGroupRequest
leadSubscriptionIdThe subscription whose terms the group takes: its next billing date becomes the group's billing date, and its payment terms, invoice delivery and send offset are written onto every member. Not repeated in memberSubscriptionIds.
memberSubscriptionIdsThe other subscriptions of the same customer that join the group: 1 to 19, distinct, none already in a group. A group holds at most 20 members including the lead.
invoiceTemplateIdA consolidated document template for the shared invoice. Omitted or null uses the customer's, then your default.
includeMemberDetailsPdfAttach a zip with one detail document per member to each send. Defaults to false.
PublicBillingGroupMemberRef
subscriptionIdThe subscription, by its stable id.
PublicFormBillingGroupResponse
billingGroupIdThe new group.
billingActiveFromThe day the set starts billing together (YYYY-MM-DD).
leadSubscriptionIdThe subscription whose terms the group took, echoed from the request.
Every member, the lead included.
PublicBillingGroupMember
subscriptionIdThe member subscription — the same stable id every subscription endpoint takes.
subscriptionNameThe subscription's current name.
billingActiveFromThe day this member starts billing on the group's shared invoice (YYYY-MM-DD). Ahead of today for a member that has joined and still bills on its own until then.
monthlyRevenueThe member's own monthly recurring revenue, as a decimal string. The group has no revenue of its own; sum the members.
currencyCurrency code (ISO 4217). Every member of a group shares one.
effectiveNextBillingDateThe member's next billing date (YYYY-MM-DD), or null when it no longer bills.
PublicBillingGroup
idBilling group id
customerIdThe one customer every member belongs to.
billingActiveFromThe day the group started, or starts, billing as a set (YYYY-MM-DD).
chargesByCardTrue when the next shared invoice is charged to the group's card rather than sent for bank payment. The card is the group's; members hold none of their own.
includeMemberDetailsPdfWhether each send also attaches a zip with one detail document per member.
The current members, ordered by the day they start billing on the group and then by id. Empty once the group has dissolved.
dissolvedAtWhen the group dissolved (ISO 8601), or null while it bills as a set. A dissolved group keeps answering here because the invoices it issued still name it.
invoiceTemplateIdThe consolidated document template the shared invoice renders from, or null to use the customer's, then your default.
PublicAddBillingGroupMembersRequest
subscriptionIdsSubscriptions of the group's customer that join it: 1 to 19, distinct, none already in a group. The group's billing date does not move; each joiner is moved onto it.
PublicAddBillingGroupMembersResponse
billingGroupIdThe group joined.
billingActiveFromThe day the joiners start billing on the group's invoice (YYYY-MM-DD).
The subscriptions that joined.
PublicRemoveBillingGroupMemberResponse
billingGroupIdThe group the subscription left.
subscriptionIdThe subscription that left, by its stable id.
groupDissolvedTrue when this departure left fewer than two members and the whole group dissolved: the remaining member bills on its own from its next billing date.
CheckoutReadinessStripeConnect
connectedWhether an active Stripe Connect account backs the card rail.
statusThe connected account’s status, when one exists.
settlementCurrencySettlement currency of the connected account.
allowCrossCurrencyChargesWhether cross-currency charges are enabled on your Stripe account.
chargeableCurrenciesCatalogue currencies that pass the charge predicate — a card step offered in any other currency would be refused.
CheckoutReadinessResponse
subscriptionLicenseWhether you hold the Subscription license — without it nothing is checkoutable.
publishedPlansNumber of published plans.
checkoutablePlansNumber of published plans with a sellable item — checkoutable on this surface.
generalTermsPublishedInformational, 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.
embeddableOriginsThe configured embeddableOrigins allowlist — required for HOSTED card windows’ returnUrl.
CheckoutQuantitySelection
priceIdThe snapshot price id the quantity applies to.
quantityThe buyer-chosen quantity. Clamped to the card’s quantity rules server-side.
CheckoutQuoteRequest
planVersionIdThe plan version to quote (from the catalogue).
planItemIdThe pricing-card item on that version.
countryBuyer country, ISO 3166-1 alpha-2 — REQUIRED so VAT resolves exactly.
customerTypeWhether the buyer is a business or a private person.
vatNumberThe buyer’s VAT number (BUSINESS only — refused otherwise).
startDateRequested start date (YYYY-MM-DD). Defaults to today; never in the past.
currencyPresentment currency (ISO 4217). Must be in the card’s availableCurrencies; refused with PORTAL_CHECKOUT_CURRENCY_NOT_AVAILABLE otherwise. Absent → the card’s own currency.
Buyer-chosen quantities for quantity-bearing products.
languageLanguage for display texts, terms and the disclosure.
CheckoutQuoteResponse
quoteFirst-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.
firstPeriodChargeableFalse 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").
CheckoutBuyer
customerTypeWhether the buyer is a business or a private person.
nameCompany name (BUSINESS) or the person’s full name (PRIVATE_PERSON).
emailThe buyer’s identity email: consent evidence is recorded against it and the self-service manage link is sent to it.
customerGroupIdREQUIRED: one of your customer groups, for classifying the created customer. Discover valid groups via GET /v1/customers/groups. Unknown ids are refused with PORTAL_CHECKOUT_CUSTOMER_GROUP_INVALID.
countryBuyer country, ISO 3166-1 alpha-2 — drives VAT resolution.
vatNumberThe buyer’s VAT number (BUSINESS only — refused otherwise). Checked against the country’s published format; registry (VIES) verification is not performed.
addressBilling address line.
postalCodeBilling postal code.
cityBilling city.
billingEmailWhere invoices, receipts and payment notices are sent when it differs from the buyer’s identity email. Absent → the identity email receives them.
existingCustomerIdAn EXISTING customer this purchase belongs to, so a returning buyer keeps one record instead of accumulating duplicates. Reuse is authorized at confirm: the buyer’s email must already hold the customer (or nobody may).
CheckoutSessionRequest
planVersionIdThe plan version to check out (from the catalogue).
planItemIdThe pricing-card item on that version.
The buyer — plain request data; no tokens, no ceremony.
startDateRequested start date (YYYY-MM-DD). Defaults to today; never in the past.
currencyPresentment currency (ISO 4217); must be in the card’s availableCurrencies.
Buyer-chosen quantities.
expiresInMinutesSession TTL in minutes. Default 30.
referenceYour own order/cart id (Stripe client_reference_id parity) — echoed on session reads, the confirm response and every checkout.* webhook payload.
languageLanguage for display texts, terms and the disclosure.
CheckoutPinned
currencyPinned presentment currency (ISO 4217).
netMajorPinned first-period net, in major units.
totalGrossMajorPinned first-period total (gross where VAT resolved), in major units. Confirm re-runs the billing engine against the pinned inputs and refuses a different output with PORTAL_CHECKOUT_AUTHORIZED_AMOUNT_CHANGED.
startDatePinned start date (YYYY-MM-DD).
disclosureVersionPinned recurring-billing disclosure version.
disclosureTextThe server-rendered recurring-billing disclosure text for the pinned version — render it (or your own equivalent) before the buyer accepts recurring billing.
acceptedTermsVersionIdsThe terms version ids pinned at mint. Acceptance evidence is written against exactly these; a terms republish mid-session makes confirm refuse with a 410 — re-mint the session.
expiresInMinutesThe session TTL that was applied, in minutes.
CheckoutSessionResponse
sessionIdThe opaque session id — your handle for every later call.
expiresAtWhen the session expires (ISO 8601). Expired sessions answer 410.
referenceYour reference, echoed.
quoteThe same first-period quote payload POST /v1/checkout/quote returns.
What the session pinned — render exactly this.
firstPeriodChargeableFalse when the pinned first period nets to zero (save-only card window).
CheckoutSessionView
sessionIdThe opaque session id.
expiresAtWhen the session expires (ISO 8601).
referenceYour reference, echoed.
planVersionIdThe pinned plan version.
planItemIdThe pinned pricing-card item.
buyerThe buyer payload the session was minted with.
firstPeriodChargeableFalse when the pinned first period nets to zero.
cardWindowOpenedWhether a card window has been opened on this session.
CheckoutCardWindowRequest
uiModeHow 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.
returnUrlWhere 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.
CheckoutCardWindowResponse
modeSTRIPE_EMBEDDED → mount with clientSecret; REDIRECT → navigate the buyer to redirectUrl.
handoffTokenThe 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.
expiresAtWhen the provider window expires (ISO 8601).
clientSecretStripe embedded Checkout client secret (STRIPE_EMBEDDED only).
publishableKeyPublishable key for Stripe.js (STRIPE_EMBEDDED only).
stripeAccountIdThe connected Stripe account id for Stripe.js (STRIPE_EMBEDDED only).
redirectUrlThe hosted window URL to send the buyer to (REDIRECT only).
CheckoutCardDisplay
labelReady-to-render label.
cardTypeCard network/brand, if known.
cardMaskMasked card number, if known.
accountIdentifierMasked identifier for non-card methods (e.g. a Link email).
CheckoutCardStatusResponse
statusPENDING: keep polling (or listen for checkout.card_ready). CARD_READY: confirm may proceed. EXPIRED: the window lapsed — open a fresh one.
cardThe captured card (CARD_READY only).
CheckoutCardReleaseResponse
statusSAVE_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.
CheckoutConfirmRequest
sessionIdThe session to confirm. Single-use: consumed whatever the outcome.
paymentMethodThe payment rail the buyer chose.
termsAcceptedYour assertion that the buyer accepted the pinned terms on your surface. Must be true — false/absent refuses with PORTAL_CHECKOUT_CONSENT_REQUIRED.
acceptedAtWhen the buyer accepted (ISO 8601). Evidence, not authority — implausible instants (future, or older than an hour) are replaced with the server’s own clock.
recurringConsentAcceptedYour assertion that the buyer accepted recurring billing. REQUIRED true on the CARD rail.
cardHandoffTokenA 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.
CheckoutConfirmResponse
subscriptionIdThe created subscription.
referenceYour reference, echoed.
billingPendingTrue 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.
PublicCheckoutVouchPrefill
customerTypeBUSINESS or PRIVATE_PERSON.
companyNameCompany name, for a BUSINESS buyer.
firstNamelastNamevatNumberaddresspostalCodecitycountryCodeISO 3166-1 alpha-2.
PublicMintCheckoutVouchRequest
emailThe buyer you are vouching for. This becomes their portal login identity, so the embedded checkout pre-fills it and LOCKS it — a buyer who is not this person uses the checkout's own escape rather than typing over it, and a confirm carrying a different address is refused. Distinct from contactEmail below, which is only where the paperwork goes.
contactEmailWhere invoices and receipts should go, when that differs from the login identity above. Written to the customer's default contact. Omit and billing follows email.
customerIdA customer you already hold the LedgerBee id for - typically one whose earlier subscription ended and who is now buying again. The purchase lands on that record instead of a second one, so a returning buyer does not accumulate duplicates. The customer must exist, be active, and belong to the API key's tenant; otherwise the mint returns 404 CUSTOMER_NOT_FOUND and nothing is minted.
This does not make the checkout read-only: the Details step still shows only what you prefilled, never the stored record, and whatever the buyer submits is written over the record at confirm. Omit for a first-time buyer - creating the customer at confirm is the default.
Optional starting values for the checkout Details step. Every field stays EDITABLE — this is a convenience for the buyer, never an assertion of fact, and whatever they submit is what we persist. Anything you omit renders empty.
allowIdentityChangeWhether the buyer may reject the vouched identity and continue as an anonymous buyer (the checkout shows a "Not you?" escape). It does NOT let them type a different address - the vouch is dropped and the checkout restarts unvouched, because we cannot vouch for someone we were not told about. Defaults to true: a buyer who genuinely is not the person you named has no other way out, and stranding them is worse than showing a link. Set false when your authentication makes a wrong identity impossible.
clientReferenceIdYour own opaque reference for this order (Stripe client_reference_id parity). It rides onto the created subscription (as partnerReferenceId), into every later subscription webhook, AND onto the customer.created event — which is the only field that maps a brand-new customer back to the cart that created it. Pass it. Server-to-server only; it never reaches a client/iframe surface. Max 200 chars, [A-Za-z0-9_-] only.
PublicMintCheckoutVouchResponse
checkoutVouchTokenOpaque, single-use, 60-second vouch reference. Return it from your page's fetchBindToken provider at checkout-start; the embedded checkout redeems it server-side. Mint it just-in-time — the TTL is deliberately shorter than a page's lifetime, and the provider is re-invoked per checkout.
expiresAtISO 8601 expiry of the reference above.
DefaultContactDto
nameContact name
emailContact email
phoneContact phone number
CreateCustomerRequestDto
customerTypeSpecifies whether the customer is a business or a private person
nameCustomer name
vatZoneVAT zone classification
customerGroupIdCustomer group ID
countryCodeTwo-letter country code
customerNumberUnique customer number. Omit it, or send an empty value, to have the next number assigned from the company customer sequence.
emailEmail address
phonePhone number
addressStreet address
cityCity
postalCodePostal code
vatNumberVAT registration number
eanNumberEAN/GLN number for Peppol routing
externalSystemIdExternal system identifier for tracking the customer across other systems. Unique per company.
websiteWebsite URL
notesAdditional notes
localeLocale for formatting invoice data
languageLanguage code for communications
creditLimitCredit limit
openingBalanceOpening balance in the company base currency, seeding receivables that predate LedgerBee. Signed: positive = the customer owes us, negative = a credit position. Folds into the entity balance only (not into invoiced totals or overdue ageing).
paymentTermsPayment terms in days
paymentTermTypePayment term type. Defaults to NET_DAYS.
defaultCashAccountIdDefault cash payment account ID. Only relevant for CASH payment terms. Send null to clear.
defaultCurrency^[A-Za-z]{3}$The customer's default invoicing currency, ISO 4217 alpha-3. Omit it, or send a blank one, to leave the answer to the server.
poNumberDefault purchase-order number ("PO-nr.") prefilled onto sales documents
ourReferenceDefault "Vores ref." (our-side reference) prefilled onto sales documents
invoiceDeliveryTypePreferencePreferred invoice delivery type for this customer. If set, overrides the app company default for billing.
reminderConfigIdReminder config profile ID. Send null to clear.
isActiveWhether the customer is active
Default contact to create for the customer. If not provided, customer name/email/phone will be used as fallback.
invoiceTemplateIdInvoice PDF template override
creditNoteTemplateIdCredit note PDF template override
quoteTemplateIdQuote PDF template override
orderConfirmationTemplateIdOrder confirmation PDF template override
parentInvoiceTemplateIdParent single invoice PDF template override. Send null to clear.
includeChildDetailsPdfWhether to attach a zip of per-child detail PDFs when sending consolidated invoices
selfServiceDetailsEnabledWhether this customer's portal users may fill in their own billing details (VAT number, street, postal code, city), both on the portal's Company settings page and during checkout, instead of only confirming a read-only copy of the record. Country and customer type stay operator-owned either way, which is what keeps them inside the VAT regime the operator assigned.
parentCustomerIdParent customer ID. Send null to clear.
billingRelationshipBilling relationship
consolidationModeConsolidation mode. Send null to clear.
billingDayBilling day (1-28). Required for single invoice mode. Send null to clear.
Key-value metadata to attach to the customer
PublicProvisionCustomerRequest
emailEmail of the portal user to grant access to. A credential-less portal user is created if none exists.
customerIdThe customer's LedgerBee id. The customer must already exist in the API key's tenant; this endpoint never creates one from an id (a 404 CUSTOMER_NOT_FOUND is returned if it doesn't). Supply either customerId or a customer payload.
A customer to upsert, identified idempotently by its customerNumber: an existing customer of the API key's tenant with that number is reused, otherwise a new one is created with this payload. Same shape as the gated POST /customers request (so vatZone and countryCode are required here). If customer.email is omitted, the portal-user email below is used as the customer's contact email (and its auto-created default contact). Supply either this or customerId.
roleMembership role to grant. Defaults to USER; the org's first member is force-assigned OWNER regardless.
userNameDisplay name of the portal user (set on first creation).
organizationDisplayNameDisplay name for the customer organization (first-invite bootstrap).
mintHandoffWhen true, also mint a back-channel handoff reference in the same call (one round-trip "Go to portal"). Requires the API key to ALSO carry the portal-sso-mint scope, and the tenant to have back-channel handoff enabled.
subThe partner's stable, unique user identifier — required when mintHandoff is true; keys the handoff identity (with the per-tenant handoff issuer).
mintCheckoutBindTokenWhen true, also mint a one-time CHECKOUT-BIND reference in the same call — an opaque token the partner's fetchBindToken provider returns to the embed at checkout-start so the embedded checkout subscribes directly against THIS customer instead of staging an anonymous magic-link signup. Requires the API key to ALSO carry the portal-sso-mint scope. Independent of mintHandoff (login): a checkout-bind ref can never mint a login session.
clientReferenceIdYour own opaque reference for this order (Stripe client_reference_id parity), e.g. your internal order or cart id. It rides the minted checkout-bind ref onto the resulting subscription (as partnerReferenceId) and into every later subscription webhook, so you can reconcile our subscription to your record. Server-to-server only — it never reaches a client/iframe surface. Max 200 chars, [A-Za-z0-9_-] only.
PublicProvisionCustomerResponse
customerIdResolved customer id.
customerCreatedWhether a new customer was created (false = an existing one was reused).
portalUserIdResolved portal user id.
membershipIdThe active organization membership id.
roleThe granted membership role.
handoffRefOpaque, single-use, 60s handoff reference — present only when mintHandoff was requested. Null otherwise.
handoffExpiresAtISO-8601 expiry of the handoff reference, when minted. Null otherwise.
checkoutBindTokenOpaque, single-use, 60s checkout-bind reference — present only when mintCheckoutBindToken was requested. Null otherwise. The partner's fetchBindToken provider returns this to the embed at checkout-start; the embedded checkout redeems it to subscribe directly against this customer.
checkoutBindExpiresAtISO-8601 expiry of the checkout-bind reference, when minted. Null otherwise.
PublicResolvePortalPlansRequest
customerTypeBuyer customer type for gross-price resolution.
vatNumberBuyer VAT number for gross-price resolution. Accepted only with customerType: 'BUSINESS' (a coded 400 otherwise). Requires a country hint to have any effect. On the resolve read it is ignored when customerId is supplied — a customer-backed resolve stays net-only.
currencyPresentment currency for every card's pricing. Must be in each card's availableCurrencies; cards that can't resolve it render null prices. Defaults to each card's own currency.
customerIdThe buyer's LedgerBee customer id (an identity HANDLE — the server hydrates customer group / country / type from it; raw rule attributes are never accepted). The customer must exist in the API key's tenant (a 404 CUSTOMER_NOT_FOUND otherwise). When present, the server-resolved identity wins and the countryCode/customerType hints are ignored.
buyerEmailThe specific person (their email) the partner is acting on behalf of under customerId — e.g. the user currently signed in on the partner's site. Bound into the catalog token: when that token is later exchanged for a portal login handoff, THIS person is logged in (or bootstrapped credential-less under the customer's organization), instead of the customer's contact email / first member. Ignored without customerId; does not affect catalog visibility.
countryCodeISO 3166-1 alpha-2 country hint for the no-customer-yet preview (drives the country rule clause). Ignored when customerId is supplied.
planIdsResolve only these plan ids. Omit to resolve every ACTIVE plan of the tenant. Each must be a uuid.
languageLanguage the resolved cards are localized to. Defaults to en.
PublicPortalPlanItemFeature
labelTranslated label, resolved for the request language.
iconKeyOptional Lu* icon key picked by the operator; null = default check icon.
PublicPortalPricingTier
fromQuantityFirst quantity covered by this tier.
toQuantityLast quantity in this tier; null for the final unbounded tier.
unitAmountMinorPer-unit amount in minor units; null when not set for this tier.
flatFeeMinorFlat fee for the tier in minor units; null when not set.
PublicPortalPlanItemProduct
priceIdSnapshot price id — stable identity / render key.
labelProduct display name (frozen product name, falling back to the price nickname).
descriptionOperator-authored product description; null when unset.
quantityTemplate quantity bundled in the plan. Defaults to 1 when unset.
pricingModelPricing model: 'flat_rate' | 'graduated' | 'package' | 'volume'.
kind'RECURRING' for period-billed lines, 'ONE_OFF' for one-time charges, 'METERED' for usage lines. A METERED line is period-bound like a recurring one, but its priceMinor is a rate per unit consumed rather than a period amount, so it contributes nothing to a period total.
unitPriceMinorHeadline unit price in minor units (first-unit "from" price for tiered models); null when unresolvable.
currencyCurrency code for unitPriceMinor.
tieredTrue for tiered models — the card prefixes the price with a "from" marker.
Tier ladder for tiered models, resolved for the currency (minor units). Empty for flat_rate products.
billingIntervalRecurring interval (e.g. 'month'); null for one-time charges.
billingIntervalCountInterval count (e.g. 1, 3, 12); null for one-time charges.
PublicPortalPlanItemVat
resolvedWhether VAT resolved for the supplied buyer hints. false = every gross field below is null.
grossPriceMinorGross headline price (minor units) for the active cadence; null when unresolved.
Gross per cadence, mirroring cadencePrices. Empty object when unresolved.
grossOneTimeMinorGross one-time charges total (minor units), mirroring oneTimeMinor; null when unresolved.
PublicPortalPlanItem
iditemTypeCard kind: 'SUBSCRIPTION' (priced card, CTA starts checkout) or 'CUSTOM_CTA' (subscription-less card whose CTA navigates ctaLink).
sourceSubscriptionIdSource subscription id (the chosen template, sent back on signup); null for CUSTOM_CTA items.
ctaLinkLink the CTA navigates to (https / relative / mailto: / tel:); non-null only for CUSTOM_CTA items.
ctaPresetKeyCTA preset ('contactUs' | 'bookDemo' | 'scheduleTime'); null for subscription cards or unmatched labels.
displayOrderplanNamePlan name (operator-edited title, language-resolved, falling back to the snapshot name).
descriptionShort pitch (language-resolved).
Bullet list; each entry is a plain string or a { label, iconKey } object, already resolved per language.
isMostPopularWhether to render the "recommended" treatment.
ctaLabelCTA copy; null falls back to the SPA default getStarted label.
titleColorOptional inline title color override (any CSS color).
ctaColorOptional inline CTA color override (any CSS color).
planIconKeyOperator-picked glyph key for the plan-card header icon.
planIconColorOptional inline override for the plan-card header icon color.
hidePlanIconWhen true, the card renders without the header icon.
featureIconColorOptional inline override for every feature-bullet icon color.
currencyCurrency code for priceMinor / oneTimeMinor.
availableCurrenciesCurrencies this card can be presented (and sold) in — the intersection across recurring products and allowed cadences of the currencies every price resolves for. For SUBSCRIPTION items it always contains currency; a requested checkout currency outside this set is a coded 400. CUSTOM_CTA items carry no pricing, so theirs is empty (and currency is '').
priceMinorHeadline price in minor units; null when no canonical recurring price exists.
cadenceKeyCadence key driving priceMinor (e.g. 'month-1'); null when priceMinor is null.
allowedCadencesCadences this item supports (drives the row-level cadence selector); empty when none is recoverable.
defaultCadenceCadence selected on first render; null when no cadence is recoverable for this item.
Price in minor units keyed by cadence; a present key with a null value is allowed-but-unpriced (renders as em-dash).
oneTimeMinorOne-time charges total in minor units (setup fees); null = no one-time line.
Products bundled in this tier (ACTIVE cadence). null for CUSTOM_CTA items; [] for a subscription tier with no products.
Product composition resolved per cadence, keyed by cadence; {} for CUSTOM_CTA items.
Buyer-specific VAT projection. resolved=false (all gross fields null) when the read carried no buyer hints, a rate could not be resolved, or the buyer zone is OSS-overridable — net figures stay authoritative either way.
PublicPortalComparisonCell
kindCell kind.
valueCell text; present only when kind is 'text'.
PublicPortalComparisonRow
labelOperator-authored row label (language-resolved).
Per-item presence keyed by plan item id.
PublicPortalComparisonSection
titleOperator-authored section heading (language-resolved).
PublicPortalComparison
PublicPortalPlan
idplanVersionIdPublished portal_plan_version id — the version pinned for checkout when the buyer clicked "Get started".
vanityPublic vanity slug (the /embed/
titleCustomer-facing title, language-resolved (en → da fallback); null when the operator entered none.
descriptionOperator-authored summary, same language fallback as title.
cardStyleCard style; null falls back to variant1 client-side.
displayedCadencesPlan-level cadence allow-list driving the row selector; null/empty falls back to the union of item cadences.
defaultDisplayedCadencePinned default for the row cadence selector; must be a member of displayedCadences. Null falls back to the first entry.
comparisonOperator-authored comparison matrix (columns are plan.items); null when none authored.
PublicPortalCatalogEntry
displayOrderOperator-controlled ordering inside the catalogue. Lower first.
isLegacyForVisitorTrue when the visitor holds an active subscription to this plan AND the plan is archived. Returned as false in v1.
checkoutableWhether a checkout of this plan can currently complete (its terms containers resolve to published versions). Buyer-facing projections filter on it; the tenant projection annotates without filtering, so plans needing operator attention stay visible.
PublicResolvePortalPlansDiagnostics
activePlansConsideredACTIVE plans the resolve considered (before any gate).
tenantHasNoVisibilityRulesTrue when the tenant has configured NO visibility rules at all — resolution is fail-closed (default hidden), so with no rules every plan drops. The fix is publishing a SHOW rule, not a hidden default.
droppedByVisibilityPlans dropped because no rule made them visible to this buyer.
droppedByCheckoutablePlans dropped because their terms do not currently resolve (not checkout-able).
PublicResolvePortalPlansResponse
The plans visible AND checkout-able to the resolved buyer, each carrying the full card content the partner renders. Non-public (gated) plans appear here when the buyer matches their rule.
catalogTokenOpaque, reusable, read-only load-time catalog token (43-char base64url). The partner returns it to each embed iframe via its fetchCatalogToken provider; the iframe presents it as a Bearer token to the by-id pricing-card / checkout-document reads. Scoped to the resolved buyer + the returned plans — replay yields only the same already-authorized cards. Treat it as a client secret (TLS-only, never log, never put on a URL).
expiresAtISO-8601 expiry of the catalog token.
Why plans were (or were not) returned — the "why is my catalogue empty" answer.
PublicPortalPlansListResponse
Every ACTIVE plan with a PUBLISHED version in the API key's tenant, projected as its canonical native card and ordered by display order. This is the integrator's full catalogue — NOT filtered by any per-visitor visibility rule and NOT run through the plan-routing rule engine — though a plan whose every card references a retired/archived subscription template is omitted (nothing renderable or sellable remains). Each entry carries the full card content the integrator renders.
PublicPortalPlanResponse
A single plan projected as its canonical native card. Returns 404 PORTAL_PLAN_NOT_FOUND when the plan id is unknown to the API key's tenant, has no published version, or every card on the published version references a retired/archived subscription template (nothing renderable or sellable remains) — never filtered by visibility rules or the rule engine.
PublicPortalSsoJwks
The published public JWK(s). Public key material only — never any private component.
PublicHandoffMembership
customerIdThe id of the customer (the GET /v1/customers resource) this user belongs to. The portal organization is resolved from it server-side — created automatically on first login if it doesn't exist yet — and a customer that doesn't belong to the API key's tenant is rejected.
roleRole to grant within that organization. One of OWNER, ADMIN, BILLING_ADMIN, USER. Unknown roles are rejected.
primaryMarks this membership as the organization the user is signed into for this session. When more than one membership is asserted, EXACTLY ONE must be primary (otherwise the mint is rejected with a 400). With a single membership it is the implied sign-in organization, so the flag is optional.
PublicHandoffMintRequest
emailEmail of the partner-provisioned user. Links a first-time SSO login to an existing invited customer-portal user.
subThe partner's stable, unique identifier for the user. Keyed together with the per-tenant handoff issuer to resolve the portal user across logins.
At least one customer membership to grant this user — required. The customer's portal organization (an opaque internal container) and the membership are created automatically server-side at redeem, so a prior provision call is NOT needed; you only ever reference customers, never organizations. Validated at mint: a customerId that isn't a customer of the API key's tenant, or an unknown role, is rejected with a 400 (rather than failing the user's browser redirect). A handoff with no membership can't establish a portal session, so an empty/omitted array is rejected here rather than minting a ref that would fail at redeem.
nameDisplay name of the user; used to populate the customer-portal user's name on first login.
PublicHandoffMintResponse
refOpaque, single-use, short-TTL reference. Carries NO identity — the identity lives only in server-side storage keyed by this reference until it is redeemed once at the customer portal.
expiresAtISO-8601 timestamp after which the reference can no longer be redeemed (60 seconds after minting).
PublicRevokeSessionsRequest
subThe partner's stable subject id for the user — the same sub used when minting their handoff. Every active portal session of that user is force-refreshed.
PublicRevokeSessionsResponse
revokedNumber of memberships whose sessions were force-refreshed (0 when the user has no active sessions).
VatCodeResponse
idThe unique identifier of the VAT code
vatCodeVAT code identifier
nameName/description of the VAT code
vatRateVAT rate percentage
typeVAT type
principleVAT principle - Gross (VAT included) or Net (VAT excluded)
accountToBookIdThe ledger account ID to book VAT to
accountToBookNumberThe ledger account number to book VAT to
accountToBookNameThe ledger account name to book VAT to
contraAccountToBookIdThe contra account ID for VAT entries
contraAccountToBookNumberThe contra account number for VAT entries
contraAccountToBookNameThe contra account name for VAT entries
VendorGroupResponse
idThe unique identifier of the vendor group
nameName of the vendor group
descriptionDescription of the vendor group
defaultAccountIdDefault ledger account ID
VendorDepartmentResponse
idThe unique identifier of the department
nameName of the department
isDefaultWhether this is the default department for the vendor
isActiveWhether the department is active
poNumberPurchase order number
eanNumberEAN number for e-invoicing
addressStreet address
cityCity
postalCodePostal code
countryCodeTwo-letter country code (ISO 3166-1 alpha-2)
VendorContactResponse
idThe unique identifier of the contact
nameName of the contact
isDefaultForVendorWhether this is the default contact for the vendor
emailEmail address
phonePhone number
VendorResponse
idThe unique identifier of the vendor
vendorNumberVendor number
nameName of the vendor
vendorGroupIdVendor group ID
currencyCurrency code
statusVendor status
vendorGroupNameVendor group name
emailEmail address
phonePhone number
addressStreet address
cityCity
postalCodePostal code
countryCodeTwo-letter country code (ISO 3166-1 alpha-2)
vatNumberVAT registration number
attentionAttention field
paymentTermsPayment terms in days
openingBalanceOpening balance in the company base currency (signed: positive = we owe the vendor)
CreateVendorContactRequest
nameContact name
isDefaultWhether this is the default contact for the vendor
emailEmail address
phonePhone number
CreateVendorRequest
vendorNumberUnique vendor number
nameVendor name
vendorGroupIdVendor group ID
currency^[A-Za-z]{3}$ · requiredThe currency this vendor bills us in, ISO 4217 alpha-3.
countryCodeTwo-letter country code
Contacts for the vendor. At least one contact with isDefault: true is required.
emailEmail address
phonePhone number
addressStreet address
cityCity
postalCodePostal code
vatNumberVAT registration number
attentionAttention field
paymentTermsPayment terms in days
openingBalanceOpening balance in the company base currency, seeding payables that predate LedgerBee. Signed: positive = we owe the vendor, negative = a credit position.
defaultAccountIdDefault ledger account ID
CreateVendorResponse
idThe unique identifier of the created vendor
vendorNumberVendor number
SupplierGroupResponse
idThe unique identifier of the supplier group
nameName of the supplier group
descriptionDescription of the supplier group
defaultAccountIdDefault ledger account ID
SupplierDepartmentResponse
idThe unique identifier of the department
nameName of the department
isDefaultWhether this is the default department for the supplier
isActiveWhether the department is active
poNumberPurchase order number
eanNumberEAN number for e-invoicing
addressStreet address
cityCity
postalCodePostal code
countryCodeTwo-letter country code (ISO 3166-1 alpha-2)
SupplierContactResponse
idThe unique identifier of the contact
nameName of the contact
isDefaultForSupplierWhether this is the default contact for the supplier
emailEmail address
phonePhone number
SupplierResponse
idThe unique identifier of the supplier
supplierNumberSupplier number
nameName of the supplier
supplierGroupIdSupplier group ID
currencyCurrency code
statusSupplier status
supplierGroupNameSupplier group name
emailEmail address
phonePhone number
addressStreet address
cityCity
postalCodePostal code
countryCodeTwo-letter country code (ISO 3166-1 alpha-2)
vatNumberVAT registration number
attentionAttention field
paymentTermsPayment terms in days
openingBalanceOpening balance in the company base currency (signed: positive = we owe the supplier)
CreateSupplierContactRequest
nameContact name
isDefaultWhether this is the default contact for the supplier
emailEmail address
phonePhone number
CreateSupplierRequest
supplierNumberUnique supplier number
nameSupplier name
supplierGroupIdSupplier group ID
currency^[A-Za-z]{3}$ · requiredThe currency this supplier bills us in, ISO 4217 alpha-3.
countryCodeTwo-letter country code
Contacts for the supplier. At least one contact with isDefault: true is required.
emailEmail address
phonePhone number
addressStreet address
cityCity
postalCodePostal code
vatNumberVAT registration number
attentionAttention field
paymentTermsPayment terms in days
openingBalanceOpening balance in the company base currency, seeding payables that predate LedgerBee. Signed: positive = we owe the supplier, negative = a credit position.
defaultAccountIdDefault ledger account ID
CreateSupplierResponse
idThe unique identifier of the created supplier
supplierNumberSupplier number
CreateWebhookEndpointRequest
urlThe HTTPS URL events are delivered to. Must be a public https URL (loopback/private/link-local hosts are rejected).
enabledEventsThe events to subscribe to. Must contain at least one known event type.
Available events:
subscription.assigned— Fired when a subscription is assigned to a customer (may be future-dated / upcoming).subscription.started— Fired when a subscription becomes active — grant entitlement/access on this event, not on assigned.subscription.updated— Fired when a config property changes without a structural transition (e.g. name, payment method, billing direction).subscription.transitioned— Fired on a structural change: plan replace, product edit, billing cadence change, phase change, or realign.subscription.paused— Fired when a subscription is paused.subscription.resumed— Fired when a subscription resumes from a pause.subscription.trial_ended— Fired when a subscription trial ends. The payload outcome says whether billing begins (ACTIVE) or the subscription was held for a missing payment card (PAUSED).subscription.cancellation_scheduled— Fired when a future cancellation is scheduled for a subscription (still active until then).subscription.cancellation_cleared— Fired when a previously scheduled cancellation is cleared.subscription.churned— Fired when a subscription is cancelled/finalized — revoke entitlement on this event.subscription.billed— Fired once per subscription that billed onto an invoice — one per child on a parent-paid consolidated invoice, one per member on a billing-group invoice. amount is always the whole document total; deduplicate on invoiceId, attribute on billingGroupId, never sum amount across events.subscription.payment_succeeded— Fired when a card charge for the subscription clears — the success pair of the charge_failed error signal. On a billing-group card charge one event fires per member, each carrying the full charged amount and the shared billingGroupId.subscription.error— Fired when a delivery/processing problem occurs for a subscription (e.g. undeliverable recipient).billing.invoice_sent— Fired when an invoice document is sent to the customer.billing.credit_note_sent— Fired when a credit note document is sent to the customer.customer.created— Fired when a customer is created (payload flags whether it was a portal self-signup).card.added— Fired when a card is successfully saved for a customer (provider-opaque).card.removed— Fired when a saved card is removed in-app or cancelled at the provider.card.updated— Fired when a saved card’s details change (network auto-update or refresh).card.expiring— Fired when a saved card is approaching expiry.card.expired— Fired when a saved card is observed to have expired.card.default_changed— Fired when the customer’s default card changes (explicit or auto-default).card.backup_changed— Fired when the customer’s designated backup card is set, replaced, or cleared.card.add_failed— Fired when a card-save attempt fails (decline or authentication failure).quote.sent— Fired when a quote is sent to the customer.quote.converted— Fired when a quote is converted into an order confirmation or an invoice.order_confirmation.sent— Fired when an order confirmation is sent to the customer.order_confirmation.converted— Fired when an order confirmation is converted into an invoice.checkout.card_ready— Fired when the buyer's card lands on a checkout session's card window — confirm may proceed. The card-status poll remains authoritative.checkout.card_failed— Fired when a checkout card window closes without a card (the provider window expired mid-capture) — open a fresh window to retry.checkout.session_expired— Fired when a checkout session expires unconsumed — the abandoned-checkout signal.project.created— Fired when a project is created (payload carries the owned dimension id for correlation with the dimensions API).project.updated— Fired when a project's fields are updated (payload lists the changed field names). Also fires on un-archive.project.archived— Fired when a project is archived (its dimension is deactivated; postings history is preserved).
descriptionOptional human-facing description.
WebhookEndpointWithSecret
idUnique identifier of the webhook endpoint.
urlThe HTTPS URL events are delivered to.
enabledEventsThe events this endpoint is subscribed to. An event is delivered to every enabled endpoint subscribed to its type.
Available events:
subscription.assigned— Fired when a subscription is assigned to a customer (may be future-dated / upcoming).subscription.started— Fired when a subscription becomes active — grant entitlement/access on this event, not on assigned.subscription.updated— Fired when a config property changes without a structural transition (e.g. name, payment method, billing direction).subscription.transitioned— Fired on a structural change: plan replace, product edit, billing cadence change, phase change, or realign.subscription.paused— Fired when a subscription is paused.subscription.resumed— Fired when a subscription resumes from a pause.subscription.trial_ended— Fired when a subscription trial ends. The payload outcome says whether billing begins (ACTIVE) or the subscription was held for a missing payment card (PAUSED).subscription.cancellation_scheduled— Fired when a future cancellation is scheduled for a subscription (still active until then).subscription.cancellation_cleared— Fired when a previously scheduled cancellation is cleared.subscription.churned— Fired when a subscription is cancelled/finalized — revoke entitlement on this event.subscription.billed— Fired once per subscription that billed onto an invoice — one per child on a parent-paid consolidated invoice, one per member on a billing-group invoice. amount is always the whole document total; deduplicate on invoiceId, attribute on billingGroupId, never sum amount across events.subscription.payment_succeeded— Fired when a card charge for the subscription clears — the success pair of the charge_failed error signal. On a billing-group card charge one event fires per member, each carrying the full charged amount and the shared billingGroupId.subscription.error— Fired when a delivery/processing problem occurs for a subscription (e.g. undeliverable recipient).billing.invoice_sent— Fired when an invoice document is sent to the customer.billing.credit_note_sent— Fired when a credit note document is sent to the customer.customer.created— Fired when a customer is created (payload flags whether it was a portal self-signup).card.added— Fired when a card is successfully saved for a customer (provider-opaque).card.removed— Fired when a saved card is removed in-app or cancelled at the provider.card.updated— Fired when a saved card’s details change (network auto-update or refresh).card.expiring— Fired when a saved card is approaching expiry.card.expired— Fired when a saved card is observed to have expired.card.default_changed— Fired when the customer’s default card changes (explicit or auto-default).card.backup_changed— Fired when the customer’s designated backup card is set, replaced, or cleared.card.add_failed— Fired when a card-save attempt fails (decline or authentication failure).quote.sent— Fired when a quote is sent to the customer.quote.converted— Fired when a quote is converted into an order confirmation or an invoice.order_confirmation.sent— Fired when an order confirmation is sent to the customer.order_confirmation.converted— Fired when an order confirmation is converted into an invoice.checkout.card_ready— Fired when the buyer's card lands on a checkout session's card window — confirm may proceed. The card-status poll remains authoritative.checkout.card_failed— Fired when a checkout card window closes without a card (the provider window expired mid-capture) — open a fresh window to retry.checkout.session_expired— Fired when a checkout session expires unconsumed — the abandoned-checkout signal.project.created— Fired when a project is created (payload carries the owned dimension id for correlation with the dimensions API).project.updated— Fired when a project's fields are updated (payload lists the changed field names). Also fires on un-archive.project.archived— Fired when a project is archived (its dimension is deactivated; postings history is preserved).
statusDelivery status. disabled endpoints are retained but receive no events.
createdAtISO 8601 creation timestamp.
updatedAtISO 8601 last-update timestamp.
secretThe signing secret (shown only on create and roll-secret). Used to verify the webhook-signature header.
descriptionOptional human-facing description of what this endpoint is used for.
WebhookEndpoint
idUnique identifier of the webhook endpoint.
urlThe HTTPS URL events are delivered to.
enabledEventsThe events this endpoint is subscribed to. An event is delivered to every enabled endpoint subscribed to its type.
Available events:
subscription.assigned— Fired when a subscription is assigned to a customer (may be future-dated / upcoming).subscription.started— Fired when a subscription becomes active — grant entitlement/access on this event, not on assigned.subscription.updated— Fired when a config property changes without a structural transition (e.g. name, payment method, billing direction).subscription.transitioned— Fired on a structural change: plan replace, product edit, billing cadence change, phase change, or realign.subscription.paused— Fired when a subscription is paused.subscription.resumed— Fired when a subscription resumes from a pause.subscription.trial_ended— Fired when a subscription trial ends. The payload outcome says whether billing begins (ACTIVE) or the subscription was held for a missing payment card (PAUSED).subscription.cancellation_scheduled— Fired when a future cancellation is scheduled for a subscription (still active until then).subscription.cancellation_cleared— Fired when a previously scheduled cancellation is cleared.subscription.churned— Fired when a subscription is cancelled/finalized — revoke entitlement on this event.subscription.billed— Fired once per subscription that billed onto an invoice — one per child on a parent-paid consolidated invoice, one per member on a billing-group invoice. amount is always the whole document total; deduplicate on invoiceId, attribute on billingGroupId, never sum amount across events.subscription.payment_succeeded— Fired when a card charge for the subscription clears — the success pair of the charge_failed error signal. On a billing-group card charge one event fires per member, each carrying the full charged amount and the shared billingGroupId.subscription.error— Fired when a delivery/processing problem occurs for a subscription (e.g. undeliverable recipient).billing.invoice_sent— Fired when an invoice document is sent to the customer.billing.credit_note_sent— Fired when a credit note document is sent to the customer.customer.created— Fired when a customer is created (payload flags whether it was a portal self-signup).card.added— Fired when a card is successfully saved for a customer (provider-opaque).card.removed— Fired when a saved card is removed in-app or cancelled at the provider.card.updated— Fired when a saved card’s details change (network auto-update or refresh).card.expiring— Fired when a saved card is approaching expiry.card.expired— Fired when a saved card is observed to have expired.card.default_changed— Fired when the customer’s default card changes (explicit or auto-default).card.backup_changed— Fired when the customer’s designated backup card is set, replaced, or cleared.card.add_failed— Fired when a card-save attempt fails (decline or authentication failure).quote.sent— Fired when a quote is sent to the customer.quote.converted— Fired when a quote is converted into an order confirmation or an invoice.order_confirmation.sent— Fired when an order confirmation is sent to the customer.order_confirmation.converted— Fired when an order confirmation is converted into an invoice.checkout.card_ready— Fired when the buyer's card lands on a checkout session's card window — confirm may proceed. The card-status poll remains authoritative.checkout.card_failed— Fired when a checkout card window closes without a card (the provider window expired mid-capture) — open a fresh window to retry.checkout.session_expired— Fired when a checkout session expires unconsumed — the abandoned-checkout signal.project.created— Fired when a project is created (payload carries the owned dimension id for correlation with the dimensions API).project.updated— Fired when a project's fields are updated (payload lists the changed field names). Also fires on un-archive.project.archived— Fired when a project is archived (its dimension is deactivated; postings history is preserved).
statusDelivery status. disabled endpoints are retained but receive no events.
createdAtISO 8601 creation timestamp.
updatedAtISO 8601 last-update timestamp.
descriptionOptional human-facing description of what this endpoint is used for.
WebhookEndpointList
totalTotal number of endpoints matching the query.
pageCurrent page (1-based).
pageSizePage size.
UpdateWebhookEndpointRequest
urlNew HTTPS delivery URL.
enabledEventsReplace the full set of subscribed events.
Available events:
subscription.assigned— Fired when a subscription is assigned to a customer (may be future-dated / upcoming).subscription.started— Fired when a subscription becomes active — grant entitlement/access on this event, not on assigned.subscription.updated— Fired when a config property changes without a structural transition (e.g. name, payment method, billing direction).subscription.transitioned— Fired on a structural change: plan replace, product edit, billing cadence change, phase change, or realign.subscription.paused— Fired when a subscription is paused.subscription.resumed— Fired when a subscription resumes from a pause.subscription.trial_ended— Fired when a subscription trial ends. The payload outcome says whether billing begins (ACTIVE) or the subscription was held for a missing payment card (PAUSED).subscription.cancellation_scheduled— Fired when a future cancellation is scheduled for a subscription (still active until then).subscription.cancellation_cleared— Fired when a previously scheduled cancellation is cleared.subscription.churned— Fired when a subscription is cancelled/finalized — revoke entitlement on this event.subscription.billed— Fired once per subscription that billed onto an invoice — one per child on a parent-paid consolidated invoice, one per member on a billing-group invoice. amount is always the whole document total; deduplicate on invoiceId, attribute on billingGroupId, never sum amount across events.subscription.payment_succeeded— Fired when a card charge for the subscription clears — the success pair of the charge_failed error signal. On a billing-group card charge one event fires per member, each carrying the full charged amount and the shared billingGroupId.subscription.error— Fired when a delivery/processing problem occurs for a subscription (e.g. undeliverable recipient).billing.invoice_sent— Fired when an invoice document is sent to the customer.billing.credit_note_sent— Fired when a credit note document is sent to the customer.customer.created— Fired when a customer is created (payload flags whether it was a portal self-signup).card.added— Fired when a card is successfully saved for a customer (provider-opaque).card.removed— Fired when a saved card is removed in-app or cancelled at the provider.card.updated— Fired when a saved card’s details change (network auto-update or refresh).card.expiring— Fired when a saved card is approaching expiry.card.expired— Fired when a saved card is observed to have expired.card.default_changed— Fired when the customer’s default card changes (explicit or auto-default).card.backup_changed— Fired when the customer’s designated backup card is set, replaced, or cleared.card.add_failed— Fired when a card-save attempt fails (decline or authentication failure).quote.sent— Fired when a quote is sent to the customer.quote.converted— Fired when a quote is converted into an order confirmation or an invoice.order_confirmation.sent— Fired when an order confirmation is sent to the customer.order_confirmation.converted— Fired when an order confirmation is converted into an invoice.checkout.card_ready— Fired when the buyer's card lands on a checkout session's card window — confirm may proceed. The card-status poll remains authoritative.checkout.card_failed— Fired when a checkout card window closes without a card (the provider window expired mid-capture) — open a fresh window to retry.checkout.session_expired— Fired when a checkout session expires unconsumed — the abandoned-checkout signal.project.created— Fired when a project is created (payload carries the owned dimension id for correlation with the dimensions API).project.updated— Fired when a project's fields are updated (payload lists the changed field names). Also fires on un-archive.project.archived— Fired when a project is archived (its dimension is deactivated; postings history is preserved).
statusEnable or disable delivery without deleting the endpoint.
descriptionUpdate the description. Send null to clear it.
TestWebhookEndpointRequest
eventThe event type to simulate. Must be one of the endpoint’s subscribed events.
Available events:
subscription.assigned— Fired when a subscription is assigned to a customer (may be future-dated / upcoming).subscription.started— Fired when a subscription becomes active — grant entitlement/access on this event, not on assigned.subscription.updated— Fired when a config property changes without a structural transition (e.g. name, payment method, billing direction).subscription.transitioned— Fired on a structural change: plan replace, product edit, billing cadence change, phase change, or realign.subscription.paused— Fired when a subscription is paused.subscription.resumed— Fired when a subscription resumes from a pause.subscription.trial_ended— Fired when a subscription trial ends. The payload outcome says whether billing begins (ACTIVE) or the subscription was held for a missing payment card (PAUSED).subscription.cancellation_scheduled— Fired when a future cancellation is scheduled for a subscription (still active until then).subscription.cancellation_cleared— Fired when a previously scheduled cancellation is cleared.subscription.churned— Fired when a subscription is cancelled/finalized — revoke entitlement on this event.subscription.billed— Fired once per subscription that billed onto an invoice — one per child on a parent-paid consolidated invoice, one per member on a billing-group invoice. amount is always the whole document total; deduplicate on invoiceId, attribute on billingGroupId, never sum amount across events.subscription.payment_succeeded— Fired when a card charge for the subscription clears — the success pair of the charge_failed error signal. On a billing-group card charge one event fires per member, each carrying the full charged amount and the shared billingGroupId.subscription.error— Fired when a delivery/processing problem occurs for a subscription (e.g. undeliverable recipient).billing.invoice_sent— Fired when an invoice document is sent to the customer.billing.credit_note_sent— Fired when a credit note document is sent to the customer.customer.created— Fired when a customer is created (payload flags whether it was a portal self-signup).card.added— Fired when a card is successfully saved for a customer (provider-opaque).card.removed— Fired when a saved card is removed in-app or cancelled at the provider.card.updated— Fired when a saved card’s details change (network auto-update or refresh).card.expiring— Fired when a saved card is approaching expiry.card.expired— Fired when a saved card is observed to have expired.card.default_changed— Fired when the customer’s default card changes (explicit or auto-default).card.backup_changed— Fired when the customer’s designated backup card is set, replaced, or cleared.card.add_failed— Fired when a card-save attempt fails (decline or authentication failure).quote.sent— Fired when a quote is sent to the customer.quote.converted— Fired when a quote is converted into an order confirmation or an invoice.order_confirmation.sent— Fired when an order confirmation is sent to the customer.order_confirmation.converted— Fired when an order confirmation is converted into an invoice.checkout.card_ready— Fired when the buyer's card lands on a checkout session's card window — confirm may proceed. The card-status poll remains authoritative.checkout.card_failed— Fired when a checkout card window closes without a card (the provider window expired mid-capture) — open a fresh window to retry.checkout.session_expired— Fired when a checkout session expires unconsumed — the abandoned-checkout signal.project.created— Fired when a project is created (payload carries the owned dimension id for correlation with the dimensions API).project.updated— Fired when a project's fields are updated (payload lists the changed field names). Also fires on un-archive.project.archived— Fired when a project is archived (its dimension is deactivated; postings history is preserved).
TestWebhookEndpointResult
successWhether the endpoint responded with a 2xx status.
durationMsRound-trip time of the probe in milliseconds.
statusCodeHTTP status returned by the endpoint, or null on a transport error.
errorTransport/error message when the probe failed, otherwise null.
PublicCreateInvoiceLine
priceIdProduct price ID. Required on a billable line — the line bills this product. Omit only for text / separator / discount lines (set lineType instead).
lineTypeSemantic type of the line (subscription, usage, discount, text, separator, etc.)
descriptionCustom description for this line item
quantityQuantity. Required on a billable line; omit for text / separator / discount lines.
unitPriceOne-time unit-price override (decimal string). Defaults to the price's current amount in the document currency when omitted. totalPrice (= quantity * unitPrice) and VAT are always computed server-side and must not be sent.
recognitionPeriodDaysOverride the revenue recognition period for this line (in days)
PublicCreateInvoice
customerIdCustomer ID this invoice is for. Required — every invoice must reference a customer (this mirrors the gated app, which also requires a customer).
dateInvoice date (ISO date, YYYY-MM-DD)
Invoice lines
customerDepartmentIdCustomer department ID (for EAN-based e-invoicing and address override)
customerContactIdCustomer contact ID (invoice recipient)
dueDateDue date for payment (ISO date). Derived from payment terms when omitted.
currencyCurrency code (ISO 4217). Defaults to the company default currency.
paymentTermsPayment terms in days
referenceReference / PO number ("PO-nr.")
ourReferenceOur reference ("Vores ref.")
descriptionOptional description of the invoice
notesAdditional notes or comments
PublicInvoiceLine
idLine item ID
quantityQuantity
unitPriceUnit price (decimal string)
totalPriceTotal price (decimal string)
priceIdPrice ID this line references
descriptionCustom description for this line item
lineTypeSemantic line type
vatAmountVAT amount (decimal string)
vatRateVAT rate percentage (decimal string)
PublicInvoice
idInvoice ID
statusInvoice status
dateInvoice date (ISO date)
isConsolidatedTrue when this invoice consolidates several subscriptions onto one document: a billing group’s shared invoice, or a parent customer’s invoice covering its child customers’ subscriptions. With both customerSubscriptionId and billingGroupId null it is the parent-paid kind.
currencyCurrency code (ISO 4217)
subtotalSubtotal before VAT (decimal string)
vatVAT amount (decimal string)
amountTotal amount including VAT (decimal string)
Invoice lines
createdAtCreation timestamp (ISO)
updatedAtLast update timestamp (ISO)
numberInvoice number. Null while the invoice is still a draft (allocated at booking).
dueDateDue date (ISO date)
customerIdCustomer ID
customerSubscriptionIdThe subscription this invoice bills, when it bills exactly one. Null on a billing group’s shared invoice (see billingGroupId), on a parent-paid consolidated invoice (see isConsolidated) and on a manually created invoice.
billingGroupIdThe billing group this invoice is issued to, when several of one customer’s subscriptions bill onto it. Set instead of customerSubscriptionId, never alongside it. Filter the list by billingGroupId to find a group’s documents.
referenceReference / PO number
ourReferenceOur reference ("Vores ref.")
notesAdditional notes
PublicInvoiceListItem
idInvoice ID
statusInvoice status
dateInvoice date (ISO date)
isConsolidatedTrue when this invoice consolidates several subscriptions onto one document: a billing group’s shared invoice, or a parent customer’s invoice covering its child customers’ subscriptions. With both customerSubscriptionId and billingGroupId null it is the parent-paid kind.
currencyCurrency code (ISO 4217)
subtotalSubtotal before VAT (decimal string)
vatVAT amount (decimal string)
amountTotal amount including VAT (decimal string)
createdAtCreation timestamp (ISO)
updatedAtLast update timestamp (ISO)
numberInvoice number. Null while the invoice is still a draft (allocated at booking).
dueDateDue date (ISO date)
customerIdCustomer ID
customerSubscriptionIdThe subscription this invoice bills, when it bills exactly one. Null on a billing group’s shared invoice (see billingGroupId), on a parent-paid consolidated invoice (see isConsolidated) and on a manually created invoice.
billingGroupIdThe billing group this invoice is issued to, when several of one customer’s subscriptions bill onto it. Set instead of customerSubscriptionId, never alongside it. Filter the list by billingGroupId to find a group’s documents.
referenceReference / PO number
ourReferenceOur reference ("Vores ref.")
notesAdditional notes
PublicListInvoicesResponse
Invoices on this page (line items omitted; GET one invoice for lines)
totalTotal invoices matching the query
pageCurrent page (1-indexed)
limitItems per page
totalPagesTotal pages
PublicSendInvoice
deliveryTypeDelivery channel
overrideEmailOverride recipient email for this send only
overrideEanNumberOverride EAN number for this send only
updateCustomerRecordPersist the override email / EAN onto the customer record
documentTemplateIdOverride document template for PDF generation
PublicSendInvoiceResponse
successWhether the send was accepted
deliveryTypeThe delivery channel the document was sent through
sproomDocumentIdSproom document ID when sent via e-invoicing
PublicDeliveryStatusSummary
sendCountNumber of send attempts recorded
lastDeliveryTypeChannel of the most recent send
lastRecipientEmailRecipient email of the most recent send
lastRecipientEanRecipient EAN of the most recent send
lastSentAtTimestamp of the most recent send (ISO)
PublicDeliveryLogEntry
idDelivery log entry ID
statusOutcome of the delivery attempt
deliveryTypeDelivery channel
sentAtTimestamp of the attempt (ISO)
recipientEmailRecipient email (email sends)
recipientEanRecipient EAN (e-invoice sends)
errorCodeError code when the attempt failed
PublicDeliveryStatusResponse
Aggregate send summary
Per-attempt delivery log entries
PublicCreateCreditNoteLine
priceIdProduct price ID. Required on a billable line — the line credits this product. Omit only for text / separator / discount lines (set lineType instead).
lineTypeSemantic type of the line (refund, cancellation credit, text, separator, etc.)
descriptionCustom description for this line item
quantityQuantity to credit. Required on a billable line; omit for text / separator / discount lines.
unitPriceOne-time unit-price override as a POSITIVE decimal string (the magnitude). Defaults to the price's current amount when omitted. The credit (negative) sign, totalPrice, and VAT are applied server-side and must not be sent.
PublicCreateCreditNote
customerIdCustomer ID this credit note is for
dateCredit note date (ISO date, YYYY-MM-DD)
Credit note lines
customerDepartmentIdCustomer department ID (for EAN-based e-invoicing and address override)
customerContactIdCustomer contact ID (credit note recipient)
invoiceNumberOriginal invoice number this credit note credits. When set, the referenced invoice is marked credited.
currencyCurrency code (ISO 4217). Defaults to the company default currency.
referenceReference / PO number ("PO-nr.")
ourReferenceOur reference ("Vores ref.")
descriptionOptional description of the credit note
notesAdditional notes or comments
PublicCreditNoteLine
idLine item ID
quantityQuantity
unitPriceUnit price (decimal string)
totalPriceTotal price (decimal string)
priceIdPrice ID this line references
descriptionCustom description for this line item
lineTypeSemantic line type
vatAmountVAT amount (decimal string)
vatRateVAT rate percentage (decimal string)
PublicCreditNote
idCredit note ID
numberCredit note number
statusCredit note status
dateCredit note date (ISO date)
currencyCurrency code (ISO 4217)
subtotalSubtotal before VAT (decimal string)
vatVAT amount (decimal string)
amountTotal amount including VAT (decimal string)
Credit note lines
createdAtCreation timestamp (ISO)
updatedAtLast update timestamp (ISO)
invoiceNumberOriginal invoice number this credit note credits
customerIdCustomer ID
customerSubscriptionIdThe subscription this credit note credits, when it credits exactly one. Null on a billing group’s credit note (see billingGroupId) and on a manually created one.
billingGroupIdThe billing group this credit note is issued to, when it credits a group’s shared invoice. Set instead of customerSubscriptionId, never alongside it.
referenceReference / PO number
ourReferenceOur reference ("Vores ref.")
notesAdditional notes
PublicCreditNoteListItem
idCredit note ID
numberCredit note number
statusCredit note status
dateCredit note date (ISO date)
currencyCurrency code (ISO 4217)
subtotalSubtotal before VAT (decimal string)
vatVAT amount (decimal string)
amountTotal amount including VAT (decimal string)
createdAtCreation timestamp (ISO)
updatedAtLast update timestamp (ISO)
invoiceNumberOriginal invoice number this credit note credits
customerIdCustomer ID
customerSubscriptionIdThe subscription this credit note credits, when it credits exactly one. Null on a billing group’s credit note (see billingGroupId) and on a manually created one.
billingGroupIdThe billing group this credit note is issued to, when it credits a group’s shared invoice. Set instead of customerSubscriptionId, never alongside it.
referenceReference / PO number
ourReferenceOur reference ("Vores ref.")
notesAdditional notes
PublicListCreditNotesResponse
Credit notes on this page (line items omitted; GET one for lines)
totalTotal credit notes matching the query
pageCurrent page (1-indexed)
limitItems per page
totalPagesTotal pages
PublicSendCreditNote
deliveryTypeDelivery channel
overrideEmailOverride recipient email for this send only
overrideEanNumberOverride EAN number for this send only
updateCustomerRecordPersist the override email / EAN onto the customer record
documentTemplateIdOverride document template for PDF generation
PublicQuoteListItem
idQuote identifier
typeAlways "quote"
statusStored lifecycle status (draft/sent/accepted/rejected)
displayStatusStatus to display. Equals status except derived states: "converted" or "expired".
dateQuote date (ISO, YYYY-MM-DD)
amountTotal amount including VAT
subtotalSubtotal excluding VAT
vatTotal VAT
currencyCurrency code
createdAtCreated timestamp (ISO)
updatedAtUpdated timestamp (ISO)
documentNumberAllocated quote number (null until sent)
validUntilValid-until date (ISO, YYYY-MM-DD)
referencePO number ("PO-nr.")
ourReferenceOur reference ("Vores ref.")
notesNotes
customerIdCustomer id
sourceDocumentIdSource document id (set when this quote originated from another document)
convertedToDocumentIdId of the order confirmation this quote was converted into
convertedToInvoiceIdId of the invoice this quote was converted into
sentAtTimestamp the quote was sent (ISO)
PublicListQuotesResponse
List of quotes (line items omitted; GET one quote for lines)
totalTotal number of quotes matching the query
pageCurrent page number (1-indexed)
limitMaximum number of items per page
totalPagesTotal number of pages available
PublicQuoteLine
idLine identifier
quantityQuantity
unitPriceUnit price
totalPriceTotal price for the line
descriptionLine description shown on the quote
lineTypeSemantic line type
vatRateVAT rate (percentage)
vatAmountVAT amount for the line
PublicQuote
idQuote identifier
typeAlways "quote"
statusStored lifecycle status (draft/sent/accepted/rejected)
displayStatusStatus to display. Equals status except derived states: "converted" or "expired".
dateQuote date (ISO, YYYY-MM-DD)
amountTotal amount including VAT
subtotalSubtotal excluding VAT
vatTotal VAT
currencyCurrency code
createdAtCreated timestamp (ISO)
updatedAtUpdated timestamp (ISO)
documentNumberAllocated quote number (null until sent)
validUntilValid-until date (ISO, YYYY-MM-DD)
referencePO number ("PO-nr.")
ourReferenceOur reference ("Vores ref.")
notesNotes
customerIdCustomer id
sourceDocumentIdSource document id (set when this quote originated from another document)
convertedToDocumentIdId of the order confirmation this quote was converted into
convertedToInvoiceIdId of the invoice this quote was converted into
sentAtTimestamp the quote was sent (ISO)
PublicCreateQuoteLine
priceIdProduct price id. Required on a billable line — the line bills this product. Omit only for text / separator / discount lines (set lineType instead).
descriptionCustom description for the line
lineTypeSemantic line type. Use text / separator / discount / interval_discount for non-billable lines; any other value marks the line billable (priceId + quantity required).
quantityQuantity. Required on a billable line; omit for text / separator / discount lines.
unitPriceOne-time unit-price override. Defaults to the price's current amount in the document currency. totalPrice and VAT are computed server-side and must not be sent.
PublicCreateQuote
customerIdCustomer this quote is for
dateQuote date (ISO, YYYY-MM-DD)
customerDepartmentIdCustomer department id
customerContactIdCustomer contact id ("Deres ref.")
validUntilValid-until date (ISO, YYYY-MM-DD)
currencyCurrency code
referencePO number ("PO-nr.")
ourReferenceOur reference ("Vores ref.")
notesNotes shown on the quote
PublicSendQuote
deliveryTypeDelivery method. Defaults to Manual. Sproom/e-invoice does not apply to quotes.
recipientEmailOverride recipient email for Email delivery
PublicConvertQuotePayload
customerIdCustomer for the converted document
dateDocument date (ISO, YYYY-MM-DD)
customerDepartmentIdCustomer department id
customerContactIdCustomer contact id
currencyCurrency code
referencePO number ("PO-nr.")
ourReferenceOur reference ("Vores ref.")
notesNotes
PublicConvertQuote
targetTarget to convert into. Use "orderConfirmation" to confirm the quote, or "invoice" to convert it directly into an invoice.
Edited target document (review-before-finalize). Omit to copy the source verbatim.
PublicConvertQuoteResult
targetTypeType of document produced by the conversion ("invoice" or "orderConfirmation")
targetIdIdentifier of the produced document
PublicUpdateQuote
customerIdCustomer this quote is for
dateQuote date (ISO, YYYY-MM-DD)
customerDepartmentIdCustomer department id
customerContactIdCustomer contact id ("Deres ref.")
validUntilValid-until date (ISO, YYYY-MM-DD)
currencyCurrency code
referencePO number ("PO-nr.")
ourReferenceOur reference ("Vores ref.")
notesNotes shown on the quote
PublicOrderConfirmationListItem
idDocument identifier
statusStored lifecycle status (draft/sent)
displayStatusStatus to display. Equals status except the derived "converted" state.
dateDocument date (ISO, YYYY-MM-DD)
amountTotal amount including VAT
subtotalSubtotal excluding VAT
vatTotal VAT
currencyCurrency code
createdAtCreated timestamp (ISO)
updatedAtUpdated timestamp (ISO)
documentNumberAllocated document number (null until sent)
referencePO number ("PO-nr.")
ourReferenceOur reference ("Vores ref.")
notesNotes
customerIdCustomer id
sourceDocumentIdSource document id (the quote this order confirmation was converted from)
convertedToInvoiceIdId of the invoice this order confirmation was converted into
sentAtTimestamp the document was sent (ISO)
PublicListOrderConfirmationsResponse
List of order confirmations (line items omitted; GET one for lines)
totalTotal number of documents matching the query
pageCurrent page number (1-indexed)
limitMaximum number of items per page
totalPagesTotal number of pages available
PublicOrderConfirmationLine
idLine identifier
quantityQuantity
unitPriceUnit price
totalPriceTotal price for the line
descriptionLine description shown on the document
lineTypeSemantic line type
vatRateVAT rate (percentage)
vatAmountVAT amount for the line
PublicOrderConfirmation
idDocument identifier
statusStored lifecycle status (draft/sent)
displayStatusStatus to display. Equals status except the derived "converted" state.
dateDocument date (ISO, YYYY-MM-DD)
amountTotal amount including VAT
subtotalSubtotal excluding VAT
vatTotal VAT
currencyCurrency code
createdAtCreated timestamp (ISO)
updatedAtUpdated timestamp (ISO)
documentNumberAllocated document number (null until sent)
referencePO number ("PO-nr.")
ourReferenceOur reference ("Vores ref.")
notesNotes
customerIdCustomer id
sourceDocumentIdSource document id (the quote this order confirmation was converted from)
convertedToInvoiceIdId of the invoice this order confirmation was converted into
sentAtTimestamp the document was sent (ISO)
PublicCreateOrderConfirmationLine
priceIdProduct price id. Required on a billable line — the line bills this product. Omit only for text / separator / discount lines (set lineType instead).
descriptionCustom description for the line
lineTypeSemantic line type. Use text / separator / discount / interval_discount for non-billable lines; any other value marks the line billable (priceId + quantity required).
quantityQuantity. Required on a billable line; omit for text / separator / discount lines.
unitPriceOne-time unit-price override. Defaults to the price's current amount in the document currency. totalPrice and VAT are computed server-side and must not be sent.
PublicCreateOrderConfirmation
customerIdCustomer this order confirmation is for
dateDocument date (ISO, YYYY-MM-DD)
customerDepartmentIdCustomer department id
customerContactIdCustomer contact id ("Deres ref.")
currencyCurrency code
referencePO number ("PO-nr.")
ourReferenceOur reference ("Vores ref.")
notesNotes shown on the document
PublicSendOrderConfirmation
deliveryTypeDelivery method. Defaults to Manual. Sproom/e-invoice does not apply to order confirmations.
recipientEmailOverride recipient email for Email delivery
PublicConvertOrderConfirmationPayload
customerIdCustomer for the converted document
dateDocument date (ISO, YYYY-MM-DD)
customerDepartmentIdCustomer department id
customerContactIdCustomer contact id
currencyCurrency code
referencePO number ("PO-nr.")
ourReferenceOur reference ("Vores ref.")
notesNotes
PublicConvertOrderConfirmation
targetTarget to convert into. An order confirmation only ever converts into an "invoice".
Edited target document (review-before-finalize). Omit to copy the source verbatim.
PublicConvertOrderConfirmationResult
targetTypeType of document produced by the conversion (always "invoice")
targetIdIdentifier of the produced document
PublicUpdateOrderConfirmation
customerIdCustomer this order confirmation is for
dateDocument date (ISO, YYYY-MM-DD)
customerDepartmentIdCustomer department id
customerContactIdCustomer contact id ("Deres ref.")
currencyCurrency code
referencePO number ("PO-nr.")
ourReferenceOur reference ("Vores ref.")
notesNotes shown on the document
statusNew stored status (validated against the document type: draft/sent for order confirmations).
PublicDownloadLink
urlFetch this URL directly to download the PDF. It needs no API key — the URL itself is the credential.
expiresAtWhen the link stops working
ProductGroupResponse
idThe unique identifier of the product group
numberUnique product-group number within the company
nameName of the product group
domesticAccountIdLedger account ID for domestic sales
createdAtWhen the product group was created
updatedAtWhen the product group was last updated
descriptionOptional description
domesticAccountNumberDomestic account number
domesticAccountNameDomestic account name
euAccountIdLedger account ID for EU sales (Rubric B)
euAccountNumberEU account number
euAccountNameEU account name
abroadAccountIdLedger account ID for sales abroad (Rubric C)
abroadAccountNumberAbroad account number
abroadAccountNameAbroad account name
domesticWithoutVatAccountIdLedger account ID for domestic sales without VAT
domesticWithoutVatAccountNumberDomestic-without-VAT account number
domesticWithoutVatAccountNameDomestic-without-VAT account name
productCountNumber of products in this group (list responses only)
ListProductGroupsResponse
Page of product groups
totalTotal number of matching product groups
pageCurrent page number
limitItems per page
totalPagesTotal number of pages
CreateProductGroupRequest
numberUnique product-group number within the company
nameName of the product group
domesticAccountIdLedger account ID for domestic sales. Must reference an existing account that carries a VAT code valid for sales.
euAccountIdLedger account ID for EU sales (Rubric B). Must carry a sales-valid VAT code.
abroadAccountIdLedger account ID for sales abroad (Rubric C). Must carry a sales-valid VAT code.
domesticWithoutVatAccountIdLedger account ID for domestic sales without VAT.
descriptionOptional description
UpdateProductGroupRequest
numberUnique product-group number within the company
nameName of the product group
descriptionOptional description
domesticAccountIdLedger account ID for domestic sales
euAccountIdLedger account ID for EU sales (Rubric B)
abroadAccountIdLedger account ID for sales abroad (Rubric C)
domesticWithoutVatAccountIdLedger account ID for domestic sales without VAT
EntitlementResponse
idEntitlement ID
nameEntitlement name
managedExternallyTrue when the entitlement is maintained by an external system rather than created by an operator in the app. Only rows with externalSource "api" can be modified through this API.
externalSourceWhich system maintains the entitlement: "api" (created via this API), "platform" (managed by LedgerBee, read-only here), or null for operator-created rows.
createdAtWhen the entitlement was created
updatedAtWhen the entitlement was last updated
keyStable integration key
ListEntitlementsResponse
totalpagelimittotalPagesCreateEntitlementRequest
nameEntitlement name
keyStable integration key
ProductListItem
idThe unique identifier of the product
productNumberUnique product number within the company
nameName of the product
unitUnit of measurement
productGroupIdProduct group this product belongs to
productTypeProduct type (goods or services) for EU VAT
isActiveWhether the product is active
isArchivedWhether the product is archived
isLockedWhether the product is locked (in use, cannot be deleted)
createdAtWhen the product was created
updatedAtWhen the product was last updated
descriptionOptional description
ListProductsResponse
Page of products (prices omitted; GET one product for its prices)
totalTotal number of matching products
pageCurrent page number
limitItems per page
totalPagesTotal number of pages
ProductPriceTierResponse
idTier ID
fromQuantityStarting quantity (inclusive)
unitAmountPrice per unit for this tier
toQuantityEnding quantity (inclusive). Null = no upper limit.
flatFeeOptional flat fee for this tier
ProductPriceResponse
idThe unique identifier of the price (use as a line priceId)
productIdThe product this price belongs to
billingPeriodTypeBilling period type
pricingModelPricing model
currencyCurrency of the displayed unitAmount (ISO 4217)
baseCurrencyBase currency (source of truth for conversions)
statusPrice status
isDefaultWhether this is the default price for the product
isLockedWhether the price is locked (in use by a subscription/invoice)
vatRatesByZoneVAT rates by zone (derived from the product group), e.g. { domestic: "25", eu: "0", abroad: "0", domestic_without_vat: "0" }
nicknameOptional nickname (e.g. "Monthly")
unitAmountUnit amount for flat-rate pricing in currency
billingIntervalBilling interval (null for one-time)
billingIntervalCountBilling interval count
availableCurrenciesCurrencies with a price-history entry
meterIdMeter ID for usage-based pricing
Pricing tiers (package/volume/graduated)
ProductResponse
idThe unique identifier of the product
productNumberUnique product number within the company
nameName of the product
unitUnit of measurement
productGroupIdProduct group this product belongs to
productTypeProduct type (goods or services) for EU VAT
isActiveWhether the product is active
isArchivedWhether the product is archived
isLockedWhether the product is locked (in use, cannot be deleted)
createdAtWhen the product was created
updatedAtWhen the product was last updated
descriptionOptional description
Prices configured for this product
Entitlements granted by this product
CreateProductPriceTierRequest
fromQuantityStarting quantity (inclusive)
unitAmountPrice per unit for this tier
toQuantityEnding quantity (inclusive). Omit for the open-ended top tier.
flatFeeOptional flat fee for this tier
CreateProductInitialPriceRequest
billingPeriodTypeBilling period type. RECURRING and USAGE both require a Subscription license.
pricingModelPricing model
nicknameOptional nickname (e.g. "Monthly")
unitAmountUnit amount. Required for FLAT_RATE pricing; for tiered models (PACKAGE/VOLUME/GRADUATED) the amounts live in tiers.
billingIntervalBilling interval (required unless one-time)
billingIntervalCountBilling interval count
currencyCurrency code (ISO 4217)
meterIdMeter ID (required for USAGE pricing)
Pricing tiers. Required for tiered models: PACKAGE (exactly 1), VOLUME / GRADUATED (one or more, last tier open-ended). Omit for FLAT_RATE.
CreateProductRequest
productNumberUnique product number within the company
nameName of the product
unitUnit of measurement
productGroupIdProduct group this product belongs to (must exist)
descriptionOptional description
isActiveWhether the product is active
productTypeProduct type (goods or services)
Optional initial price. If provided it is created, activated and set as default in one transaction.
entitlementIdsExternally managed entitlement IDs to bind (max 100)
UpdateProductRequest
productNumberUnique product number within the company
nameName of the product
descriptionOptional description
unitUnit of measurement
productGroupIdProduct group this product belongs to
isActiveWhether the product is active
productTypeProduct type (goods or services)
entitlementIdsExternally managed entitlement IDs to bind (max 100)
PublicOpenEntry
kindWhat this row points at. Echo it back verbatim as a settlement selection — an ANCHOR and a PREPAYMENT are stored alike and are not interchangeable.
idID of the entry — the invoice anchor for ANCHOR and PREPAYMENT rows, the payment entry for PAYMENT.
typeWhat the entry is.
referenceInvoice number, payment reference, or anchor number.
datePosting date of the original entry (YYYY-MM-DD).
currencyCurrency of the original entry (3-letter ISO).
originalAmountSigned face amount in the entry’s own currency. Positive on an invoice, negative on a credit note.
remainingAmountSigned amount still open, in the entry’s own currency. This is the ceiling for amountToApply.
baseRemainingAmountThe same remaining amount converted to the company’s base currency at the entry’s booked rate.
versionConcurrency token. Pass it back on a settlement selection and the request is refused if the entry changed in the meantime.
prepaymentKindWhat the held credit is, on PREPAYMENT rows only. ADVANCE is money toward future invoices; HELD_DEPOSIT is a security deposit held and owed back; REFUNDABLE is money that bought nothing — a double payment or an overpayment the counterparty wants returned. All three settle against an invoice the same way; the kind says what the balance is for.
bookedExchangeRateThe rate that converted this entry to base currency when it was booked. Null when the entry is already in base currency.
dueDateWhen the document falls due (YYYY-MM-DD). Null on payments and on documents carrying no due date.
daysOverdueWhole days past due as of the request’s cut-off; 0 means not yet due. Null on payments and prepayments, neither of which is a claim.
journalEntryIdThe journal entry behind this row, when one exists. Null on an imported entry with no backing entry.
PublicOpenEntriesCurrencyTotal
currency3-letter ISO currency code.
remainingTotalSigned sum of the listed rows’ remaining amounts in this currency.
PublicOpenEntriesTotals
One total per currency the listed entries are denominated in.
baseCurrencyOutstandingThe counterparty’s authoritative outstanding balance in the company’s base currency. It includes the opening balance, which the rows deliberately do not carry — so summing baseRemainingAmount across the rows does NOT reproduce it. Read this figure; never derive one.
PublicOpenEntriesResponse
baseCurrencyThe company’s base currency (3-letter ISO).
asOfThe date this response answers as of. Always present — it is the requested cut-off, or today when none was given, so it does not tell you which was asked for.
The counterparty’s open entries.
PublicSettlementListItem
idID of the settlement.
postingDateAccounting date the settlement posted on (YYYY-MM-DD).
createdAtWhen the settlement was recorded.
counterpartyTypecounterpartyIdThe customer or supplier the entries belong to.
reversedWhether the settlement has been reversed. A reversed settlement contributes nothing — its entries are open again.
baseAmountSettledTotal value settled, in the company’s base currency.
reversedAtWhen it was reversed. Null while it stands.
reversalReasonWhy it was reversed. Null while it stands.
residualJournalEntryIdThe journal entry carrying the difference, when the entries did not net to zero. Null when they balanced exactly.
PublicSettlementsResponse
baseCurrencyThe company’s base currency (3-letter ISO).
PublicSettlementEntry
kindtypeidThe entry that was settled — the same id the open-entries listing reports.
referenceInvoice number, payment reference, or anchor number.
datePosting date of the entry (YYYY-MM-DD).
currencyCurrency of the entry (3-letter ISO).
originalAmountThe entry’s full signed amount in its own currency. A settlement may consume only part of it, so compare against appliedAmount.
appliedAmountSigned amount this settlement applied, in the entry’s currency.
baseAmountAppliedThe same applied amount in the company’s base currency.
journalEntryIdThe journal entry behind it, when one exists.
PublicSettlementDifferenceLeg
accountIdThe ledger account posted to.
accountNumberAccount number as it appears in the chart of accounts.
accountNameAccount name.
typeWhich side the amount posted on.
baseAmountMagnitude in base currency — always positive; the side is on type.
PublicSettlementDifference
journalEntryIdThe journal entry carrying the difference.
descriptionWhat the posting says it is — this is where an exchange difference is distinguished from a write-off.
PublicSettlement
idID of the settlement.
postingDateAccounting date the settlement posted on (YYYY-MM-DD).
createdAtWhen the settlement was recorded.
counterpartyTypecounterpartyIdThe customer or supplier the entries belong to.
reversedWhether the settlement has been reversed. A reversed settlement contributes nothing — its entries are open again.
baseCurrencyThe company’s base currency (3-letter ISO).
The entries this settlement linked, and how much of each it applied.
reversedAtWhen it was reversed. Null while it stands.
reversalReasonWhy it was reversed. Null while it stands.
differenceThe difference posting, when the entries did not net to zero. Null when they balanced exactly.
PublicSettlementEntrySelection
kindThe kind the open-entries listing reported for this entry. Echo it back unchanged.
idThe id the open-entries listing reported for this entry.
amountToApplyHow much of the entry to apply, in the entry’s own currency.
Always positive — send the absolute value. The open-entries listing reports a credit note or a
payment with a NEGATIVE remainingAmount, and passing that figure back is refused. Which direction an
entry moves the balance follows from what it is, so the sign is never yours to state: take
Math.abs(remainingAmount), and at most that.
The response signs it for you — an entry consumed reads negative, one that consumes reads positive.
versionThe version the open-entries listing reported. Supplying it refuses the settlement if the entry was
EDITED or REVERSED in between; omitting it settles against whatever the entry is now.
It does not move when another settlement applies to the same entry, so an unchanged version is not a
promise that the entry still has as much open as it did. Applying more than remains is refused on its
own, against the amount at the moment of the write rather than the one you read.
PublicSettleRequest
postingDateAccounting date to post the settlement on (YYYY-MM-DD).
The entries to settle against each other — at least two, since a settlement links something owed to something that pays it. All must belong to the named counterparty.
customerIdRead the customer’s entries. Mutually exclusive with supplierId; exactly one is required.
supplierIdRead the supplier’s entries. Mutually exclusive with customerId; exactly one is required.
idempotencyKeyYour own key for this settlement. Sending the same key with the same body returns the original settlement instead of posting a second one, so a retry after a timeout is safe.
PublicSettlementPreviewEntry
idThe entry, as named in the request.
kindappliedAmountSigned amount that would be applied, in the entry’s own currency.
baseAmountAppliedThe same amount in the company’s base currency.
exchangeRateRate used to convert it.
rateSourcestatusAfterWhat this entry’s status becomes. Null for a payment, which carries no status of its own.
fullyConsumedAfterWhether a payment is used up entirely. Null for anything that carries a status instead.
PublicSettlementDifferencePreview
kindbaseAmountThe difference in the company’s base currency, signed: it is the net of baseAmountApplied across the entries — what the applied amounts leave uncancelled. Zero when the entries balance.
labelWhat the difference is, in words — for example "Realized FX gain".
accountThe account the difference would post to. Null when there is nothing to post.
PublicSettlementPostingLine
accountIdThe ledger account posted to.
accountLabelAccount number and name.
currencyCurrency of the line (3-letter ISO).
originalAmountSigned amount in that currency.
exchangeRateRate used to convert it.
baseAmountThe same amount in the company’s base currency.
kindPublicSettlementRateGapCurrency
currencyminRateLowest rate any selected entry in this currency was booked at.
maxRateHighest rate any selected entry in this currency was booked at.
spreadHow far apart the two are, as a fraction of the higher one.
PublicSettlementPreview
baseCurrencyThe company’s base currency (3-letter ISO).
postingDateAccounting date the settlement would post on.
What each named entry would have applied to it, and what it becomes.
The lines that would post. Empty when the entries balance and nothing needs a posting.
blockersError codes that would refuse the settlement. A non-empty list means the commit fails with the first of them.
warningsCodes for things worth checking. The settlement would still post.
Which currencies’ entries disagree about the rate, widest first. Present only alongside the rate-gap warning, and null otherwise — it names the rates to check the booked ones against.
PublicSettlementCreated
idThe settlement. Read it back at GET /v1/settlements/{id}.
differenceJournalEntryIdThe journal entry carrying the difference, when the entries did not net to zero. Null when they balanced exactly.
vatReclassJournalEntryIdThe journal entry that moved a prepayment’s VAT onto the invoice it was applied to. Null unless the settlement did that.
CreateProductPriceRequest
productIdThe product this price belongs to
billingPeriodTypeBilling period type. RECURRING and USAGE both require a Subscription license.
pricingModelPricing model
nicknameOptional nickname (e.g. "Monthly")
statusInitial status. Defaults to active, so the price is usable immediately. Pass draft to stage it and publish it later via the activate endpoint.
unitAmountUnit amount. Required for FLAT_RATE pricing; for tiered models (PACKAGE/VOLUME/GRADUATED) the amounts live in tiers.
billingIntervalBilling interval (required unless one-time)
billingIntervalCountBilling interval count
currencyCurrency code (ISO 4217). Defaults to the company default.
meterIdMeter ID (required for USAGE pricing)
Pricing tiers. Required for tiered models: PACKAGE (exactly 1), VOLUME / GRADUATED (one or more, last tier open-ended). Omit for FLAT_RATE.
UpdateProductPriceRequest
nicknameOptional nickname
unitAmountUnit amount for flat-rate pricing
billingPeriodTypeBilling period type
pricingModelPricing model
billingIntervalBilling interval (null for one-time)
billingIntervalCountBilling interval count
currencyCurrency code (ISO 4217)
statusPrice status
meterIdMeter ID for usage-based pricing
Pricing tiers
DocumentTemplateListItem
idThe unique identifier of the template
nameTemplate name
documentTypeDocument type this template applies to
isDefaultWhether this is the default template for its document type
createdAtWhen the template was created
updatedAtWhen the template was last updated
ListDocumentTemplatesResponse
Page of document templates
totalTotal number of matching templates
pageCurrent page number
limitItems per page
totalPagesTotal number of pages
BudgetSummary
idThe unique identifier of the budget
nameBudget name
statusBudget status. Informational — the status does not restrict reads.
accountingYearIdAccounting year the budget covers
accountingYearStartDateAccounting year start date (ISO date, YYYY-MM-DD)
accountingYearEndDateAccounting year end date (ISO date, YYYY-MM-DD)
currencyISO 4217 currency every amount on this budget is denominated in — the company's base (functional) currency.
createdAtWhen the budget was created (ISO 8601)
updatedAtWhen the budget was last updated (ISO 8601)
dimensionCategoryIdDimension category scoping this budget: lines then carry per-dimension-value buckets. null for flat budgets.
ListBudgetsResponse
Page of budgets
totalTotal number of matching budgets
pageCurrent page number
limitItems per page
totalPagesTotal number of pages
BudgetRunwayResponse
currencyISO 4217 currency every amount is denominated in — the company's base (functional) currency.
cashOnHandSum of bank-account-linked ledger balances as of asOf (decimal string)
trailing3MonthBurnTrailing average net outflow over the last 3 closed months (decimal string). Negative when the company is cash-positive.
monthsRemainingCash divided by burn; null = infinite runway (burn ≤ 0)
statusOK (≥ 6 months), WATCH (3-6), LOW (< 3), or UNKNOWN (no cash source, or no closed periods to compute burn from — see hasCashSource).
hasCashSourceWhether at least one bank account is linked to a ledger account. When false, cashOnHand is a meaningless 0.
asOfISO date the cash and burn were computed as of
feedReportedCashTotalSum of provider-reported balances over active bank accounts in the functional currency (decimal string). null when any active account is held in another currency.
unlinkedBankAccountCountActive bank accounts with no linked ledger account — invisible to cashOnHand.
BudgetLine
idThe unique identifier of the budget line
ledgerIdLedger account this line budgets
ledgerNameLedger account name
accountNumberLedger account number
accountingPeriodIdAccounting period this cell belongs to (see periods)
amountBudgeted amount in the budget's currency (decimal string). For CLOSED periods this is the book actual (the cell then carries source: ACTUALS), matching the rolling-forecast grid the app shows.
dimensionValueIdDimension value bucket. null = the Unallocated bucket; absent for flat budgets.
formulaFormula text (e.g. =baseline*1.05), or null for a plain literal cell.
inputMethodHow the cell was entered. Absent on legacy rows (treat as MANUAL).
sourceProvenance of the value: ACTUALS = closed-period book actual; SUBSCRIPTION = filled from the subscription forecast. null/absent = user-entered.
errorPer-cell formula evaluation error code, when the cell could not resolve. null/absent = resolved.
baselinePrior accounting year's realised amount for the same account and calendar month (decimal string). null unless requested with ?includeBaseline=true.
BudgetPeriod
idAccounting period id
labelPeriod label
startDatePeriod start date (ISO date, YYYY-MM-DD)
endDatePeriod end date (ISO date, YYYY-MM-DD)
periodIndexPeriod index within the accounting year (1-12)
statusOPEN or CLOSED. Lines in CLOSED periods show the book actuals (rolling forecast), not the planned amount.
BudgetDriverCell
idThe unique identifier of the driver cell
accountingPeriodIdAccounting period this cell belongs to (see periods)
valueResolved value. Drivers are quantities (headcount, ARPU, …), not money, so this is a number.
formulaFormula text, or null for a plain literal cell.
errorPer-cell formula evaluation error code, when the cell could not resolve. null/absent = resolved.
BudgetDriverRow
idThe unique identifier of the driver row
nameDisplay name
handleStable token used to reference this row in formulas
displayOrderDisplay order among the driver rows
Per-period cells
unitUnit label (e.g. "FTE", "%").
BudgetRowOverride
ledgerIdLedger account the override applies to
isHiddenWhether the row is hidden from the editor (still counted in totals).
labelBudget-local display name overriding the account name. null = default name.
BudgetRowNumber
lineNumberStable reference number used by #N formula references
ledgerIdLedger account this number belongs to. Exactly one of ledgerId / driverRowId is set.
driverRowIdDriver row this number belongs to. Exactly one of ledgerId / driverRowId is set.
BudgetDetail
idThe unique identifier of the budget
nameBudget name
statusBudget status. Informational — the status does not restrict reads.
accountingYearIdAccounting year the budget covers
accountingYearStartDateAccounting year start date (ISO date, YYYY-MM-DD)
accountingYearEndDateAccounting year end date (ISO date, YYYY-MM-DD)
currencyISO 4217 currency every amount on this budget is denominated in — the company's base (functional) currency.
createdAtWhen the budget was created (ISO 8601)
updatedAtWhen the budget was last updated (ISO 8601)
Budget cells (one per account × period, and per dimension bucket when dimensioned)
The accounting year's periods, ordered by periodIndex
Driver rows with resolved cells (non-money quantities)
Budget-local display overrides. Only accounts carrying an override are listed.
Stable #N row numbers used by formula references. Rows never numbered in the editor may be absent.
dimensionCategoryIdDimension category scoping this budget: lines then carry per-dimension-value buckets. null for flat budgets.
BudgetScenario
idThe unique identifier of the scenario
nameScenario name
isBaselineTrue for the "Base" overlay — the budget grid with no scenario assumptions applied. The Base scenario is created when the tenant first uses scenarios in the app, so a budget may not have one yet.
createdAtWhen the scenario was created (ISO 8601)
updatedAtWhen the scenario was last updated (ISO 8601)
descriptionScenario description
ListBudgetScenariosResponse
The budget's scenarios
BudgetScenarioGridResponse
currencyISO 4217 currency every amount is denominated in — the company's base (functional) currency.
All resolved budget cells under the scenario overlay
All driver rows with resolved cells under the overlay
hasCycleTrue when the overlay could not resolve because of a formula cycle — offending cells carry error: BUDGET_FORMULA_CYCLE and amounts must not be trusted.
forecastHorizonMonthLast calendar month (YYYY-MM) with a subscription-forecast projection. Cells past it that reference the subscription forecast resolve to 0. null when no subscription token is used.
BudgetComparisonSummary
totalBudgetTotal budgeted amount (decimal string)
totalActualTotal actual amount (decimal string)
totalVarianceTotal variance, budget − actual (decimal string)
totalVariancePercentTotal variance as a percentage of budget; null when the budget is 0
isOverBudgetTrue when total actual exceeds total budget
BudgetComparisonEntry
ledgerIdLedger account
ledgerNameLedger account name
accountNumberLedger account number
periodIdAccounting period (see periods)
budgetAmountBudgeted amount (decimal string)
actualAmountActual amount from the ledger (decimal string)
varianceVariance, budget − actual (decimal string)
variancePercentVariance as a percentage of budget; null when the budget is 0
isOverBudgetTrue when the variance is unfavourable: actual above budget on expense accounts, actual below budget on revenue accounts.
isRevenueAccountTrue for revenue (credit-normal) accounts; false for expense (debit-normal) accounts
dimensionValueIdDimension value bucket. null = the Unallocated bucket; absent for flat budgets.
BudgetComparisonResponse
budgetNameBudget name
currencyISO 4217 currency every amount is denominated in — the company's base (functional) currency.
Summary totals for the comparison
Comparison entries by account and period
The periods covered by the comparison
BudgetVarianceRow
ledgerIdLedger account
accountNameLedger account name
accountTypeNormal side of the account: DEBIT (expense-like) or CREDIT (revenue-like)
periodIdAccounting period
frozenBaselineAmount in the frozen baseline (decimal string)
actualActual amount from the ledger (decimal string)
varianceVariance, actual − frozen baseline (decimal string)
variancePercentVariance as a percentage of the absolute baseline; null when the baseline is 0
sentimentUnfavourable when spending exceeds the frozen plan (expense accounts) or revenue misses it (revenue accounts).
BudgetVarianceResponse
currencyISO 4217 currency every amount is denominated in — the company's base (functional) currency.
Closed-period variance rows vs the frozen baseline. Empty when the budget has no frozen baseline yet.
BudgetFrozenBaselineSummary
idThe unique identifier of the frozen baseline
labelLabel given when the baseline was frozen
frozenAtWhen the baseline was frozen (ISO 8601)
cellCountNumber of snapshot cells
scenarioIdScenario whose overlay was snapshotted. null = the base grid.
frozenByIdentity that froze the baseline
ListBudgetFrozenBaselinesResponse
The budget's frozen baselines, most recent first
BudgetFrozenBaselineCell
idThe unique identifier of the snapshot cell
ledgerIdLedger account
accountingPeriodIdAccounting period
amountFrozen resolved amount (decimal string)
dimensionValueIdDimension value bucket. null = the Unallocated bucket; absent for flat budgets.
sourceProvenance of the cell at freeze time
BudgetFrozenBaselineDetail
idThe unique identifier of the frozen baseline
labelLabel given when the baseline was frozen
frozenAtWhen the baseline was frozen (ISO 8601)
currencyISO 4217 currency every amount is denominated in — the company's base (functional) currency.
Snapshot cells
scenarioIdScenario whose overlay was snapshotted. null = the base grid.
frozenByIdentity that froze the baseline
BudgetRebaselineProposal
idThe unique identifier of the proposal
accountingPeriodIdThe closed accounting period the proposal was raised for
statusPROPOSED (open), CONFIRMED (accepted — the budget was recomputed forward), or REJECTED.
proposedAtWhen the proposal was raised (ISO 8601)
confirmedAtWhen the proposal was confirmed. null while open or rejected.
ListBudgetRebaselineProposalsResponse
The budget's re-baseline proposals
ProjectSubproject
idUnique identifier of the subproject.
dimensionValueIdThe journal-tag value ID that represents this subproject in the dimensions system. Use this value when tagging ledger transactions to the subproject.
nameDisplay name of the subproject.
isDefaultWhether this is the default (catch-all) subproject for the project.
sortOrderDisplay sort order (ascending).
budgetHoursBudget in hours for this subproject. Null when no budget is set.
budgetAmountBudget amount in the project currency for this subproject. Null when no budget is set.
colorHex colour code for visual identification in the UI. Null when not set.
Project
idUnique identifier of the project.
nameDisplay name of the project.
isArchivedWhether the project has been archived. Archived projects are read-only.
currencyISO 4217 currency code used for budget amounts on this project.
dimensionIdThe shared "Projects" dimension category ID (journal-tag category) that backs every project in your company. Subproject values live as dimension values under this category, nested beneath this project's own dimension value (dimensionValueId).
defaultSubprojectIdID of the default subproject (the catch-all subproject created with the project).
All subprojects for this project, sorted by sortOrder ascending.
createdAtISO 8601 timestamp when the project was created.
updatedAtISO 8601 timestamp when the project was last updated.
customerIdID of the customer this project belongs to. Null when not linked to a customer.
budgetHoursTotal budget in hours across all subprojects. Null when not set.
budgetAmountTotal budget amount in the project currency. Null when not set.
startDateProject start date (inclusive), ISO 8601 date string. Null when not set.
endDateProject end date (inclusive), ISO 8601 date string. Null when not set.
externalReferenceYour system external reference for this project. Useful for idempotent upserts and cross-system reconciliation. Null when not set.
colorHex colour code for visual identification. Null when not set.
dimensionValueIdThe project's own dimension value (journal-tag) ID inside the shared Projects category. Subprojects are nested as dimension values beneath this value. Null only for a project in a corrupt state with no journal-tag.
UpsertProjectRequest
nameDisplay name for the project. Must be unique within your company.
customerIdID of the customer this project belongs to.
currencyISO 4217 currency code for budget amounts. Defaults to the customer's currency or the company base currency when omitted.
budgetHoursTotal budget in hours. Null clears the budget.
budgetAmountTotal budget amount in the project currency. Null clears the budget.
startDateProject start date (inclusive), ISO 8601 date string.
endDateProject end date (inclusive), ISO 8601 date string.
externalReferenceYour system external reference for this project. Must be unique within your company. The upsert finds an existing project by this value and updates it, or creates a new one.
colorHex colour code for visual identification.
CreateProjectRequest
nameDisplay name for the project. Must be unique within your company.
customerIdID of the customer this project belongs to.
currencyISO 4217 currency code for budget amounts. Defaults to the customer's currency or the company base currency when omitted.
budgetHoursTotal budget in hours. Null clears the budget.
budgetAmountTotal budget amount in the project currency. Null clears the budget.
startDateProject start date (inclusive), ISO 8601 date string.
endDateProject end date (inclusive), ISO 8601 date string.
externalReferenceYour system external reference for this project. Must be unique within your company. Can be used for idempotent upserts via PUT /.
colorHex colour code for visual identification.
ProjectProfitTotals
revenueBase-currency revenue in the date range (positive figure, sign-flipped from REVENUE ledgers).
costBase-currency cost in the date range (positive figure, EXPENSE ledgers).
profitrevenue - cost.
isOverBudgetTrue when burnPercent > 100 (over budget). False when under budget or no budget.
budgetAmountThe budget amount this burn is measured against. Null when no budget is set.
burnPercentcost / budgetAmount * 100, rounded. Null when no budget is set or budgetAmount is 0.
ProjectSubprojectProfit
revenueBase-currency revenue in the date range (positive figure, sign-flipped from REVENUE ledgers).
costBase-currency cost in the date range (positive figure, EXPENSE ledgers).
profitrevenue - cost.
isOverBudgetTrue when burnPercent > 100 (over budget). False when under budget or no budget.
subprojectIdSubproject ID.
dimensionValueIdThe dimension value ID (journal-tag ID) for this subproject.
nameDisplay name of the subproject.
isDefaultWhether this is the default (catch-all) subproject.
budgetAmountThe budget amount this burn is measured against. Null when no budget is set.
burnPercentcost / budgetAmount * 100, rounded. Null when no budget is set or budgetAmount is 0.
ProjectProfit
projectIdProject ID.
fromInclusive range start actually used (after defaulting), YYYY-MM-DD.
toInclusive range end actually used (after defaulting), YYYY-MM-DD.
currencyCompany base currency the amounts are expressed in.
Aggregate totals for the project.
Per-subproject profit breakdown.
UpdateProjectRequest
nameNew display name for the project.
customerIdCustomer ID. Null clears the customer link.
currencyISO 4217 currency code.
budgetHoursBudget in hours. Null clears the budget.
budgetAmountBudget amount in the project currency. Null clears the budget.
startDateProject start date (inclusive), ISO 8601. Null clears the date.
endDateProject end date (inclusive), ISO 8601. Null clears the date.
externalReferenceExternal reference. Null clears the value.
colorHex colour code. Null clears the value.
isArchivedArchive or un-archive the project.
CreateSubprojectRequest
nameDisplay name for the subproject.
budgetHoursBudget in hours for this subproject. Null clears the budget.
budgetAmountBudget amount in the project currency. Null clears the budget.
colorHex colour code. Null clears the value.
sortOrderSort order (ascending). Defaults to 0.
UpdateSubprojectRequest
nameNew display name for the subproject.
budgetHoursBudget in hours. Null clears the budget.
budgetAmountBudget amount in the project currency. Null clears the budget.
colorHex colour code. Null clears the value.
sortOrderSort order (ascending).
UsageReportRequestDto
valueThe numeric value of this usage event. How it is used depends on the meter's aggregation method: summed (sum) or taken as the latest value (last). For count meters the value is ignored, but a non-negative number is still required.
customerIdCustomer ID this usage is associated with.
meterIdMeter identifier. Provide meterId or meterName. Meter must be ACTIVE; usage will be rejected for archived meters.
meterNameMeter name. Provide meterId or meterName. Meter must be ACTIVE; usage will be rejected for archived meters.
timestampISO-8601 timestamp. Defaults to now.
dimensionWhat the quantity is measured PER — a seat, a device, a user. Only a meter using the max_per_dimension aggregation reads it; every other aggregation ignores it.
This is a GROUPING key, not a label: the meter bills the peak each dimension reached, added together, so the value must identify a thing that persists across reports. Put descriptive detail in metadata instead, which is never aggregated on.
A value that is unique per report defeats the aggregation, and a meter is refused new dimensions once it carries too many distinct values.
metadataAdditional metadata for the usage event (values must be string, number, or boolean)