LedgerBee Developer
  • Getting started
  • Conventions
  • Products
  • Advisor firms
  • Configuration
  • API Reference
Information
Accounts
    List accountsgetCreate an accountpostGet an accountgetDelete an accountdeleteUpdate an accountpatch
Advisor Authority Extracts
    Submit authority extract data for an advisor firm's clientspost
Advisor Clients
    List the advisor firm's clientsget
API Key
    Get current API keyget
Authority Extracts
    Submit authority extract datapost
Bank Reconciliations
    Reconcile bank lines against entriespostUndo a bank reconciliationpostCheck what undoing a reconciliation would dopostReconcile a batch of matchespostCheck what reconciling a batch of matches would dopostCheck what reconciling bank lines against entries would dopost
Bank Transactions
    List bank linesgetGet a bank linegetDismiss bank lines from reconciliationpostCheck which bank lines a dismiss would changepostRestore dismissed bank lines to reconciliationpostCheck which bank lines a restore would changepost
Billing Groups
    Form a billing grouppostGet a billing groupgetAdd members to a billing grouppostRemove a member from a billing groupdeleteCheck billing group eligibilitypost
Budgets
    List budgetsgetGet a budgetgetGet the budget vs actuals comparisongetExport a budget's Excel workbookgetOverwrite a budget's figures from an edited workbookpostList a budget's frozen baselinesgetGet a frozen baseline with its snapshot cellsgetList a budget's re-baseline proposalsgetList a budget's scenariosgetResolve a budget's grid under a scenariogetGet the variance report vs a frozen baselinegetGet the runway headlineget
Checkout
    Confirm the checkoutpostQuote a first periodpostIntegration readinessgetMint a checkout sessionpostRehydrate a sessiongetRelease the card hold (edit-after-card)postPoll card statusgetOpen the card windowpostOpen a card window for a live subscriptionpost
Company
    Get company detailsget
Connected app OAuth
    JSON Web Key Set used to verify OAuth access-token signaturesgetRFC 8414 authorization-server metadata for the connected-app OAuth servergetRFC 9728 protected-resource metadata for an MCP resourcegetRFC 9728 protected-resource metadata for an MCP resourcegetOpenID Connect discovery document for the connected-app OAuth serverget
Credit Note Links
    Link a credit note to the invoice it creditspostCheck a credit note’s links and the invoices it can be linked topostDetach a credit note from the invoices it is applied topost
Credit Notes
    List credit notesgetCreate a credit notepostGet a credit notegetGet the delivery status of a credit notegetDownload the credit note PDFgetSend a credit note to the customerpostCredit a whole invoicepost
Customers
    List customersgetCreate a customerpostGet a customergetDelete a customerdeleteUpdate a customerpatchList a customer's contactsgetList a customer's departmentsgetList customer groupsget
Dimensions
    List all dimensionsgetCreate a new dimension categorypostGet a dimensiongetUpdate a dimension categoryputDelete a dimension categorydeleteList distribution keys (paginated)getCreate a distribution keypostGet a distribution keygetList dimension values (paginated)getCreate a new dimension valuepostUpdate a dimension valueputDelete a dimension valuedelete
Discounts
    List discountsgetCreate a discountpostGet a discountgetDelete a discountdeleteUpdate a discountpatchSet a discount's amount in one currencyputRemove a discount's amount in one currencydeleteCheck whether a discount applies to a product for a customer on a daygetAssign a discountpostRemove an assignmentdeleteUpdate an assignmentpatchList a discount's codesgetAdd a code to a discountpostDelete a codedeleteUpdate a codepatchList the discounts that apply to a product for a customer on a daygetCheck a cartpostLook up a discount codeget
Document Templates
    List document templatesget
Document Upload Links
    Upload a file through a minted linkpost
Download Links
    Mint a download link for a document PDFgetDownload a minted linkget
Draft Journal Entries
    Create multiple draft journal entries in batchpostList draft journal entriesgetCreate a draft journal entrypostGet a draft journal entrygetDelete a draft journal entrydeleteBook a draft journal entrypost
Draft Journal Entries (v2)
    Create draft journal entries in batch (v2)postList draft journal entries (v2)getCreate a draft journal entry (v2)postGet a draft journal entry (v2)getDelete a draft journal entry (v2)deleteUpdate a draft journal entry (v2)patchGet attachments for a draft journal entry (v2)getAdd a document to a draft journal entry (v2)postRemove a document from a draft journal entry (v2)deleteBook a draft journal entry (v2)post
Entitlements
    List entitlementsgetCreate an entitlementpostGet an entitlementgetDelete an entitlementdeleteUpdate an entitlementpatch
Invoices
    List invoicesgetCreate a draft invoicepostGet an invoicegetDelete a draft invoicedeleteUpdate an unsent invoicepatchGet the delivery status of an invoicegetDownload the invoice PDFgetSend an invoice to the customerpost
Journal Categories
    List journal categoriesgetCreate a journal categorypostUpdate a journal categoryputDelete a journal categorydelete
Journal Entries
    List journal entriesgetGet a journal entrygetUpdate a journal entry — correct the reference and/or set your external system idpatchGet attachments for a journal entrygetAdd a document to a journal entrypostRemove a document from a journal entrydeletePreview a correction without posting itpostMove postings to different accounts, keeping the document intactpostRebuild the entry a reversal undid, as a draftpostPreview rebuilding the entry a reversal undidpostReverse a posted entry and open a draft to re-enter itpostReverse posted journal entries in batchpostPreview reversing posted journal entries in batchpostReverse a posted journal entrypostPreview reversing a posted journal entrypost
Journal Entries (v2)
    Create a journal entry (v2)postCreate journal entries in batch (v2)post
MCP
    LedgerBee Developer MCP Serverpost
Meters
    List meter subscriptions by IDgetReport usagepostList meter subscriptions by nameget
Open Entries
    List a counterparty’s open entriesget
Order Confirmations
    List order confirmationsgetCreate a draft order confirmationpostGet an order confirmationgetUpdate a draft order confirmationpatchConvert an order confirmation into an invoicepostDownload an order confirmation as PDFgetSend an order confirmationpost
Payment Methods
    List saved payment methods for a customergetCancel a saved card on the payment providerdeleteUnassign a payment method from a customerdeleteGenerate a link for the customer to save a card for future paymentspostSet a saved payment method as the customer defaultput
Portal Plans
    List the full plan cataloguegetGet a plangetResolve the gated pricing catalogue for an identified buyer (partner display)post
Portal SSO
    Get a tenant's SSO signing keys (JWKS)getMint a checkout-vouch token (partner-vouched anonymous checkout)postMint a customer-portal SSO handoff referencepostProvision a customer + grant portal access (partner JIT provisioning)postRevoke (force-refresh) a user's customer-portal sessionspost
Product Groups
    List product groupsgetCreate a product grouppostGet a product groupgetDelete a product groupdeleteUpdate a product grouppatch
Product Prices
    Create a product pricepostGet a product pricegetDelete a product pricedeleteUpdate a product pricepatchActivate a product pricepostArchive a product pricepostDisable a product pricepostSet a price as the product defaultpost
Products
    List productsgetCreate a productpostGet a productgetDelete a productdeleteUpdate a productpatchArchive a productpost
Projects
    List all projectsgetCreate or update a project by external referenceputCreate a projectpostGet a projectgetUpdate a projectputGet project profitgetAdd a subprojectpostUpdate a subprojectputDelete a subprojectdelete
Quotes
    List quotesgetCreate a draft quotepostGet a quotegetUpdate a draft quotepatchConvert a quotepostDownload a quote as PDFgetSend a quotepost
Settlements
    List a counterparty’s settlementsgetSettle open entries against each otherpostGet a settlementgetUndo a settlementpostCheck what undoing a settlement would dopostCheck what settling these entries would dopost
Shipments
    List shipmentsgetCreate a shipment from an orderpostGet a shipmentgetCancel a shipmentpostDispatch a shipmentpost
Stock
    List stock movementsgetList on-hand stockgetOn-hand for one productget
Subscriptions
    List customer subscriptionsgetAssign a subscription to a customerpostGet a customer subscription by its stable idgetUpdate a customer subscriptionpatchAdd an add-on to a customer subscriptionpostAttach existing subscriptions as add-onspostCheck whether subscriptions can become add-onspostChange the products on a customer subscriptionpostRetry a failed card paymentpostList a subscription's pending scheduled changesgetCancel a single pending scheduled changedeleteGet a subscription's unbilled usagegetCancel a customer subscriptionpostList subscription plansgetCreate a subscription planpostArchive a subscription planpost
Suppliers
    List suppliersgetCreate a supplierpostDelete a supplierdeleteList supplier contactsgetList supplier departmentsgetList supplier groupsget
VAT Codes
    List VAT codesgetCreate a VAT codepostGet a VAT codegetDelete a VAT codedeleteUpdate a VAT codepatch
VAT periods
    Record a VAT return filed outside LedgerBeepostPreview recording a VAT return filed outside LedgerBeepostSettle a filed VAT periodpostPreview a VAT period settlementpost
Vendors
    List vendorsgetCreate a vendorpostList vendor contactsgetList vendor departmentsgetList vendor groupsget
Webhook Endpoints
    List webhook endpointsgetCreate a webhook endpointpostRetrieve a webhook endpointgetUpdate a webhook endpointputDelete a webhook endpointdeleteRoll the signing secretpostSend a test eventpost
Schemas
LedgerBee Public API
LedgerBee Public API

Discounts

Download schema

List discounts

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

Credential: a company's API key or OAuth token.

Retrieves a paginated list of your company's discounts, each with its amounts per currency and its assignments, ordered by priority (lowest first), then name.

Pass ?active=true or ?active=false, ?type= and ?scope= to narrow the list; total counts the filtered set.

Required Scope

  • products-read

List discounts › query Parameters

page
​number · min: 1 · max: 100000

Page number (1-indexed)

Default: 1
limit
​number · min: 1 · max: 100

Maximum number of items per page

Default: 25
active
​string · enum

true lists active discounts only, false inactive ones only. Omitted: both.

Enum values:
true
false
type
​DiscountType · enum

Only discounts of this type.

Enum values:
percentage
fixed
per_unit
scope
​DiscountScope · enum

Only discounts of this scope.

Enum values:
line
document

List discounts › Responses

Paginated list of discounts for the company

ListDiscountsResponse
​DiscountResponse[] · required

Page of discounts, ordered by priority (lowest first), then name.

total
​number · required

Total number of matching discounts

Example: 3
page
​number · required

Current page number

Example: 1
limit
​number · required

Items per page

Example: 25
totalPages
​number · required

Total number of pages

Example: 1
GET/v1/discounts
curl https://api.ledgerbee.com/api/v1/discounts \ --header 'x-api-key: <api-key>'
Example Responses
{ "data": [ { "id": "0199b6d2-3c1a-7a40-9f00-1d2e3f4a5b6c", "name": "Black Friday", "type": "percentage", "scope": "line", "percentagePct": "10.0000", "priority": 0, "combinable": true, "active": true, "requiresCode": true, "maxRedemptions": 0, "maxPerCustomer": 0, "durationInPeriods": 0, "amounts": [ { "currency": "DKK", "amount": "50.00" } ], "assignments": [ { "id": "0199b6d2-3c1a-7a40-9f00-1d2e3f4a5b6c", "discountId": "discountId", "productId": "productId", "productGroupId": "productGroupId", "customerId": "customerId", "customerGroupId": "customerGroupId", "startsAt": "2026-11-27", "endsAt": "2026-11-30" } ] } ], "total": 3, "page": 1, "limit": 25, "totalPages": 1 }
json
application/json

Create a discount

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

Credential: a company's API key or OAuth token.

Creates a discount. A percentage discount states percentagePct; a fixed or per_unit discount states one positive amount per currency in amounts, and is never converted between currencies. The type cannot change after creation. A per_unit discount takes line scope only; document scope is refused with DISCOUNT_PER_UNIT_NEEDS_LINE_SCOPE.

A new discount has no assignments, so it applies nowhere until one is added with POST /v1/discounts/{discountId}/assignments.

A discount is applied only to a document line or a document that references its id. Creating, changing or assigning a discount changes no document on its own.

Required Scope

  • products-write

Create a discount › Headers

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

Optional idempotency key for safely retrying mutating requests.

Create a discount › Request Body

CreateDiscountRequest
name
​string · required

Printed as the reason on the e-invoice allowance.

Example: Loyalty 10%
type
​string · enum · required

percentage takes a percent off; fixed takes an amount off, per eligible line for a line discount or once per document for a document discount; per_unit takes an amount off each unit on a line and takes line scope only. The type cannot change after the discount is created.

Enum values:
percentage
fixed
per_unit
scope
​string · enum · required

line applies to each eligible line on its own. document applies once per document, after every line discount, when the customer matches and at least one line has an eligible product. A per_unit discount with document scope is refused with DISCOUNT_PER_UNIT_NEEDS_LINE_SCOPE.

Enum values:
line
document
percentagePct
​string

Required for a percentage discount, refused for other types: the percent off, above 0 and at most 100, with at most 4 decimals. Outside that range: DISCOUNT_INVALID_PERCENTAGE.

Example: 10
priority
​number

The order the server applies discounts in when it picks them itself; lowest first. Defaults to 0.

Example: 0
combinable
​boolean

False: a line may not reference this discount together with another one. Defaults to true.

active
​boolean

An inactive discount applies nowhere. Defaults to true.

requiresCode
​boolean

True: the discount applies only through one of its codes. A document or an applicability check that names it by its id alone is refused with the reason codeRequired, and GET /v1/discounts/applicable leaves it out. Defaults to false.

maxRedemptions
​number | null

Total uses allowed. Null or omitted: no limit.

maxPerCustomer
​number | null

Uses allowed per customer. Null or omitted: no limit.

durationInPeriods
​number | null · min: 1

How many billing periods the discount lasts on a subscription that references it. Null or omitted: for as long as the reference stands.

​DiscountAmount[]

Fixed and per-unit discounts only: one positive amount per currency, each currency at most once. Amounts are never converted between currencies. Refused on a percentage discount.

Create a discount › Responses

Discount created

DiscountResponse
id
​string · required

The discount ID.

Example: 0199b6d2-3c1a-7a40-9f00-1d2e3f4a5b6c
name
​string · required

Printed as the reason on the e-invoice allowance.

Example: Black Friday
type
​string · enum · required

percentage takes a percent off; fixed takes an amount off, per eligible line for a line discount or once per document for a document discount; per_unit takes an amount off each unit on a line and takes line scope only. The type cannot change after the discount is created.

Enum values:
percentage
fixed
per_unit
scope
​string · enum · required

line applies to each eligible line on its own. document applies once per document, after every line discount, when the customer matches and at least one line has an eligible product. A per_unit discount with document scope is refused with DISCOUNT_PER_UNIT_NEEDS_LINE_SCOPE.

Enum values:
line
document
percentagePct
​string | null · required

Percentage discounts only: the percent taken off, above 0 and at most 100. Null for other types.

Example: 10.0000
priority
​number · required

The order the server applies discounts in when it picks them itself; lowest first.

Example: 0
combinable
​boolean · required

False: a line may not reference this discount together with another one.

active
​boolean · required

An inactive discount applies nowhere.

requiresCode
​boolean · required

True: the discount applies only through one of its codes. A document or an applicability check that names it by its id alone is refused with the reason codeRequired, and GET /v1/discounts/applicable leaves it out.

maxRedemptions
​number | null · required

Total uses allowed. Null: no limit.

maxPerCustomer
​number | null · required

Uses allowed per customer. Null: no limit.

durationInPeriods
​number | null · required

How many billing periods the discount lasts on a subscription that references it. Null: for as long as the reference stands.

​DiscountAmount[] · required

Fixed and per-unit discounts: one positive amount per currency, sorted by currency. Empty for a percentage discount. A discount is applied only to a document line or document that references its id; creating or assigning it changes no document on its own.

​DiscountAssignment[] · required

Where the discount applies: each assignment names a product, a customer and a window of days, any of them null for "all". A discount with no assignment applies nowhere.

POST/v1/discounts
curl https://api.ledgerbee.com/api/v1/discounts \ --request POST \ --header 'Content-Type: application/json' \ --header 'x-api-key: <api-key>' \ --data '{ "name": "Loyalty 10%", "type": "percentage", "scope": "line", "percentagePct": "10", "priority": 0, "combinable": true, "active": true, "requiresCode": true, "maxRedemptions": 0, "maxPerCustomer": 0, "durationInPeriods": 1, "amounts": [ { "currency": "DKK", "amount": "50.00" } ] }'
Example Request Body
{ "name": "Loyalty 10%", "type": "percentage", "scope": "line", "percentagePct": "10", "priority": 0, "combinable": true, "active": true, "requiresCode": true, "maxRedemptions": 0, "maxPerCustomer": 0, "durationInPeriods": 1, "amounts": [ { "currency": "DKK", "amount": "50.00" } ] }
json
application/json
Example Responses
{ "id": "0199b6d2-3c1a-7a40-9f00-1d2e3f4a5b6c", "name": "Black Friday", "type": "percentage", "scope": "line", "percentagePct": "10.0000", "priority": 0, "combinable": true, "active": true, "requiresCode": true, "maxRedemptions": 0, "maxPerCustomer": 0, "durationInPeriods": 0, "amounts": [ { "currency": "DKK", "amount": "50.00" } ], "assignments": [ { "id": "0199b6d2-3c1a-7a40-9f00-1d2e3f4a5b6c", "discountId": "discountId", "productId": "productId", "productGroupId": "productGroupId", "customerId": "customerId", "customerGroupId": "customerGroupId", "startsAt": "2026-11-27", "endsAt": "2026-11-30" } ] }
json
application/json

Get a discount

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

Credential: a company's API key or OAuth token.

Returns a discount with its amounts per currency and its assignments.

Required Scope

  • products-read

Get a discount › path Parameters

discountId
​string · required

Discount ID

Get a discount › Responses

Discount details

DiscountResponse
id
​string · required

The discount ID.

Example: 0199b6d2-3c1a-7a40-9f00-1d2e3f4a5b6c
name
​string · required

Printed as the reason on the e-invoice allowance.

Example: Black Friday
type
​string · enum · required

percentage takes a percent off; fixed takes an amount off, per eligible line for a line discount or once per document for a document discount; per_unit takes an amount off each unit on a line and takes line scope only. The type cannot change after the discount is created.

Enum values:
percentage
fixed
per_unit
scope
​string · enum · required

line applies to each eligible line on its own. document applies once per document, after every line discount, when the customer matches and at least one line has an eligible product. A per_unit discount with document scope is refused with DISCOUNT_PER_UNIT_NEEDS_LINE_SCOPE.

Enum values:
line
document
percentagePct
​string | null · required

Percentage discounts only: the percent taken off, above 0 and at most 100. Null for other types.

Example: 10.0000
priority
​number · required

The order the server applies discounts in when it picks them itself; lowest first.

Example: 0
combinable
​boolean · required

False: a line may not reference this discount together with another one.

active
​boolean · required

An inactive discount applies nowhere.

requiresCode
​boolean · required

True: the discount applies only through one of its codes. A document or an applicability check that names it by its id alone is refused with the reason codeRequired, and GET /v1/discounts/applicable leaves it out.

maxRedemptions
​number | null · required

Total uses allowed. Null: no limit.

maxPerCustomer
​number | null · required

Uses allowed per customer. Null: no limit.

durationInPeriods
​number | null · required

How many billing periods the discount lasts on a subscription that references it. Null: for as long as the reference stands.

​DiscountAmount[] · required

Fixed and per-unit discounts: one positive amount per currency, sorted by currency. Empty for a percentage discount. A discount is applied only to a document line or document that references its id; creating or assigning it changes no document on its own.

​DiscountAssignment[] · required

Where the discount applies: each assignment names a product, a customer and a window of days, any of them null for "all". A discount with no assignment applies nowhere.

GET/v1/discounts/{discountId}
curl https://api.ledgerbee.com/api/v1/discounts/:discountId \ --header 'x-api-key: <api-key>'
Example Responses
{ "id": "0199b6d2-3c1a-7a40-9f00-1d2e3f4a5b6c", "name": "Black Friday", "type": "percentage", "scope": "line", "percentagePct": "10.0000", "priority": 0, "combinable": true, "active": true, "requiresCode": true, "maxRedemptions": 0, "maxPerCustomer": 0, "durationInPeriods": 0, "amounts": [ { "currency": "DKK", "amount": "50.00" } ], "assignments": [ { "id": "0199b6d2-3c1a-7a40-9f00-1d2e3f4a5b6c", "discountId": "discountId", "productId": "productId", "productGroupId": "productGroupId", "customerId": "customerId", "customerGroupId": "customerGroupId", "startsAt": "2026-11-27", "endsAt": "2026-11-30" } ] }
json
application/json

Delete a discount

DELETE
https://api.ledgerbee.com/api
/v1/discounts/{discountId}
x-api-key (header)
or
OAuth 2.0

Credential: a company's API key or OAuth token.

Deletes a discount with its amounts and assignments. A discount a document or a redemption already records is refused with DISCOUNT_IN_USE; deactivate it with active: false instead.

Required Scope

  • products-write

Delete a discount › path Parameters

discountId
​string · required

Discount ID

Delete a discount › Headers

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

Optional idempotency key for safely retrying mutating requests.

Delete a discount › Responses

Discount deleted

No data returned
DELETE/v1/discounts/{discountId}
curl https://api.ledgerbee.com/api/v1/discounts/:discountId \ --request DELETE \ --header 'x-api-key: <api-key>'
Example Responses
No example specified for this content type

Update a discount

PATCH
https://api.ledgerbee.com/api
/v1/discounts/{discountId}
x-api-key (header)
or
OAuth 2.0

Credential: a company's API key or OAuth token.

Updates a discount. Only the fields provided are changed; maxRedemptions or maxPerCustomer sent as null removes that limit, and any other field sent as null is refused with 400. The type cannot change: a different type is refused with DISCOUNT_TYPE_IMMUTABLE. A per_unit discount cannot move to document scope (DISCOUNT_PER_UNIT_NEEDS_LINE_SCOPE).

The edit is saved and the response's warnings carries DISCOUNT_IN_USE_ON_OPEN_DOCUMENTS when open quotes, order confirmations or invoice drafts reference the discount: total counts them and documents lists the newest 50 of those your key may read (quotes-read, order-confirmations-read, invoices-read). A sent quote or order confirmation keeps its discount figures until it is converted; an invoice draft takes the new value the next time it is saved. warnings is empty when nothing is open.

An edit that changes what the discount takes off or where it applies (percent, scope, active, combinable, requiresCode) gives that warning; a rename or a change to priority or limits gives none.

A subscription freezes a discount's terms for each billing period. An edit that changes what the discount takes off for a subscription that references it (percent, the amount in its currency, scope, combinable) is refused with 409 DISCOUNT_IN_USE_ON_SUBSCRIPTIONS and nothing is saved, unless the request accepts applyToSubscriptions. Then each such subscription takes the new terms from its next billing period, as a new version, and subscriptionChanges lists them with that date. A period already running keeps the old terms. The refusal's details.total counts the subscriptions; details.subscriptions lists them, and subscriptionChanges gives their name and customerName, only to a key with subscriptions-read. Accepting needs subscriptions-write as well: without it, applyToSubscriptions is ignored and the edit is refused.

Required Scope

  • products-write

Update a discount › path Parameters

discountId
​string · required

Discount ID

Update a discount › Headers

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

Optional idempotency key for safely retrying mutating requests.

Update a discount › Request Body

UpdateDiscountRequest
name
​string

Printed as the reason on the e-invoice allowance.

type
​string · enum

Accepted only when it equals the current type. The type cannot change after creation: a different value is refused with DISCOUNT_TYPE_IMMUTABLE.

Enum values:
percentage
fixed
per_unit
scope
​string · enum

line applies to each eligible line on its own. document applies once per document, after every line discount, when the customer matches and at least one line has an eligible product. A per_unit discount with document scope is refused with DISCOUNT_PER_UNIT_NEEDS_LINE_SCOPE.

Enum values:
line
document
percentagePct
​string

Percentage discounts only: above 0 and at most 100, with at most 4 decimals. Outside that range: DISCOUNT_INVALID_PERCENTAGE.

Example: 15
priority
​number

The order the server applies discounts in when it picks them itself.

combinable
​boolean

False: a line may not reference this discount together with another one.

active
​boolean

An inactive discount applies nowhere.

requiresCode
​boolean

True: the discount applies only through one of its codes. A document or an applicability check that names it by its id alone is refused with the reason codeRequired, and GET /v1/discounts/applicable leaves it out.

maxRedemptions
​number | null

Null removes the limit.

maxPerCustomer
​number | null

Null removes the limit.

durationInPeriods
​number | null · min: 1

Null: lasts for as long as a subscription references it.

applyToSubscriptions
​boolean

True accepts moving the subscriptions that reference the discount onto the edited terms: each takes them from its next billing period, as a new version. Omitted or false: an edit that changes what the discount takes off (percent, amount, scope, combinable) while subscriptions reference it is refused with DISCOUNT_IN_USE_ON_SUBSCRIPTIONS and nothing is saved.

Update a discount › Responses

Discount updated

UpdateDiscountResponse
id
​string · required

The discount ID.

Example: 0199b6d2-3c1a-7a40-9f00-1d2e3f4a5b6c
name
​string · required

Printed as the reason on the e-invoice allowance.

Example: Black Friday
type
​string · enum · required

percentage takes a percent off; fixed takes an amount off, per eligible line for a line discount or once per document for a document discount; per_unit takes an amount off each unit on a line and takes line scope only. The type cannot change after the discount is created.

Enum values:
percentage
fixed
per_unit
scope
​string · enum · required

line applies to each eligible line on its own. document applies once per document, after every line discount, when the customer matches and at least one line has an eligible product. A per_unit discount with document scope is refused with DISCOUNT_PER_UNIT_NEEDS_LINE_SCOPE.

Enum values:
line
document
percentagePct
​string | null · required

Percentage discounts only: the percent taken off, above 0 and at most 100. Null for other types.

Example: 10.0000
priority
​number · required

The order the server applies discounts in when it picks them itself; lowest first.

Example: 0
combinable
​boolean · required

False: a line may not reference this discount together with another one.

active
​boolean · required

An inactive discount applies nowhere.

requiresCode
​boolean · required

True: the discount applies only through one of its codes. A document or an applicability check that names it by its id alone is refused with the reason codeRequired, and GET /v1/discounts/applicable leaves it out.

maxRedemptions
​number | null · required

Total uses allowed. Null: no limit.

maxPerCustomer
​number | null · required

Uses allowed per customer. Null: no limit.

durationInPeriods
​number | null · required

How many billing periods the discount lasts on a subscription that references it. Null: for as long as the reference stands.

​DiscountAmount[] · required

Fixed and per-unit discounts: one positive amount per currency, sorted by currency. Empty for a percentage discount. A discount is applied only to a document line or document that references its id; creating or assigning it changes no document on its own.

​DiscountAssignment[] · required

Where the discount applies: each assignment names a product, a customer and a window of days, any of them null for "all". A discount with no assignment applies nowhere.

​DiscountInUseOnOpenDocumentsWarning[] · required

Warnings about the edit, empty when there is nothing to warn about. DISCOUNT_IN_USE_ON_OPEN_DOCUMENTS lists the open quotes (not converted, rejected or expired), order confirmations (not converted) and invoice drafts that reference the discount. The edit is saved either way. A sent quote or order confirmation keeps its discount figures until it is converted; an invoice draft takes the new value the next time it is saved. Given when the edit changed what the discount takes off or where it applies (percent, amounts, scope, active, combinable, requiresCode); a rename or a change to priority or limits gives none.

​DiscountSubscriptionTermsChange[] · required

With applyToSubscriptions: true, the subscriptions whose terms the edit changed: each takes the new terms from its next billing period. Empty otherwise.

PATCH/v1/discounts/{discountId}
curl https://api.ledgerbee.com/api/v1/discounts/:discountId \ --request PATCH \ --header 'Content-Type: application/json' \ --header 'x-api-key: <api-key>' \ --data '{ "name": "string", "type": "percentage", "scope": "line", "percentagePct": "15", "priority": 0, "combinable": true, "active": true, "requiresCode": true, "maxRedemptions": 0, "maxPerCustomer": 0, "durationInPeriods": 1, "applyToSubscriptions": true }'
Example Request Body
{ "name": "string", "type": "percentage", "scope": "line", "percentagePct": "15", "priority": 0, "combinable": true, "active": true, "requiresCode": true, "maxRedemptions": 0, "maxPerCustomer": 0, "durationInPeriods": 1, "applyToSubscriptions": true }
json
application/json
Example Responses
{ "id": "0199b6d2-3c1a-7a40-9f00-1d2e3f4a5b6c", "name": "Black Friday", "type": "percentage", "scope": "line", "percentagePct": "10.0000", "priority": 0, "combinable": true, "active": true, "requiresCode": true, "maxRedemptions": 0, "maxPerCustomer": 0, "durationInPeriods": 0, "amounts": [ { "currency": "DKK", "amount": "50.00" } ], "assignments": [ { "id": "0199b6d2-3c1a-7a40-9f00-1d2e3f4a5b6c", "discountId": "discountId", "productId": "productId", "productGroupId": "productGroupId", "customerId": "customerId", "customerGroupId": "customerGroupId", "startsAt": "2026-11-27", "endsAt": "2026-11-30" } ], "warnings": [ { "code": "DISCOUNT_IN_USE_ON_OPEN_DOCUMENTS", "total": 0, "documents": [ { "id": "id", "kind": "quote", "number": "number", "reference": "reference", "status": "status", "validUntil": "validUntil" } ] } ], "subscriptionChanges": [ { "customerSubscriptionId": "customerSubscriptionId", "chainHeadId": "chainHeadId", "name": "name", "customerName": "customerName", "effectiveDate": "effectiveDate", "outcome": "scheduled", "errorCode": "errorCode" } ] }
json
application/json

Set a discount's amount in one currency

PUT
https://api.ledgerbee.com/api
/v1/discounts/{discountId}/amounts/{currency}
x-api-key (header)
or
OAuth 2.0

Credential: a company's API key or OAuth token.

Sets a fixed or per-unit discount's amount in the path's currency, adding it or replacing the amount already there. The amount is positive and applies to documents in that currency only. Refused on a percentage discount with DISCOUNT_AMOUNT_NOT_ALLOWED.

The edit is saved and the response's warnings carries DISCOUNT_IN_USE_ON_OPEN_DOCUMENTS when open quotes, order confirmations or invoice drafts reference the discount: total counts them and documents lists the newest 50 of those your key may read (quotes-read, order-confirmations-read, invoices-read). A sent quote or order confirmation keeps its discount figures until it is converted; an invoice draft takes the new value the next time it is saved. warnings is empty when nothing is open.

Restating the amount already stored gives no warning.

A subscription freezes a discount's terms for each billing period. An edit that changes what the discount takes off for a subscription that references it (percent, the amount in its currency, scope, combinable) is refused with 409 DISCOUNT_IN_USE_ON_SUBSCRIPTIONS and nothing is saved, unless the request accepts applyToSubscriptions. Then each such subscription takes the new terms from its next billing period, as a new version, and subscriptionChanges lists them with that date. A period already running keeps the old terms. The refusal's details.total counts the subscriptions; details.subscriptions lists them, and subscriptionChanges gives their name and customerName, only to a key with subscriptions-read. Accepting needs subscriptions-write as well: without it, applyToSubscriptions is ignored and the edit is refused.

Required Scope

  • products-write

Set a discount's amount in one currency › path Parameters

discountId
​string · required

Discount ID

currency
​string · required

ISO 4217 alpha-3 currency code

Example: EUR

Set a discount's amount in one currency › Headers

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

Optional idempotency key for safely retrying mutating requests.

Set a discount's amount in one currency › Request Body

SetDiscountAmountRequest
amount
​string · required

The amount in the path's currency. What the discount takes off in this currency, in major units, as a positive decimal string. Each currency carries its own amount: a document in a currency the discount has no amount for is refused, never converted at an exchange rate.

Example: 8.00
applyToSubscriptions
​boolean

True accepts moving the subscriptions that reference the discount onto the edited terms: each takes them from its next billing period, as a new version. Omitted or false: an edit that changes what the discount takes off (percent, amount, scope, combinable) while subscriptions reference it is refused with DISCOUNT_IN_USE_ON_SUBSCRIPTIONS and nothing is saved.

Set a discount's amount in one currency › Responses

The discount with its amounts

UpdateDiscountResponse
id
​string · required

The discount ID.

Example: 0199b6d2-3c1a-7a40-9f00-1d2e3f4a5b6c
name
​string · required

Printed as the reason on the e-invoice allowance.

Example: Black Friday
type
​string · enum · required

percentage takes a percent off; fixed takes an amount off, per eligible line for a line discount or once per document for a document discount; per_unit takes an amount off each unit on a line and takes line scope only. The type cannot change after the discount is created.

Enum values:
percentage
fixed
per_unit
scope
​string · enum · required

line applies to each eligible line on its own. document applies once per document, after every line discount, when the customer matches and at least one line has an eligible product. A per_unit discount with document scope is refused with DISCOUNT_PER_UNIT_NEEDS_LINE_SCOPE.

Enum values:
line
document
percentagePct
​string | null · required

Percentage discounts only: the percent taken off, above 0 and at most 100. Null for other types.

Example: 10.0000
priority
​number · required

The order the server applies discounts in when it picks them itself; lowest first.

Example: 0
combinable
​boolean · required

False: a line may not reference this discount together with another one.

active
​boolean · required

An inactive discount applies nowhere.

requiresCode
​boolean · required

True: the discount applies only through one of its codes. A document or an applicability check that names it by its id alone is refused with the reason codeRequired, and GET /v1/discounts/applicable leaves it out.

maxRedemptions
​number | null · required

Total uses allowed. Null: no limit.

maxPerCustomer
​number | null · required

Uses allowed per customer. Null: no limit.

durationInPeriods
​number | null · required

How many billing periods the discount lasts on a subscription that references it. Null: for as long as the reference stands.

​DiscountAmount[] · required

Fixed and per-unit discounts: one positive amount per currency, sorted by currency. Empty for a percentage discount. A discount is applied only to a document line or document that references its id; creating or assigning it changes no document on its own.

​DiscountAssignment[] · required

Where the discount applies: each assignment names a product, a customer and a window of days, any of them null for "all". A discount with no assignment applies nowhere.

​DiscountInUseOnOpenDocumentsWarning[] · required

Warnings about the edit, empty when there is nothing to warn about. DISCOUNT_IN_USE_ON_OPEN_DOCUMENTS lists the open quotes (not converted, rejected or expired), order confirmations (not converted) and invoice drafts that reference the discount. The edit is saved either way. A sent quote or order confirmation keeps its discount figures until it is converted; an invoice draft takes the new value the next time it is saved. Given when the edit changed what the discount takes off or where it applies (percent, amounts, scope, active, combinable, requiresCode); a rename or a change to priority or limits gives none.

​DiscountSubscriptionTermsChange[] · required

With applyToSubscriptions: true, the subscriptions whose terms the edit changed: each takes the new terms from its next billing period. Empty otherwise.

PUT/v1/discounts/{discountId}/amounts/{currency}
curl https://api.ledgerbee.com/api/v1/discounts/:discountId/amounts/:currency \ --request PUT \ --header 'Content-Type: application/json' \ --header 'x-api-key: <api-key>' \ --data '{ "amount": "8.00", "applyToSubscriptions": true }'
Example Request Body
{ "amount": "8.00", "applyToSubscriptions": true }
json
application/json
Example Responses
{ "id": "0199b6d2-3c1a-7a40-9f00-1d2e3f4a5b6c", "name": "Black Friday", "type": "percentage", "scope": "line", "percentagePct": "10.0000", "priority": 0, "combinable": true, "active": true, "requiresCode": true, "maxRedemptions": 0, "maxPerCustomer": 0, "durationInPeriods": 0, "amounts": [ { "currency": "DKK", "amount": "50.00" } ], "assignments": [ { "id": "0199b6d2-3c1a-7a40-9f00-1d2e3f4a5b6c", "discountId": "discountId", "productId": "productId", "productGroupId": "productGroupId", "customerId": "customerId", "customerGroupId": "customerGroupId", "startsAt": "2026-11-27", "endsAt": "2026-11-30" } ], "warnings": [ { "code": "DISCOUNT_IN_USE_ON_OPEN_DOCUMENTS", "total": 0, "documents": [ { "id": "id", "kind": "quote", "number": "number", "reference": "reference", "status": "status", "validUntil": "validUntil" } ] } ], "subscriptionChanges": [ { "customerSubscriptionId": "customerSubscriptionId", "chainHeadId": "chainHeadId", "name": "name", "customerName": "customerName", "effectiveDate": "effectiveDate", "outcome": "scheduled", "errorCode": "errorCode" } ] }
json
application/json

Remove a discount's amount in one currency

DELETE
https://api.ledgerbee.com/api
/v1/discounts/{discountId}/amounts/{currency}
x-api-key (header)
or
OAuth 2.0

Credential: a company's API key or OAuth token.

Removes the amount in the path's currency. A document in that currency that references the discount is then refused with DISCOUNT_NO_AMOUNT_IN_CURRENCY.

The edit is saved and the response's warnings carries DISCOUNT_IN_USE_ON_OPEN_DOCUMENTS when open quotes, order confirmations or invoice drafts reference the discount: total counts them and documents lists the newest 50 of those your key may read (quotes-read, order-confirmations-read, invoices-read). A sent quote or order confirmation keeps its discount figures until it is converted; an invoice draft takes the new value the next time it is saved. warnings is empty when nothing is open.

A subscription freezes a discount's terms for each billing period. An edit that changes what the discount takes off for a subscription that references it (percent, the amount in its currency, scope, combinable) is refused with 409 DISCOUNT_IN_USE_ON_SUBSCRIPTIONS and nothing is saved, unless the request accepts applyToSubscriptions. Then each such subscription takes the new terms from its next billing period, as a new version, and subscriptionChanges lists them with that date. A period already running keeps the old terms. The refusal's details.total counts the subscriptions; details.subscriptions lists them, and subscriptionChanges gives their name and customerName, only to a key with subscriptions-read. Accepting needs subscriptions-write as well: without it, applyToSubscriptions is ignored and the edit is refused.

Required Scope

  • products-write

Remove a discount's amount in one currency › path Parameters

discountId
​string · required

Discount ID

currency
​string · required

ISO 4217 alpha-3 currency code

Example: EUR

Remove a discount's amount in one currency › query Parameters

applyToSubscriptions
​string · enum

True accepts moving the subscriptions that reference the discount onto the edited terms: each takes them from its next billing period, as a new version. Omitted or false: an edit that changes what the discount takes off (percent, amount, scope, combinable) while subscriptions reference it is refused with DISCOUNT_IN_USE_ON_SUBSCRIPTIONS and nothing is saved.

Enum values:
true
false

Remove a discount's amount in one currency › Headers

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

Optional idempotency key for safely retrying mutating requests.

Remove a discount's amount in one currency › Responses

The discount with its remaining amounts

UpdateDiscountResponse
id
​string · required

The discount ID.

Example: 0199b6d2-3c1a-7a40-9f00-1d2e3f4a5b6c
name
​string · required

Printed as the reason on the e-invoice allowance.

Example: Black Friday
type
​string · enum · required

percentage takes a percent off; fixed takes an amount off, per eligible line for a line discount or once per document for a document discount; per_unit takes an amount off each unit on a line and takes line scope only. The type cannot change after the discount is created.

Enum values:
percentage
fixed
per_unit
scope
​string · enum · required

line applies to each eligible line on its own. document applies once per document, after every line discount, when the customer matches and at least one line has an eligible product. A per_unit discount with document scope is refused with DISCOUNT_PER_UNIT_NEEDS_LINE_SCOPE.

Enum values:
line
document
percentagePct
​string | null · required

Percentage discounts only: the percent taken off, above 0 and at most 100. Null for other types.

Example: 10.0000
priority
​number · required

The order the server applies discounts in when it picks them itself; lowest first.

Example: 0
combinable
​boolean · required

False: a line may not reference this discount together with another one.

active
​boolean · required

An inactive discount applies nowhere.

requiresCode
​boolean · required

True: the discount applies only through one of its codes. A document or an applicability check that names it by its id alone is refused with the reason codeRequired, and GET /v1/discounts/applicable leaves it out.

maxRedemptions
​number | null · required

Total uses allowed. Null: no limit.

maxPerCustomer
​number | null · required

Uses allowed per customer. Null: no limit.

durationInPeriods
​number | null · required

How many billing periods the discount lasts on a subscription that references it. Null: for as long as the reference stands.

​DiscountAmount[] · required

Fixed and per-unit discounts: one positive amount per currency, sorted by currency. Empty for a percentage discount. A discount is applied only to a document line or document that references its id; creating or assigning it changes no document on its own.

​DiscountAssignment[] · required

Where the discount applies: each assignment names a product, a customer and a window of days, any of them null for "all". A discount with no assignment applies nowhere.

​DiscountInUseOnOpenDocumentsWarning[] · required

Warnings about the edit, empty when there is nothing to warn about. DISCOUNT_IN_USE_ON_OPEN_DOCUMENTS lists the open quotes (not converted, rejected or expired), order confirmations (not converted) and invoice drafts that reference the discount. The edit is saved either way. A sent quote or order confirmation keeps its discount figures until it is converted; an invoice draft takes the new value the next time it is saved. Given when the edit changed what the discount takes off or where it applies (percent, amounts, scope, active, combinable, requiresCode); a rename or a change to priority or limits gives none.

​DiscountSubscriptionTermsChange[] · required

With applyToSubscriptions: true, the subscriptions whose terms the edit changed: each takes the new terms from its next billing period. Empty otherwise.

DELETE/v1/discounts/{discountId}/amounts/{currency}
curl https://api.ledgerbee.com/api/v1/discounts/:discountId/amounts/:currency \ --request DELETE \ --header 'x-api-key: <api-key>'
Example Responses
{ "id": "0199b6d2-3c1a-7a40-9f00-1d2e3f4a5b6c", "name": "Black Friday", "type": "percentage", "scope": "line", "percentagePct": "10.0000", "priority": 0, "combinable": true, "active": true, "requiresCode": true, "maxRedemptions": 0, "maxPerCustomer": 0, "durationInPeriods": 0, "amounts": [ { "currency": "DKK", "amount": "50.00" } ], "assignments": [ { "id": "0199b6d2-3c1a-7a40-9f00-1d2e3f4a5b6c", "discountId": "discountId", "productId": "productId", "productGroupId": "productGroupId", "customerId": "customerId", "customerGroupId": "customerGroupId", "startsAt": "2026-11-27", "endsAt": "2026-11-30" } ], "warnings": [ { "code": "DISCOUNT_IN_USE_ON_OPEN_DOCUMENTS", "total": 0, "documents": [ { "id": "id", "kind": "quote", "number": "number", "reference": "reference", "status": "status", "validUntil": "validUntil" } ] } ], "subscriptionChanges": [ { "customerSubscriptionId": "customerSubscriptionId", "chainHeadId": "chainHeadId", "name": "name", "customerName": "customerName", "effectiveDate": "effectiveDate", "outcome": "scheduled", "errorCode": "errorCode" } ] }
json
application/json

Check whether a discount applies to a product for a customer on a day

GET
https://api.ledgerbee.com/api
/v1/discounts/{discountId}/applicability
x-api-key (header)
or
OAuth 2.0

Credential: a company's API key or OAuth token.

Answers whether this discount applies, and when it does not, the first check that failed, in this order: unknown, inactive, codeRequired, notAssigned or notInGroup, outsideWindow, maxRedemptionsReached, maxPerCustomerReached. notInGroup means an assignment would match if the product or the customer were in the group it names. A discount of another company answers unknown.

remaining and remainingForCustomer are the uses left under maxRedemptions and maxPerCustomer, null when the discount has no such limit. Asking holds no use: a booking that would pass a limit is still refused.

Required Scope

  • products-read

Check whether a discount applies to a product for a customer on a day › path Parameters

discountId
​string · required

Discount ID

Check whether a discount applies to a product for a customer on a day › query Parameters

customerId
​string · required

The customer the document is for.

productId
​string · required

The line's product.

asOf
​string · required

The calendar day to judge on (YYYY-MM-DD), normally the document's date. An assignment covers it when startsAt ≤ asOf ≤ endsAt, both ends inclusive.

Example: 2026-11-27

Check whether a discount applies to a product for a customer on a day › Responses

Whether the discount applies

DiscountApplicabilityResponse
applicable
​boolean · required

Whether the discount applies to this customer and product on this day.

reason
​string · enum · required

Null when it applies. Otherwise the first check that failed: unknown (no such discount in your company), inactive, codeRequired (the discount applies only through a code), notAssigned (no assignment names this product and customer, or all), notInGroup (an assignment would match, but the product or the customer is not in the group it targets), outsideWindow (an assignment matches, but not on this day), maxRedemptionsReached (no use left under maxRedemptions), maxPerCustomerReached (no use left for this customer under maxPerCustomer).

Enum values:
unknown
inactive
codeRequired
notAssigned
notInGroup
outsideWindow
maxRedemptionsReached
maxPerCustomerReached
remaining
​number | null · required

Uses left under maxRedemptions, counted from booked invoices whose uses no full credit note has given back. Null when the discount has no total limit, or no such discount exists in your company.

Example: 3
remainingForCustomer
​number | null · required

Uses left for this customer under maxPerCustomer. Null when the discount has no per-customer limit, or no such discount exists in your company.

Example: 1
GET/v1/discounts/{discountId}/applicability
curl 'https://api.ledgerbee.com/api/v1/discounts/:discountId/applicability?customerId=<string>&productId=<string>&asOf=<string>' \ --header 'x-api-key: <api-key>'
Example Responses
{ "applicable": true, "reason": "unknown", "remaining": 3, "remainingForCustomer": 1 }
json
application/json

Assign a discount

POST
https://api.ledgerbee.com/api
/v1/discounts/{discountId}/assignments
x-api-key (header)
or
OAuth 2.0

Credential: a company's API key or OAuth token.

Adds an assignment: the products, the customers and the window of days the discount applies to. The products are one product (productId), every product in a product group (productGroupId), or every product when both are null; the customers are one customer, a customer group or every customer the same way. Setting both fields of a pair is refused with 400 DISCOUNT_ASSIGNMENT_TARGET_CONFLICT. A null startsAt means from any day and a null endsAt never ending. Both dates are inclusive calendar days.

A group is read when a document is checked, so a product or customer moved into the group later is covered from then on. Deleting the group deletes the assignments aimed at it.

A discount can carry several assignments, so one discount can serve several products or customers.

The edit is saved and the response's warnings carries DISCOUNT_IN_USE_ON_OPEN_DOCUMENTS when open quotes, order confirmations or invoice drafts reference the discount: total counts them and documents lists the newest 50 of those your key may read (quotes-read, order-confirmations-read, invoices-read). A sent quote or order confirmation keeps its discount figures until it is converted; an invoice draft takes the new value the next time it is saved. warnings is empty when nothing is open.

Required Scope

  • products-write

Assign a discount › path Parameters

discountId
​string · required

Discount ID

Assign a discount › Headers

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

Optional idempotency key for safely retrying mutating requests.

Assign a discount › Request Body

CreateDiscountAssignmentRequest
productId
​string | null

The product the discount applies to. Null or omitted, with no product group: every product.

productGroupId
​string | null

The product group the discount applies to: every product in it. Set at most one of productId and productGroupId; both is refused with DISCOUNT_ASSIGNMENT_TARGET_CONFLICT.

customerId
​string | null

The customer the discount applies to. Null or omitted, with no customer group: every customer.

customerGroupId
​string | null

The customer group the discount applies to: every customer in it. Set at most one of customerId and customerGroupId; both is refused with DISCOUNT_ASSIGNMENT_TARGET_CONFLICT.

startsAt
​string | null

First calendar day it applies, inclusive (YYYY-MM-DD). Null or omitted: from any day.

Example: 2026-11-27
endsAt
​string | null

Last calendar day it applies, inclusive (YYYY-MM-DD). Null or omitted: it never ends.

Example: 2026-11-30

Assign a discount › Responses

Assignment created

UpdateDiscountAssignmentResponse
id
​string · required

The assignment ID.

Example: 0199b6d2-3c1a-7a40-9f00-1d2e3f4a5b6c
discountId
​string · required

The discount this assignment belongs to.

productId
​string | null · required

The product the discount applies to. Null, with no product group: every product.

productGroupId
​string | null · required

The product group the discount applies to: every product whose group it is, at the time a document is checked. Null: no group target. Never set together with productId.

customerId
​string | null · required

The customer the discount applies to. Null, with no customer group: every customer.

customerGroupId
​string | null · required

The customer group the discount applies to: every customer whose group it is, at the time a document is checked. Null: no group target. Never set together with customerId.

startsAt
​string | null · required

First calendar day the discount applies, inclusive (YYYY-MM-DD). Null: from any day.

Example: 2026-11-27
endsAt
​string | null · required

Last calendar day the discount applies, inclusive (YYYY-MM-DD). Null: it never ends.

Example: 2026-11-30
​DiscountInUseOnOpenDocumentsWarning[] · required

Warnings about the edit, empty when there is nothing to warn about. DISCOUNT_IN_USE_ON_OPEN_DOCUMENTS lists the open quotes (not converted, rejected or expired), order confirmations (not converted) and invoice drafts that reference the discount. The edit is saved either way. A sent quote or order confirmation keeps its discount figures until it is converted; an invoice draft takes the new value the next time it is saved. Given when an assignment is added, or an edit moves its product, product group, customer, customer group or dates.

POST/v1/discounts/{discountId}/assignments
curl https://api.ledgerbee.com/api/v1/discounts/:discountId/assignments \ --request POST \ --header 'Content-Type: application/json' \ --header 'x-api-key: <api-key>' \ --data '{ "productId": "string", "productGroupId": "string", "customerId": "string", "customerGroupId": "string", "startsAt": "2026-11-27", "endsAt": "2026-11-30" }'
Example Request Body
{ "productId": "string", "productGroupId": "string", "customerId": "string", "customerGroupId": "string", "startsAt": "2026-11-27", "endsAt": "2026-11-30" }
json
application/json
Example Responses
{ "id": "0199b6d2-3c1a-7a40-9f00-1d2e3f4a5b6c", "discountId": "discountId", "productId": "productId", "productGroupId": "productGroupId", "customerId": "customerId", "customerGroupId": "customerGroupId", "startsAt": "2026-11-27", "endsAt": "2026-11-30", "warnings": [ { "code": "DISCOUNT_IN_USE_ON_OPEN_DOCUMENTS", "total": 0, "documents": [ { "id": "id", "kind": "quote", "number": "number", "reference": "reference", "status": "status", "validUntil": "validUntil" } ] } ] }
json
application/json

Remove an assignment

DELETE
https://api.ledgerbee.com/api
/v1/discounts/{discountId}/assignments/{assignmentId}
x-api-key (header)
or
OAuth 2.0

Credential: a company's API key or OAuth token.

Removes an assignment. A discount left with no assignment applies nowhere.

The edit is saved and the response's warnings carries DISCOUNT_IN_USE_ON_OPEN_DOCUMENTS when open quotes, order confirmations or invoice drafts reference the discount: total counts them and documents lists the newest 50 of those your key may read (quotes-read, order-confirmations-read, invoices-read). A sent quote or order confirmation keeps its discount figures until it is converted; an invoice draft takes the new value the next time it is saved. warnings is empty when nothing is open.

Removing an assignment gives that warning whenever open documents reference the discount.

Required Scope

  • products-write

Remove an assignment › path Parameters

discountId
​string · required

Discount ID

assignmentId
​string · required

Assignment ID

Remove an assignment › Headers

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

Optional idempotency key for safely retrying mutating requests.

Remove an assignment › Responses

Assignment removed

RemoveDiscountAssignmentResponse
​DiscountInUseOnOpenDocumentsWarning[] · required

Warnings about the edit, empty when there is nothing to warn about. DISCOUNT_IN_USE_ON_OPEN_DOCUMENTS lists the open quotes (not converted, rejected or expired), order confirmations (not converted) and invoice drafts that reference the discount. The edit is saved either way. A sent quote or order confirmation keeps its discount figures until it is converted; an invoice draft takes the new value the next time it is saved. Given whenever open documents reference the discount, since removing an assignment narrows where it applies.

DELETE/v1/discounts/{discountId}/assignments/{assignmentId}
curl https://api.ledgerbee.com/api/v1/discounts/:discountId/assignments/:assignmentId \ --request DELETE \ --header 'x-api-key: <api-key>'
Example Responses
{ "warnings": [ { "code": "DISCOUNT_IN_USE_ON_OPEN_DOCUMENTS", "total": 0, "documents": [ { "id": "id", "kind": "quote", "number": "number", "reference": "reference", "status": "status", "validUntil": "validUntil" } ] } ] }
json
application/json

Update an assignment

PATCH
https://api.ledgerbee.com/api
/v1/discounts/{discountId}/assignments/{assignmentId}
x-api-key (header)
or
OAuth 2.0

Credential: a company's API key or OAuth token.

Changes an assignment. A field left out keeps its value; a field sent as null clears it, widening the assignment to every product, every customer, any start day or no end. To move an assignment from a product to a product group (or a customer to a customer group), send the new field and null for the old one in the same request: a pair holding both is refused with 400 DISCOUNT_ASSIGNMENT_TARGET_CONFLICT.

The edit is saved and the response's warnings carries DISCOUNT_IN_USE_ON_OPEN_DOCUMENTS when open quotes, order confirmations or invoice drafts reference the discount: total counts them and documents lists the newest 50 of those your key may read (quotes-read, order-confirmations-read, invoices-read). A sent quote or order confirmation keeps its discount figures until it is converted; an invoice draft takes the new value the next time it is saved. warnings is empty when nothing is open.

An edit that moves the product, product group, customer, customer group or dates gives that warning; one that restates them gives none.

Required Scope

  • products-write

Update an assignment › path Parameters

discountId
​string · required

Discount ID

assignmentId
​string · required

Assignment ID

Update an assignment › Headers

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

Optional idempotency key for safely retrying mutating requests.

Update an assignment › Request Body

UpdateDiscountAssignmentRequest
productId
​string | null

The product the discount applies to. Null or omitted, with no product group: every product.

productGroupId
​string | null

The product group the discount applies to: every product in it. Set at most one of productId and productGroupId; both is refused with DISCOUNT_ASSIGNMENT_TARGET_CONFLICT.

customerId
​string | null

The customer the discount applies to. Null or omitted, with no customer group: every customer.

customerGroupId
​string | null

The customer group the discount applies to: every customer in it. Set at most one of customerId and customerGroupId; both is refused with DISCOUNT_ASSIGNMENT_TARGET_CONFLICT.

startsAt
​string | null

First calendar day it applies, inclusive (YYYY-MM-DD). Null or omitted: from any day.

Example: 2026-11-27
endsAt
​string | null

Last calendar day it applies, inclusive (YYYY-MM-DD). Null or omitted: it never ends.

Example: 2026-11-30

Update an assignment › Responses

Assignment updated

UpdateDiscountAssignmentResponse
id
​string · required

The assignment ID.

Example: 0199b6d2-3c1a-7a40-9f00-1d2e3f4a5b6c
discountId
​string · required

The discount this assignment belongs to.

productId
​string | null · required

The product the discount applies to. Null, with no product group: every product.

productGroupId
​string | null · required

The product group the discount applies to: every product whose group it is, at the time a document is checked. Null: no group target. Never set together with productId.

customerId
​string | null · required

The customer the discount applies to. Null, with no customer group: every customer.

customerGroupId
​string | null · required

The customer group the discount applies to: every customer whose group it is, at the time a document is checked. Null: no group target. Never set together with customerId.

startsAt
​string | null · required

First calendar day the discount applies, inclusive (YYYY-MM-DD). Null: from any day.

Example: 2026-11-27
endsAt
​string | null · required

Last calendar day the discount applies, inclusive (YYYY-MM-DD). Null: it never ends.

Example: 2026-11-30
​DiscountInUseOnOpenDocumentsWarning[] · required

Warnings about the edit, empty when there is nothing to warn about. DISCOUNT_IN_USE_ON_OPEN_DOCUMENTS lists the open quotes (not converted, rejected or expired), order confirmations (not converted) and invoice drafts that reference the discount. The edit is saved either way. A sent quote or order confirmation keeps its discount figures until it is converted; an invoice draft takes the new value the next time it is saved. Given when an assignment is added, or an edit moves its product, product group, customer, customer group or dates.

PATCH/v1/discounts/{discountId}/assignments/{assignmentId}
curl https://api.ledgerbee.com/api/v1/discounts/:discountId/assignments/:assignmentId \ --request PATCH \ --header 'Content-Type: application/json' \ --header 'x-api-key: <api-key>' \ --data '{ "productId": "string", "productGroupId": "string", "customerId": "string", "customerGroupId": "string", "startsAt": "2026-11-27", "endsAt": "2026-11-30" }'
Example Request Body
{ "productId": "string", "productGroupId": "string", "customerId": "string", "customerGroupId": "string", "startsAt": "2026-11-27", "endsAt": "2026-11-30" }
json
application/json
Example Responses
{ "id": "0199b6d2-3c1a-7a40-9f00-1d2e3f4a5b6c", "discountId": "discountId", "productId": "productId", "productGroupId": "productGroupId", "customerId": "customerId", "customerGroupId": "customerGroupId", "startsAt": "2026-11-27", "endsAt": "2026-11-30", "warnings": [ { "code": "DISCOUNT_IN_USE_ON_OPEN_DOCUMENTS", "total": 0, "documents": [ { "id": "id", "kind": "quote", "number": "number", "reference": "reference", "status": "status", "validUntil": "validUntil" } ] } ] }
json
application/json

List a discount's codes

GET
https://api.ledgerbee.com/api
/v1/discounts/{discountId}/codes
x-api-key (header)
or
OAuth 2.0

Credential: a company's API key or OAuth token.

Retrieves a paginated list of the discount's codes, active and switched off, oldest first, each with the uses counted through it. total counts every code of the discount.

Required Scope

  • products-read

List a discount's codes › path Parameters

discountId
​string · required

Discount ID

List a discount's codes › query Parameters

page
​number · min: 1 · max: 100000

Page number (1-indexed)

Default: 1
limit
​number · min: 1 · max: 100

Maximum number of items per page

Default: 25

List a discount's codes › Responses

Paginated list of the discount's codes

ListDiscountCodesResponse
​DiscountCode[] · required

Page of the discount's codes, active and switched off, oldest first.

total
​number · required

Total number of codes the discount has

Example: 3
page
​number · required

Current page number

Example: 1
limit
​number · required

Items per page

Example: 25
totalPages
​number · required

Total number of pages

Example: 1
GET/v1/discounts/{discountId}/codes
curl https://api.ledgerbee.com/api/v1/discounts/:discountId/codes \ --header 'x-api-key: <api-key>'
Example Responses
{ "data": [ { "id": "id", "discountId": "discountId", "code": "Summer25", "normalizedCode": "SUMMER25", "customerId": "customerId", "maxRedemptions": 0, "expiresAt": "2026-12-31", "active": true, "uses": 0, "createdAt": "createdAt" } ], "total": 3, "page": 1, "limit": 25, "totalPages": 1 }
json
application/json

Add a code to a discount

POST
https://api.ledgerbee.com/api
/v1/discounts/{discountId}/codes
x-api-key (header)
or
OAuth 2.0

Credential: a company's API key or OAuth token.

Adds a code a customer can type to claim the discount. A discount can carry many codes. A code narrows the discount and never widens it: the discount's assignments, window and limits still apply, and the code may add the one customer it is for, its own limit on uses and a last day.

Refused with 409 DISCOUNT_CODE_TAKEN while another active code of your company holds the same text, compared without case; a switched-off code frees its text. Refused with DISCOUNT_CODE_INVALID for an empty code, one over 64 characters or one with a space inside, and with DISCOUNT_CODE_CUSTOMER_NOT_ASSIGNED for a customer the discount's assignments do not cover.

Required Scope

  • products-write

Add a code to a discount › path Parameters

discountId
​string · required

Discount ID

Add a code to a discount › Headers

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

Optional idempotency key for safely retrying mutating requests.

Add a code to a discount › Request Body

CreateDiscountCodeRequest
code
​string · required

The code a customer types: 1 to 64 characters with no space inside, matched without regard to case or surrounding spaces. Otherwise DISCOUNT_CODE_INVALID; an active code of your company with the same text: DISCOUNT_CODE_TAKEN.

Example: SUMMER25
customerId
​string | null

The one customer who may use the code. It must be a customer the discount's assignments cover, or DISCOUNT_CODE_CUSTOMER_NOT_ASSIGNED. Null or omitted: any customer.

maxRedemptions
​number | null

Uses allowed through this code. Null or omitted: no limit.

expiresAt
​string | null

Last calendar day the code may be used, inclusive (YYYY-MM-DD). Null or omitted: never expires.

Example: 2026-12-31
active
​boolean

Defaults to true.

Add a code to a discount › Responses

Code created

DiscountCode
id
​string · required

The code ID.

discountId
​string · required

The discount the code claims.

code
​string · required

The code as it was entered, without surrounding spaces.

Example: Summer25
normalizedCode
​string · required

The code trimmed and upper-cased: the text a lookup matches on.

Example: SUMMER25
customerId
​string | null · required

The one customer who may use the code. Null: any customer the discount applies to.

maxRedemptions
​number | null · required

Uses allowed through this code. Null: no limit of its own.

expiresAt
​string | null · required

Last calendar day the code may be used, inclusive (YYYY-MM-DD). Null: it never expires.

Example: 2026-12-31
active
​boolean · required

False: the code is switched off and its text may be reused by a new code.

uses
​number · required

Uses counted through this code: booked invoices whose use no full credit note has given back.

Example: 0
createdAt
​string · required

When the code was created (ISO 8601).

POST/v1/discounts/{discountId}/codes
curl https://api.ledgerbee.com/api/v1/discounts/:discountId/codes \ --request POST \ --header 'Content-Type: application/json' \ --header 'x-api-key: <api-key>' \ --data '{ "code": "SUMMER25", "customerId": "string", "maxRedemptions": 0, "expiresAt": "2026-12-31", "active": true }'
Example Request Body
{ "code": "SUMMER25", "customerId": "string", "maxRedemptions": 0, "expiresAt": "2026-12-31", "active": true }
json
application/json
Example Responses
{ "id": "id", "discountId": "discountId", "code": "Summer25", "normalizedCode": "SUMMER25", "customerId": "customerId", "maxRedemptions": 0, "expiresAt": "2026-12-31", "active": true, "uses": 0, "createdAt": "createdAt" }
json
application/json

Delete a code

DELETE
https://api.ledgerbee.com/api
/v1/discounts/{discountId}/codes/{codeId}
x-api-key (header)
or
OAuth 2.0

Credential: a company's API key or OAuth token.

Deletes a code no use records. A code that has been used is refused with 409 DISCOUNT_CODE_IN_USE; switch it off with active: false instead.

Required Scope

  • products-write

Delete a code › path Parameters

discountId
​string · required

Discount ID

codeId
​string · required

Code ID

Delete a code › Headers

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

Optional idempotency key for safely retrying mutating requests.

Delete a code › Responses

Code deleted

No data returned
DELETE/v1/discounts/{discountId}/codes/{codeId}
curl https://api.ledgerbee.com/api/v1/discounts/:discountId/codes/:codeId \ --request DELETE \ --header 'x-api-key: <api-key>'
Example Responses
No example specified for this content type

Update a code

PATCH
https://api.ledgerbee.com/api
/v1/discounts/{discountId}/codes/{codeId}
x-api-key (header)
or
OAuth 2.0

Credential: a company's API key or OAuth token.

Changes whether the code is active, the customer it is for, its limit and its last day. A field left out keeps its value; a nullable field sent as null clears it. The code's text cannot change: switch it off and add a new one.

Required Scope

  • products-write

Update a code › path Parameters

discountId
​string · required

Discount ID

codeId
​string · required

Code ID

Update a code › Headers

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

Optional idempotency key for safely retrying mutating requests.

Update a code › Request Body

UpdateDiscountCodeRequest
active
​boolean

False switches the code off. True switches it back on, refused with DISCOUNT_CODE_TAKEN if another active code now holds its text.

customerId
​string | null

Null: any customer the discount applies to.

maxRedemptions
​number | null

Null removes the limit.

expiresAt
​string | null

Null: never expires.

Example: 2026-12-31

Update a code › Responses

Code updated

DiscountCode
id
​string · required

The code ID.

discountId
​string · required

The discount the code claims.

code
​string · required

The code as it was entered, without surrounding spaces.

Example: Summer25
normalizedCode
​string · required

The code trimmed and upper-cased: the text a lookup matches on.

Example: SUMMER25
customerId
​string | null · required

The one customer who may use the code. Null: any customer the discount applies to.

maxRedemptions
​number | null · required

Uses allowed through this code. Null: no limit of its own.

expiresAt
​string | null · required

Last calendar day the code may be used, inclusive (YYYY-MM-DD). Null: it never expires.

Example: 2026-12-31
active
​boolean · required

False: the code is switched off and its text may be reused by a new code.

uses
​number · required

Uses counted through this code: booked invoices whose use no full credit note has given back.

Example: 0
createdAt
​string · required

When the code was created (ISO 8601).

PATCH/v1/discounts/{discountId}/codes/{codeId}
curl https://api.ledgerbee.com/api/v1/discounts/:discountId/codes/:codeId \ --request PATCH \ --header 'Content-Type: application/json' \ --header 'x-api-key: <api-key>' \ --data '{ "active": true, "customerId": "string", "maxRedemptions": 0, "expiresAt": "2026-12-31" }'
Example Request Body
{ "active": true, "customerId": "string", "maxRedemptions": 0, "expiresAt": "2026-12-31" }
json
application/json
Example Responses
{ "id": "id", "discountId": "discountId", "code": "Summer25", "normalizedCode": "SUMMER25", "customerId": "customerId", "maxRedemptions": 0, "expiresAt": "2026-12-31", "active": true, "uses": 0, "createdAt": "createdAt" }
json
application/json

List the discounts that apply to a product for a customer on a day

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

Credential: a company's API key or OAuth token.

Returns every active discount with an assignment that covers the product, the customer and the day, ordered by priority (lowest first). An assignment with no product and no product group covers every product; one with no customer and no customer group covers every customer; one with a group covers the products or customers in that group when the request is made. Its startsAt and endsAt are inclusive calendar days.

A discount whose redemption limit has no use left, in total or for this customer, is left out. A use is counted when an invoice that references the discount is booked, and given back when a credit note leaves nothing creditable on that invoice.

The answer does not look at currency: a fixed or per-unit discount without an amount in the document's currency is still listed, and a document that references it in that currency is refused with DISCOUNT_NO_AMOUNT_IN_CURRENCY.

Required Scope

  • products-read

List the discounts that apply to a product for a customer on a day › query Parameters

customerId
​string · required

The customer the document is for.

productId
​string · required

The line's product.

asOf
​string · required

The calendar day to judge on (YYYY-MM-DD), normally the document's date. An assignment covers it when startsAt ≤ asOf ≤ endsAt, both ends inclusive.

Example: 2026-11-27

List the discounts that apply to a product for a customer on a day › Responses

The discounts that apply

​DiscountResponse[]
DiscountResponse
id
​string · required

The discount ID.

Example: 0199b6d2-3c1a-7a40-9f00-1d2e3f4a5b6c
name
​string · required

Printed as the reason on the e-invoice allowance.

Example: Black Friday
type
​string · enum · required

percentage takes a percent off; fixed takes an amount off, per eligible line for a line discount or once per document for a document discount; per_unit takes an amount off each unit on a line and takes line scope only. The type cannot change after the discount is created.

Enum values:
percentage
fixed
per_unit
scope
​string · enum · required

line applies to each eligible line on its own. document applies once per document, after every line discount, when the customer matches and at least one line has an eligible product. A per_unit discount with document scope is refused with DISCOUNT_PER_UNIT_NEEDS_LINE_SCOPE.

Enum values:
line
document
percentagePct
​string | null · required

Percentage discounts only: the percent taken off, above 0 and at most 100. Null for other types.

Example: 10.0000
priority
​number · required

The order the server applies discounts in when it picks them itself; lowest first.

Example: 0
combinable
​boolean · required

False: a line may not reference this discount together with another one.

active
​boolean · required

An inactive discount applies nowhere.

requiresCode
​boolean · required

True: the discount applies only through one of its codes. A document or an applicability check that names it by its id alone is refused with the reason codeRequired, and GET /v1/discounts/applicable leaves it out.

maxRedemptions
​number | null · required

Total uses allowed. Null: no limit.

maxPerCustomer
​number | null · required

Uses allowed per customer. Null: no limit.

durationInPeriods
​number | null · required

How many billing periods the discount lasts on a subscription that references it. Null: for as long as the reference stands.

​DiscountAmount[] · required

Fixed and per-unit discounts: one positive amount per currency, sorted by currency. Empty for a percentage discount. A discount is applied only to a document line or document that references its id; creating or assigning it changes no document on its own.

​DiscountAssignment[] · required

Where the discount applies: each assignment names a product, a customer and a window of days, any of them null for "all". A discount with no assignment applies nowhere.

GET/v1/discounts/applicable
curl 'https://api.ledgerbee.com/api/v1/discounts/applicable?customerId=<string>&productId=<string>&asOf=<string>' \ --header 'x-api-key: <api-key>'
Example Responses
[ { "id": "0199b6d2-3c1a-7a40-9f00-1d2e3f4a5b6c", "name": "Black Friday", "type": "percentage", "scope": "line", "percentagePct": "10.0000", "priority": 0, "combinable": true, "active": true, "requiresCode": true, "maxRedemptions": 0, "maxPerCustomer": 0, "durationInPeriods": 0, "amounts": [ { "currency": "DKK", "amount": "50.00" } ], "assignments": [ { "id": "0199b6d2-3c1a-7a40-9f00-1d2e3f4a5b6c", "discountId": "discountId", "productId": "productId", "productGroupId": "productGroupId", "customerId": "customerId", "customerGroupId": "customerGroupId", "startsAt": "2026-11-27", "endsAt": "2026-11-30" } ] } ]
json
application/json

Check a cart

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

Credential: a company's API key or OAuth token.

Prices a webshop cart before any order exists: what each discount and code takes off these lines, the ones that do not apply and why, and the uses left. It creates no document and holds no use; booking the invoice counts the use and checks every limit again.

The discounts in discountIds apply first, then the codes, each in the order sent; a discount named twice applies once. A line discount, named once for the cart, lands on every line whose product it covers. A document discount is taken from the net of the lines it covers, a returned (negative) line included, and is split by VAT rate only when every line it falls on carries vatRatePct.

Without customerId the shopper is a guest: only assignments for every customer apply, a code made for one customer does not, and remainingForCustomer is null.

A code your company does not have, or a discount that does not apply, comes back in refusals with its reason while the rest of the cart is still priced.

Limited to 600 uses a minute per API key (or OAuth grant, else OAuth client), shared with the code lookup. A check uses one per code it names, and one when it names none; a lookup uses one. A check that needs more than is left is refused whole and tries none of its codes: the answer is 429 DISCOUNT_CHECK_RATE_LIMITED with a Retry-After header.

Required Scope

  • discounts-check or products-read

Check a cart › Headers

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

Optional idempotency key for safely retrying mutating requests.

Check a cart › Request Body

DiscountCheckRequest
currency
​string · pattern: ^[A-Za-z]{3}$ · required

The cart's currency, ISO 4217 alpha-3. A fixed or per-unit discount needs an amount in it.

Example: DKK
date
​string · required

The calendar day the cart is priced on (YYYY-MM-DD).

Example: 2026-11-27
​DiscountCheckLineRequest[] · required

1 to 200 lines.

customerId
​string

The customer buying. Omitted: a guest, to whom only assignments for every customer apply, a code made for one customer does not apply, and no per-customer use is counted.

codes
​string[]

Codes the shopper typed, at most 20, matched without regard to case or surrounding spaces. They apply after discountIds, in the order sent.

Example: ["SUMMER25"]
discountIds
​string[]

Discounts applied by id, at most 50, in the order sent and before the codes.

Check a cart › Responses

What the cart takes off, and what does not apply

DiscountCheckResponse
​DiscountCheckLine[] · required

Every line of the request, in order.

​DiscountCheckDocumentDiscount[] · required
​DiscountCheckRefusal[] · required
​DiscountCheckLimit[] · required

One row per discount the cart named.

POST/v1/discounts/check
curl https://api.ledgerbee.com/api/v1/discounts/check \ --request POST \ --header 'Content-Type: application/json' \ --header 'x-api-key: <api-key>' \ --data '{ "customerId": "string", "currency": "DKK", "date": "2026-11-27", "lines": [ { "productId": "string", "quantity": 1, "unitPrice": "1000.00", "vatRatePct": 25 } ], "codes": [ "SUMMER25" ], "discountIds": [ "string" ] }'
Example Request Body
{ "customerId": "string", "currency": "DKK", "date": "2026-11-27", "lines": [ { "productId": "string", "quantity": 1, "unitPrice": "1000.00", "vatRatePct": 25 } ], "codes": [ "SUMMER25" ], "discountIds": [ "string" ] }
json
application/json
Example Responses
{ "lines": [ { "lineIndex": 0, "discounts": [ { "discountId": "discountId", "code": "code", "originalReductionAmount": "100.00" } ], "originalNet": "900.00" } ], "documentDiscounts": [ { "discountId": "discountId", "code": "code", "originalReductionAmount": "130.00", "vatSplitAvailable": true, "vatSplit": [ { "vatRatePct": "25", "taxCategory": "S", "originalReductionAmount": "originalReductionAmount", "originalVatReductionAmount": "originalVatReductionAmount" } ] } ], "refusals": [ { "code": "code", "discountId": "discountId", "reason": "codeUnknown", "lineIndex": 0 } ], "limits": [ { "discountId": "discountId", "code": "code", "remaining": 0, "remainingForCustomer": 0, "remainingForCode": 0 } ] }
json
application/json

Look up a discount code

GET
https://api.ledgerbee.com/api
/v1/discounts/codes/{code}
x-api-key (header)
or
OAuth 2.0

Credential: a company's API key or OAuth token.

Answers the code a customer typed, the discount it claims, and whether it applies. The code is matched without regard to case or surrounding spaces, so summer25 finds SUMMER25. Built for a webshop's "apply code" field: it answers one code and lists nothing.

Pass customerId for a known customer; without it the shopper is a guest, to whom only assignments for every customer apply and a code made for one customer does not. Pass productId to judge the discount for one product, and asOf for a day other than today.

A code your company does not have answers 200 with reason: codeUnknown, code: null and discount: null; another company's code answers the same. The reasons are checked in this order: codeUnknown, inactive, notAssigned or notInGroup, outsideWindow, maxRedemptionsReached, maxPerCustomerReached, codeInactive, codeExpired, codeCustomerMismatch, codeMaxRedemptionsReached.

Asking holds no use: a booking that would pass a limit is still refused.

Required Scope

  • discounts-check or products-read

Look up a discount code › path Parameters

code
​string · required

The code as the customer typed it

Example: SUMMER25

Look up a discount code › query Parameters

customerId
​string

The customer who would use the code. Omitted: a guest, to whom only assignments for every customer apply.

productId
​string

A product to judge the discount's assignments for. Omitted: any product.

asOf
​string

The calendar day to judge on (YYYY-MM-DD), normally the order date. Omitted: today.

Example: 2026-11-27

Look up a discount code › Responses

The code and whether it applies

DiscountCodeLookupResponse
code
​object | null · required

Null when your company has no such code.

discount
​object | null · required

The discount the code claims. Null when your company has no such code.

applicable
​boolean · required

Whether the code applies for this customer, product and day.

reason
​string · enum · required

Null when it applies. Otherwise the first check that failed: codeUnknown (no such code in your company), then the discount's own inactive, notAssigned, notInGroup (an assignment would match, but the product or the customer is not in the group it targets), outsideWindow, maxRedemptionsReached, maxPerCustomerReached, then the code's codeInactive, codeExpired (past its last day), codeCustomerMismatch (the code is for another customer, or for a customer and none was given) and codeMaxRedemptionsReached.

Enum values:
unknown
inactive
codeRequired
notAssigned
notInGroup
outsideWindow
maxRedemptionsReached
maxPerCustomerReached
remaining
​number | null · required

Uses left under the discount's maxRedemptions. Null: no total limit.

remainingForCustomer
​number | null · required

Uses left for this customer under the discount's maxPerCustomer. Null: no such limit, or no customer given.

remainingForCode
​number | null · required

Uses left under the code's own maxRedemptions. Null: no limit of its own.

GET/v1/discounts/codes/{code}
curl https://api.ledgerbee.com/api/v1/discounts/codes/:code \ --header 'x-api-key: <api-key>'
Example Responses
{ "code": { "id": "id", "discountId": "discountId", "code": "Summer25", "normalizedCode": "SUMMER25", "maxRedemptions": 0, "expiresAt": "2026-12-31", "active": true, "uses": 0, "createdAt": "createdAt" }, "discount": { "id": "id", "name": "Summer sale", "type": "percentage", "scope": "line", "percentagePct": "percentagePct", "combinable": true, "amounts": [ { "currency": "DKK", "amount": "50.00" } ] }, "applicable": true, "reason": "unknown", "remaining": 0, "remainingForCustomer": 0, "remainingForCode": 0 }
json
application/json

DimensionsDocument Templates