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

Journal Entries

Download schema

Journal entry creation endpoints


List journal entries

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

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

Retrieves a paginated list of journal entries with optional filtering by date, account, customer, external system id, and search text.

Required Scope

  • journal-entries-read

List journal entries › query Parameters

cursor
​string

Opaque cursor from the previous response's nextCursor. Returns the rows after it, in the same order. Send the same filters and sort as the request that produced it, and do not send page. The preferred way to page through a list.

page
​number · min: 1 · deprecated

Deprecated: page with cursor instead. Page number (1-indexed). From 2026-12-31, a page past the first of a list with more than 10,000 matching rows is refused.

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

Maximum number of items per page

Default: 25
fromDate
​string

Only include entries with a posting date on or after this date (ISO 8601). Filters je.date (bogføringsdato).

Example: 2026-01-01
toDate
​string

Only include entries with a posting date on or before this date (ISO 8601). Filters je.date (bogføringsdato).

Example: 2026-01-31
documentDateFrom
​string

Only include entries with a document date on or after this date (ISO 8601). Filters je.documentDate.

Example: 2026-01-01
documentDateTo
​string

Only include entries with a document date on or before this date (ISO 8601). Filters je.documentDate.

Example: 2026-01-31
accountId
​string · uuid

Filter by account ID

customerId
​string · uuid

Filter by customer ID

supplierId
​string · uuid

Filter by supplier ID

vendorId
​string · uuid · deprecated

Deprecated — use supplierId. Legacy alias for the supplier filter.

journalType
​string · enum

Filter by journal type

Enum values:
JOURNAL_ENTRY
SUPPLIER_INVOICE
SUPPLIER_PAYMENT
CUSTOMER_INVOICE
CUSTOMER_PAYMENT
CUSTOMER_REMINDER
CURRENCY_REVALUATION
VAT_SETTLEMENT
journalCategoryId
​string · uuid

Only include entries in this journal category

status
​string · enum

Filter by entry status. Omit to get every status — an entry becomes PAID or PARTIALLY_PAID as it is settled, so filtering to POSTED returns only entries nothing has been paid against.

Enum values:
POSTED
PAID
PARTIALLY_PAID
excludeReversed
​boolean

When true, leave out every entry reversed in LedgerBee together with its reversal. A reversed entry and its reversal cancel each other out, and both keep their status, so the status filter cannot do this. An entry cancelled by a reversal imported from e-conomic is not linked to it, so both stay in the list.

Default: false
externalSystemId
​string · maxLength: 255

Exact-match filter on your own system's id (set via PATCH /journal-entries/:id or carried on the entry). Not unique — several entries may share one id, so expect zero or more results.

Example: erp-7f3a2c91
minAmount
​number

Only include entries with an amount greater than or equal to this value (inclusive).

Example: 100
maxAmount
​number

Only include entries with an amount less than or equal to this value (inclusive).

Example: 10000
search
​string

Free-text search in description and reference fields

sortBy
​string · enum

Sort field. amount is not supported and is refused. documentDate cannot be combined with cursor, since entries without a document date have no place in its order.

Enum values:
date
documentDate
amount
createdAt
Example: date
Default: date
sortOrder
​string · enum

Sort direction

Enum values:
ASC
DESC
Example: DESC
Default: DESC

List journal entries › Responses

Journal entries retrieved successfully

ListJournalEntriesResponse
​JournalEntryResponse[] · required

List of journal entries

total
​number · required

Total number of matching entries

Example: 150
limit
​number · required

Number of items per page

Example: 25
nextCursor
​string | null · required

Cursor for the next page; pass it as cursor. null on the last page, and on every page of a sort that cannot page by cursor — hasMore then says whether another page follows by page number.

Example: eyJ2IjoxLCJmIjoiOWMxZjQyYWIzMTA4ZDc2ZSIsImsiOlsiMjAyNi0wMS0yMCJdfQ
hasMore
​boolean · required

Whether more rows follow this page.

Example: true
page
​number · deprecated

Deprecated: page with nextCursor instead. Current page number.

Example: 1
totalPages
​number · deprecated

Deprecated: page with nextCursor instead. Total number of pages.

Example: 6
GET/v1/journal-entries
curl https://api.ledgerbee.com/api/v1/journal-entries \ --header 'x-api-key: <api-key>'
Example Responses
{ "data": [ { "id": "550e8400-e29b-41d4-a716-446655440000", "entryNumber": "JE-00001", "date": "2026-01-15", "documentDate": "2026-01-15", "dueDate": "2026-02-14", "amount": 1000, "currency": "DKK", "originalAmount": 200, "originalCurrency": "EUR", "originalCurrencyToBaseCurrencyExchangeRate": 7.45, "originalCurrencyToBaseCurrencyExchangeRateDate": "2026-01-15", "exchangeRate": 7.45, "exchangeRateDate": "2026-01-15", "description": "Office supplies purchase", "reference": "REF-2026-001", "externalSystemId": "erp-7f3a2c91", "journalType": "JOURNAL_ENTRY", "journalCategoryId": "550e8400-e29b-41d4-a716-446655440004", "type": "debit", "status": "POSTED", "reversedByEntryId": null, "reversalOfEntryId": null, "accountId": "550e8400-e29b-41d4-a716-446655440000", "contraAccountId": "550e8400-e29b-41d4-a716-446655440001", "lines": [ { "accountId": "550e8400-e29b-41d4-a716-446655440000", "type": "debit", "accountAmount": 500, "accountCurrency": "DKK", "functionalAmount": 500, "originalAmount": 200, "isVatLine": false, "vatSourceLineIndex": 0, "vatCodeId": "550e8400-e29b-41d4-a716-446655440000", "description": "Consulting hours — March", "tagIds": [ "string" ] } ], "customerId": "550e8400-e29b-41d4-a716-446655440002", "supplierId": "550e8400-e29b-41d4-a716-446655440003", "vendorId": "550e8400-e29b-41d4-a716-446655440003", "vatCodeId": "550e8400-e29b-41d4-a716-446655440000", "tagIds": [ "string" ], "documentRefs": [ "string" ], "createdAt": "2026-01-15T10:30:00.000Z", "warnings": [ { "code": "JOURNAL_ENTRY_YEAR_END_ACCOUNT_POSTED", "details": { "accountId": "550e8400-e29b-41d4-a716-446655440000" } } ] } ], "total": 150, "page": 1, "limit": 25, "totalPages": 6, "nextCursor": "eyJ2IjoxLCJmIjoiOWMxZjQyYWIzMTA4ZDc2ZSIsImsiOlsiMjAyNi0wMS0yMCJdfQ", "hasMore": true }
json
application/json

Get a journal entry

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

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

Retrieves a journal entry by its ID.

Required Scope

  • journal-entries-read

Get a journal entry › path Parameters

id
​string · required

Journal entry ID (UUID)

Example: 550e8400-e29b-41d4-a716-446655440000

Get a journal entry › Responses

Journal entry retrieved successfully

JournalEntryResponse
id
​string · required

Unique identifier of the created journal entry

Example: 550e8400-e29b-41d4-a716-446655440000
entryNumber
​string · required

Entry number assigned to the journal entry

Example: JE-00001
date
​string · required

Date of the journal entry

Example: 2026-01-15
amount
​number · required

Amount 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.

Example: 1000
currency
​string · required

Currency amount is denominated in — the operating currency of that first line's account.

Example: DKK
journalType
​string · required

Journal type

Example: JOURNAL_ENTRY
journalCategoryId
​string | null · uuid · required

ID of the journal category the entry is in. A draft booked with a category keeps it. List the categories with GET /v1/journal-categories. Null when the entry has no category.

Example: 550e8400-e29b-41d4-a716-446655440004
type
​string · required

Transaction type

Example: debit
status
​string · required

Status of the journal entry

Example: POSTED
reversedByEntryId
​string | null · uuid · required

The id of the entry that reverses this one, or null when no reversal made in LedgerBee points at it. A reversed entry keeps its status, so this field is what says it no longer counts: it and its reversal cancel each other out. A reversal imported from e-conomic cancels its entry through opposite amounts and is not linked, so the entry it cancels reads null here.

Example: null
reversalOfEntryId
​string | null · uuid · required

On a reversal, the id of the entry it reverses; null on every other entry. The entry named here names this one in its reversedByEntryId.

Example: null
accountId
​string · required

One 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.

Example: 550e8400-e29b-41d4-a716-446655440000
createdAt
​string · required

Timestamp when the entry was created

Example: 2026-01-15T10:30:00.000Z
documentDate
​string | null

Document date (date on the invoice/voucher). Null when the entry was booked without one; its VAT period then follows date.

Example: 2026-01-15
dueDate
​string | null

Due date of the customer or supplier invoice this entry books (YYYY-MM-DD). Null on every other entry type, on a credit note booked without one, and on an invoice posted through this API without a reference (no invoice is registered for it).

Example: 2026-02-14
originalAmount
​number | null

What 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.

Example: 200
originalCurrency
​string | null

The currency the entry was posted in: what originalAmount is denominated in, and what originalCurrencyToBaseCurrencyExchangeRate 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.

Example: EUR
originalCurrencyToBaseCurrencyExchangeRate
​number | null

Rate 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 * originalCurrencyToBaseCurrencyExchangeRate 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.

Example: 7.45
originalCurrencyToBaseCurrencyExchangeRateDate
​string | null

Date the originalCurrencyToBaseCurrencyExchangeRate was captured for. Set on every posted entry, including one that stored no rate; an entry posted in your company base currency carries its own date.

Example: 2026-01-15
description
​string

Description of the journal entry

Example: Office supplies purchase
reference
​string

Reference number

Example: REF-2026-001
externalSystemId
​string

Your own system's id for this entry, when set. Not unique — several entries may share one id.

Example: erp-7f3a2c91
contraAccountId
​string

The 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.

Example: 550e8400-e29b-41d4-a716-446655440001
​JournalEntryLine[]

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.

customerId
​string

Customer ID if applicable

Example: 550e8400-e29b-41d4-a716-446655440002
supplierId
​string

Supplier ID if applicable

Example: 550e8400-e29b-41d4-a716-446655440003
vatCodeId
​string

VAT/Tax code on the line accountId names, if it has one. Lines can carry different codes — read lines[].vatCodeId for the per-line codes.

Example: 550e8400-e29b-41d4-a716-446655440000
tagIds
​string[]

Tag IDs attached to the entry as a whole. Per-line dimensions are on lines[].tagIds.

documentRefs
​string[]

Document IDs attached to the entry

​JournalEntryWarningDto[]

Notes on the posted entry, as codes. Present only when there is one. JOURNAL_ENTRY_YEAR_END_ACCOUNT_POSTED: the entry has a line on the company year-end account and every other line is on a balance-sheet account; details.accountId names the account. An entry with a line there and an income or expense line is refused with 400 JOURNAL_ENTRY_YEAR_END_ACCOUNT_RESULT_LINE.

exchangeRate
​number | null · deprecated

Deprecated — use originalCurrencyToBaseCurrencyExchangeRate, which carries the same value.

Example: 7.45
exchangeRateDate
​string | null · deprecated

Deprecated — use originalCurrencyToBaseCurrencyExchangeRateDate, which carries the same value.

Example: 2026-01-15
vendorId
​string · deprecated

Deprecated — use supplierId. Legacy alias, emitted with the same value.

Example: 550e8400-e29b-41d4-a716-446655440003
GET/v1/journal-entries/{id}
curl https://api.ledgerbee.com/api/v1/journal-entries/:id \ --header 'x-api-key: <api-key>'
Example Responses
{ "id": "550e8400-e29b-41d4-a716-446655440000", "entryNumber": "JE-00001", "date": "2026-01-15", "documentDate": "2026-01-15", "dueDate": "2026-02-14", "amount": 1000, "currency": "DKK", "originalAmount": 200, "originalCurrency": "EUR", "originalCurrencyToBaseCurrencyExchangeRate": 7.45, "originalCurrencyToBaseCurrencyExchangeRateDate": "2026-01-15", "exchangeRate": 7.45, "exchangeRateDate": "2026-01-15", "description": "Office supplies purchase", "reference": "REF-2026-001", "externalSystemId": "erp-7f3a2c91", "journalType": "JOURNAL_ENTRY", "journalCategoryId": "550e8400-e29b-41d4-a716-446655440004", "type": "debit", "status": "POSTED", "reversedByEntryId": null, "reversalOfEntryId": null, "accountId": "550e8400-e29b-41d4-a716-446655440000", "contraAccountId": "550e8400-e29b-41d4-a716-446655440001", "lines": [ { "accountId": "550e8400-e29b-41d4-a716-446655440000", "type": "debit", "accountAmount": 500, "accountCurrency": "DKK", "functionalAmount": 500, "originalAmount": 200, "isVatLine": false, "vatSourceLineIndex": 0, "vatCodeId": "550e8400-e29b-41d4-a716-446655440000", "description": "Consulting hours — March", "tagIds": [ "string" ] } ], "customerId": "550e8400-e29b-41d4-a716-446655440002", "supplierId": "550e8400-e29b-41d4-a716-446655440003", "vendorId": "550e8400-e29b-41d4-a716-446655440003", "vatCodeId": "550e8400-e29b-41d4-a716-446655440000", "tagIds": [ "string" ], "documentRefs": [ "string" ], "createdAt": "2026-01-15T10:30:00.000Z", "warnings": [ { "code": "JOURNAL_ENTRY_YEAR_END_ACCOUNT_POSTED", "details": { "accountId": "550e8400-e29b-41d4-a716-446655440000" } } ] }
json
application/json

Update a journal entry — correct the reference and/or set your external system id

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

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

Partial update of a posted journal entry. Provide at least one of reference, externalSystemId.

reference corrects the reference on a CUSTOMER_INVOICE / CUSTOMER_PAYMENT / SUPPLIER_INVOICE / SUPPLIER_PAYMENT entry and re-runs payment ↔ invoice matching. Use this when an entry was booked with a wrong reference and therefore never matched.

externalSystemId stores your own system's id for the entry. It is metadata: settable on any journal type regardless of match state, and never affects matching. It is not unique — several entries may share one id; filter GET /journal-entries?externalSystemId=... to list them.

Reference corrections apply to unmatched journal entries only. A payment that settles an invoice carries amounts derived against that invoice (currency and original exchange rate), and which invoice a payment settled is part of the books — neither can be edited in place. Documents with settlement activity are rejected with 409 JOURNAL_ENTRY_REFERENCE_UPDATE_ALREADY_MATCHED.

Matched to the wrong journal entry? Reverse the entry with POST /api/v1/journal-entries/reverse and re-book it with the correct reference via POST /api/v2/journal-entries. The reversal keeps the audit trail intact, and the re-booked entry derives its settlement amounts against the correct invoice.

Payments: the journal entry must be UNMATCHED (not linked to an invoice). After the update the corrected reference is looked up against the counterparty's invoices — on a hit the payment is linked and the invoice status recomputed (OPEN → PARTIALLY_PAID / PAID). On a miss the payment stays unmatched and can be corrected again.

Invoices: the invoice must have no settlement activity (no applied payments or linked credit notes). The invoice number is updated and any payments already waiting on the corrected number are matched in the same transaction. A 409 is returned when the invoice is already settled against, or when another invoice for the same counterparty already uses the new number.

Reference corrections on reversed entries and other journal types are rejected with 400.

Required Scope

  • journal-entries-write

Update a journal entry — correct the reference and/or set your external system id › path Parameters

id
​string · required

Journal entry ID

Update a journal entry — correct the reference and/or set your external system id › Headers

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

Optional idempotency key for safely retrying mutating requests.

Update a journal entry — correct the reference and/or set your external system id › Request Body

UpdateJournalEntryRequest
reference
​string · maxLength: 255

Corrected 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.

Example: INV-1042
externalSystemId
​string | null · maxLength: 255

Your 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.

Example: erp-7f3a2c91

Update a journal entry — correct the reference and/or set your external system id › Responses

Journal entry updated.

UpdateJournalEntryResponse
id
​string · required

Journal entry ID.

Example: 550e8400-e29b-41d4-a716-446655440000
reference
​string | null · required

The reference after the update.

Example: INV-1042
externalSystemId
​string | null · required

The external system id after the update.

Example: erp-7f3a2c91
PATCH/v1/journal-entries/{id}
curl https://api.ledgerbee.com/api/v1/journal-entries/:id \ --request PATCH \ --header 'Content-Type: application/json' \ --header 'x-api-key: <api-key>' \ --data '{ "reference": "INV-1042", "externalSystemId": "erp-7f3a2c91" }'
Example Request Body
{ "reference": "INV-1042", "externalSystemId": "erp-7f3a2c91" }
json
application/json
Example Responses
{ "id": "550e8400-e29b-41d4-a716-446655440000", "reference": "INV-1042", "externalSystemId": "erp-7f3a2c91" }
json
application/json

Get attachments for a journal entry

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

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

Retrieves all attachments/documents associated with a journal entry.

Required Scope

  • journal-entries-read

Get attachments for a journal entry › path Parameters

id
​string · required

Journal entry ID (UUID)

Example: 550e8400-e29b-41d4-a716-446655440000

Get attachments for a journal entry › Responses

Attachments retrieved successfully

JournalEntryAttachmentsListResponse
journalEntryId
​string · required

Journal entry ID the attachments belong to

Example: 550e8400-e29b-41d4-a716-446655440000
​JournalEntryAttachmentResponse[] · required

List of attachments

GET/v1/journal-entries/{id}/attachments
curl https://api.ledgerbee.com/api/v1/journal-entries/:id/attachments \ --header 'x-api-key: <api-key>'
Example Responses
{ "journalEntryId": "550e8400-e29b-41d4-a716-446655440000", "attachments": [ { "id": "550e8400-e29b-41d4-a716-446655440000", "filename": "invoice.pdf", "contentType": "application/pdf", "fileSize": 102400, "content": "JVBERi0xLjQKJeLjz9MKMyAwIG9iago8PC...", "createdAt": "2026-01-15T10:30:00.000Z" } ] }
json
application/json

Add a document to a journal entry

POST
https://api.ledgerbee.com/api
/v1/journal-entries/{id}/attachments
x-api-key (header)
or
OAuth 2.0

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

Uploads a file and attaches it to a posted journal entry — a receipt or an invoice that arrived after the entry was booked.

Send the file as the multipart form field file: PDF, JPEG or PNG, up to 10 MB. When the part is sent as application/octet-stream, the type is taken from the file name's extension. The content must match the type, or the upload is rejected with 400 DOCUMENT_UPLOAD_INVALID_FILE_TYPE. A file over 10 MB is rejected with 413.

Attaching a document changes no amounts, so it is allowed when the entry's accounting period is closed. When the entry is reconciled to a card transaction, the receipt is also sent to the card provider.

The response carries the new document id; pass it to DELETE /api/v1/journal-entries/{id}/attachments/{documentId} to take the document off again.

Required Scope

  • journal-entries-write

Add a document to a journal entry › path Parameters

id
​string · required

Journal entry ID (UUID)

Add a document to a journal entry › Headers

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

Optional idempotency key for safely retrying mutating requests.

Add a document to a journal entry › Request Body

file
​string · required

The document: PDF, JPEG or PNG, up to 10 MB.

Add a document to a journal entry › Responses

Document attached

JournalEntryAttachmentAddedResponse
id
​string · required

ID of the new attachment/document. Pass it to the remove endpoint to take the document off again.

Example: 550e8400-e29b-41d4-a716-446655440000
journalEntryId
​string · required

Journal entry ID the attachment was added to

Example: 550e8400-e29b-41d4-a716-446655440000
POST/v1/journal-entries/{id}/attachments
curl https://api.ledgerbee.com/api/v1/journal-entries/:id/attachments \ --request POST \ --header 'Content-Type: multipart/form-data' \ --header 'x-api-key: <api-key>' \ --form 'file=file'
Example Request Body
{ "file": "file" }
text
Example Responses
{ "id": "550e8400-e29b-41d4-a716-446655440000", "journalEntryId": "550e8400-e29b-41d4-a716-446655440000" }
json
application/json

Remove a document from a journal entry

DELETE
https://api.ledgerbee.com/api
/v1/journal-entries/{id}/attachments/{documentId}
x-api-key (header)
or
OAuth 2.0

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

Takes a document off a posted journal entry — one attached by mistake. The document is not deleted: it returns to the inbox, unless another journal entry or draft still uses it.

Removing a document changes no amounts, so it is allowed when the entry's accounting period is closed. A receipt already sent to the card provider stays there; the removal applies in LedgerBee only.

Returns 404 JOURNAL_ENTRY_DOCUMENT_NOT_ATTACHED when the document is not attached to the entry.

Required Scope

  • journal-entries-write

Remove a document from a journal entry › path Parameters

id
​string · required

Journal entry ID (UUID)

documentId
​string · required

Document ID (UUID), as listed by GET /api/v1/journal-entries/{id}/attachments

Remove a document from a journal entry › Headers

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

Optional idempotency key for safely retrying mutating requests.

Remove a document from a journal entry › Responses

Document removed from the journal entry

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

Preview a correction without posting it

POST
https://api.ledgerbee.com/api
/v1/journal-entries/{id}/correct/preview
x-api-key (header)
or
OAuth 2.0

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

Runs the correction for real inside a transaction and rolls it back, so the response is what the entries would actually look like rather than a re-derivation of them. Nothing is posted and nothing is left behind.

The response carries the reversal, and — for reverseAndCorrect and reclassify — the replacement entry beside it. A reclassify preview also returns the original for comparison and marks each changed line with isChanged.

Every eligibility rule the real correction applies is applied here too, so a preview that returns 400 tells you the correction would be refused, and why.

Required Scope

  • journal-entries-write

Preview a correction without posting it › path Parameters

id
​string · required

Journal entry ID (UUID)

Preview a correction without posting it › Headers

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

Optional idempotency key for safely retrying mutating requests.

Preview a correction without posting it › Request Body

PreviewJournalEntryCorrectionRequest
correctionType
​string · enum · required

Which correction to preview.

Enum values:
reverseOnly
reverseAndCorrect
reclassify
Example: reclassify
correctionDate
​string · pattern: ^\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.

Example: 2026-06-01
reason
​string · maxLength: 1700

Free-text reason appended to the correction description for audit purposes.

Example: Booked with 0% VAT instead of 25%
​ReclassifyJournalEntryLine[] · maxItems: 100

Line changes to preview (max 100). Required for reclassify, ignored by the other two types.

Preview a correction without posting it › Responses

Preview produced. Nothing was posted.

JournalEntryCorrectionPreviewResponse
​object · required

The reversal that would neutralise the original.

​object

The entry as it stands today, for comparison. Present on a reclassification preview.

​object

The replacement entry. Absent for reverseOnly, which posts no replacement.

POST/v1/journal-entries/{id}/correct/preview
curl https://api.ledgerbee.com/api/v1/journal-entries/:id/correct/preview \ --request POST \ --header 'Content-Type: application/json' \ --header 'x-api-key: <api-key>' \ --data '{ "correctionDate": "2026-06-01", "reason": "Booked with 0% VAT instead of 25%", "correctionType": "reclassify", "lines": [ { "ledgerTransactionId": "550e8400-e29b-41d4-a716-446655440000", "newAccountId": "550e8400-e29b-41d4-a716-446655440001", "newVatCodeId": "550e8400-e29b-41d4-a716-446655440002" } ] }'
Example Request Body
{ "correctionDate": "2026-06-01", "reason": "Booked with 0% VAT instead of 25%", "correctionType": "reclassify", "lines": [ { "ledgerTransactionId": "550e8400-e29b-41d4-a716-446655440000", "newAccountId": "550e8400-e29b-41d4-a716-446655440001", "newVatCodeId": "550e8400-e29b-41d4-a716-446655440002" } ] }
json
application/json
Example Responses
{ "originalEntry": { "description": "Correction of INV-1042", "date": "2026-06-01", "entryType": "reversal", "isDraft": true, "lines": [ { "accountNumber": "6200", "accountName": "Brændstof", "amount": 5000, "type": "debit", "currency": "DKK", "vatCodeName": "I25", "isChanged": true, "isVatTransaction": true } ], "totalDebit": 5000, "totalCredit": 5000, "totalCurrency": "DKK", "enteredAs": { "amount": 1000, "currency": "EUR", "exchangeRate": 7.45 } }, "reversalEntry": { "description": "Correction of INV-1042", "date": "2026-06-01", "entryType": "reversal", "isDraft": true, "lines": [ { "accountNumber": "6200", "accountName": "Brændstof", "amount": 5000, "type": "debit", "currency": "DKK", "vatCodeName": "I25", "isChanged": true, "isVatTransaction": true } ], "totalDebit": 5000, "totalCredit": 5000, "totalCurrency": "DKK", "enteredAs": { "amount": 1000, "currency": "EUR", "exchangeRate": 7.45 } }, "newEntry": { "description": "Correction of INV-1042", "date": "2026-06-01", "entryType": "reversal", "isDraft": true, "lines": [ { "accountNumber": "6200", "accountName": "Brændstof", "amount": 5000, "type": "debit", "currency": "DKK", "vatCodeName": "I25", "isChanged": true, "isVatTransaction": true } ], "totalDebit": 5000, "totalCredit": 5000, "totalCurrency": "DKK", "enteredAs": { "amount": 1000, "currency": "EUR", "exchangeRate": 7.45 } } }
json
application/json

Move postings to different accounts, keeping the document intact

POST
https://api.ledgerbee.com/api
/v1/journal-entries/{id}/correct/reclassify
x-api-key (header)
or
OAuth 2.0

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

Reverses the original and posts a replacement in one transaction, with the named lines on their new accounts and every other line copied unchanged. Both entries stay on the books, so the trail shows the error and the fix.

The invoice anchor survives: an invoice reclassified this way stays payable, on the same anchor, for the same amount, and its settlements and credit-note links are carried onto the replacement. That is what makes this the right verb for a mis-coded expense or a wrong VAT code on a document the counterparty already holds.

newVatCodeId re-splits the line's gross amount, so the net posted to the account moves even though the document total does not. Preview it first if that matters.

A line can move only to an account whose currency equals the line's accountCurrency. A move to an account in another currency is refused with 400 JOURNAL_ENTRY_RECLASSIFY_TARGET_ACCOUNT_CURRENCY_MISMATCH, and nothing is posted.

Required Scope

  • journal-entries-write

Move postings to different accounts, keeping the document intact › path Parameters

id
​string · required

Journal entry ID (UUID)

Move postings to different accounts, keeping the document intact › Headers

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

Optional idempotency key for safely retrying mutating requests.

Move postings to different accounts, keeping the document intact › Request Body

ReclassifyJournalEntryRequest
​ReclassifyJournalEntryLine[] · minItems: 1 · maxItems: 100 · required

The lines to move (1-100). Lines not listed are copied to the replacement entry unchanged.

correctionDate
​string · pattern: ^\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.

Example: 2026-06-01
reason
​string · maxLength: 1700

Free-text reason appended to the correction description for audit purposes.

Example: Booked with 0% VAT instead of 25%

Move postings to different accounts, keeping the document intact › Responses

Reversal and reclassified replacement posted

ReclassifyJournalEntryResponse
reversalId
​string · required

Unique identifier of the posted reversal of the original entry.

Example: 550e8400-e29b-41d4-a716-446655440000
newEntryId
​string · required

Unique identifier of the posted replacement entry carrying the new account and VAT coding.

Example: 550e8400-e29b-41d4-a716-446655440010
​JournalEntryWarningDto[]

Notes on the replacement entry, as codes. Present only when there is one: JOURNAL_ENTRY_YEAR_END_ACCOUNT_POSTED when it has a line on the company year-end account and every other line is on a balance-sheet account. A replacement with a line there and an income or expense line is refused with 400 JOURNAL_ENTRY_YEAR_END_ACCOUNT_RESULT_LINE.

POST/v1/journal-entries/{id}/correct/reclassify
curl https://api.ledgerbee.com/api/v1/journal-entries/:id/correct/reclassify \ --request POST \ --header 'Content-Type: application/json' \ --header 'x-api-key: <api-key>' \ --data '{ "correctionDate": "2026-06-01", "reason": "Booked with 0% VAT instead of 25%", "lines": [ { "ledgerTransactionId": "550e8400-e29b-41d4-a716-446655440000", "newAccountId": "550e8400-e29b-41d4-a716-446655440001", "newVatCodeId": "550e8400-e29b-41d4-a716-446655440002" } ] }'
Example Request Body
{ "correctionDate": "2026-06-01", "reason": "Booked with 0% VAT instead of 25%", "lines": [ { "ledgerTransactionId": "550e8400-e29b-41d4-a716-446655440000", "newAccountId": "550e8400-e29b-41d4-a716-446655440001", "newVatCodeId": "550e8400-e29b-41d4-a716-446655440002" } ] }
json
application/json
Example Responses
{ "reversalId": "550e8400-e29b-41d4-a716-446655440000", "newEntryId": "550e8400-e29b-41d4-a716-446655440010", "warnings": [ { "code": "JOURNAL_ENTRY_YEAR_END_ACCOUNT_POSTED", "details": { "accountId": "550e8400-e29b-41d4-a716-446655440000" } } ] }
json
application/json

Rebuild the entry a reversal undid, as a draft

POST
https://api.ledgerbee.com/api
/v1/journal-entries/{id}/correct/recreate-draft
x-api-key (header)
or
OAuth 2.0

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

A reversal cannot itself be reversed. When the reversal was the mistake, this rebuilds the original as an unlocked DRAFT on its own sides, with its accounts, amounts, VAT codes, dimensions and documents.

Nothing is posted and the reversal and the original stay as they are. Review the draft through the drafts endpoints and book it; all three entries then stand and the ledger is back at the original position.

Pass the REVERSAL's id. An invoice or a supplier bill rebuilds under its own number and date. A payment is refused with JOURNAL_ENTRY_RECREATE_UNSUPPORTED_JOURNAL_TYPE, because it would post without restoring the invoices it settled, and an id that is no reversal with JOURNAL_ENTRY_RECREATE_SOURCE_NOT_REVERSAL. An entry is rebuilt once: while its draft is open the call answers JOURNAL_ENTRY_HAS_PENDING_CORRECTION_DRAFT, and once a replacement is booked JOURNAL_ENTRY_ALREADY_CORRECTED.

Required Scope

  • journal-entries-write

Rebuild the entry a reversal undid, as a draft › path Parameters

id
​string · required

ID of the reversal entry (UUID)

Rebuild the entry a reversal undid, as a draft › Headers

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

Optional idempotency key for safely retrying mutating requests.

Rebuild the entry a reversal undid, as a draft › Responses

Draft created

RecreateJournalEntryResponseDto
draftId
​string · required

Unique identifier of the unlocked DRAFT rebuilding the original. Nothing is posted until the draft is booked.

Example: 550e8400-e29b-41d4-a716-446655440010
originalEntryId
​string · required

Unique identifier of the original entry the reversal undid.

Example: 550e8400-e29b-41d4-a716-446655440000
POST/v1/journal-entries/{id}/correct/recreate-draft
curl https://api.ledgerbee.com/api/v1/journal-entries/:id/correct/recreate-draft \ --request POST \ --header 'x-api-key: <api-key>'
Example Responses
{ "draftId": "550e8400-e29b-41d4-a716-446655440010", "originalEntryId": "550e8400-e29b-41d4-a716-446655440000" }
json
application/json

Preview rebuilding the entry a reversal undid

POST
https://api.ledgerbee.com/api
/v1/journal-entries/{id}/correct/recreate-draft/preview
x-api-key (header)
or
OAuth 2.0

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

Answers which entry the reversal undid and the date a rebuilt draft would take, and refuses for the same reasons the rebuild does. Nothing is created.

Required Scope

  • journal-entries-write

Preview rebuilding the entry a reversal undid › path Parameters

id
​string · required

ID of the reversal entry (UUID)

Preview rebuilding the entry a reversal undid › Headers

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

Optional idempotency key for safely retrying mutating requests.

Preview rebuilding the entry a reversal undid › Responses

The rebuild would be accepted. Nothing was created.

PreviewRecreateJournalEntryResponseDto
originalEntryId
​string · required

Unique identifier of the original entry the reversal undid, which the draft rebuilds.

Example: 550e8400-e29b-41d4-a716-446655440000
draftDate
​string · required

The date the draft would take (YYYY-MM-DD): the document's own date for an invoice or a supplier bill, otherwise today.

Example: 2026-03-01
POST/v1/journal-entries/{id}/correct/recreate-draft/preview
curl https://api.ledgerbee.com/api/v1/journal-entries/:id/correct/recreate-draft/preview \ --request POST \ --header 'x-api-key: <api-key>'
Example Responses
{ "originalEntryId": "550e8400-e29b-41d4-a716-446655440000", "draftDate": "2026-03-01" }
json
application/json

Reverse a posted entry and open a draft to re-enter it

POST
https://api.ledgerbee.com/api
/v1/journal-entries/{id}/correct/reverse-and-correct
x-api-key (header)
or
OAuth 2.0

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

Posts the reversal immediately and creates an unlocked DRAFT pre-filled from the original, so the books are neutral while the replacement is being fixed. Use this when the entry is wrong in a way that needs re-keying rather than a line-for-line account swap.

Nothing replaces the original until you book the draft. Edit it through the drafts endpoints and book it; abandoning it leaves the reversal standing on its own, which is a plain reversal.

Required Scope

  • journal-entries-write

Reverse a posted entry and open a draft to re-enter it › path Parameters

id
​string · required

Journal entry ID (UUID)

Reverse a posted entry and open a draft to re-enter it › Headers

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

Optional idempotency key for safely retrying mutating requests.

Reverse a posted entry and open a draft to re-enter it › Request Body

ReverseAndCorrectJournalEntryRequest
correctionDate
​string · pattern: ^\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.

Example: 2026-06-01
reason
​string · maxLength: 1700

Free-text reason appended to the correction description for audit purposes.

Example: Booked with 0% VAT instead of 25%

Reverse a posted entry and open a draft to re-enter it › Responses

Reversal posted and correction draft created

ReverseAndCorrectJournalEntryResponse
reversalId
​string · required

Unique identifier of the posted reversal journal entry.

Example: 550e8400-e29b-41d4-a716-446655440000
draftId
​string · required

Unique 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.

Example: 550e8400-e29b-41d4-a716-446655440010
POST/v1/journal-entries/{id}/correct/reverse-and-correct
curl https://api.ledgerbee.com/api/v1/journal-entries/:id/correct/reverse-and-correct \ --request POST \ --header 'Content-Type: application/json' \ --header 'x-api-key: <api-key>' \ --data '{ "correctionDate": "2026-06-01", "reason": "Booked with 0% VAT instead of 25%" }'
Example Request Body
{ "correctionDate": "2026-06-01", "reason": "Booked with 0% VAT instead of 25%" }
json
application/json
Example Responses
{ "reversalId": "550e8400-e29b-41d4-a716-446655440000", "draftId": "550e8400-e29b-41d4-a716-446655440010" }
json
application/json

Reverse posted journal entries in batch

POST
https://api.ledgerbee.com/api
/v1/journal-entries/batch-reverse
x-api-key (header)
or
OAuth 2.0

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

Atomically reverses 1–100 posted journal entries in a single transaction. The original entries are left untouched; both originals and reversals remain visible in ledger / aging / balance reports so the audit trail is preserved.

Date handling: when reversalDate is omitted, each reversal is dated to its own original entry so the original/reversal pair lands in the same posting period. When reversalDate is supplied it applies to every reversal in the batch.

The posting period for every reversal date must be open. Duplicate IDs in the request are de-duplicated. If any reversal fails (closed period, ineligible source entry, etc.) the whole batch rolls back and no reversals are persisted.

Required Scope

  • journal-entries-write

Reverse posted journal entries in batch › Headers

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

Optional idempotency key for safely retrying mutating requests.

Reverse posted journal entries in batch › Request Body

BatchReverseJournalEntriesRequest
journalEntryIds
​string[] · minItems: 1 · maxItems: 100 · required

IDs 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.

Example: ["550e8400-e29b-41d4-a716-446655440000","550e8400-e29b-41d4-a716-446655440001"]
reversalDate
​string

Date 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.

Example: 2026-06-01
reason
​string · maxLength: 500

Free-text reason appended to every reversal description for audit purposes.

Example: Bulk reversal of misclassified subscription invoices

Reverse posted journal entries in batch › Responses

Reversals posted successfully

BatchReverseJournalEntriesResponse
totalReversed
​number · required

Number of reversals posted. Equals the count of unique IDs in the request on success.

Example: 2
​BatchReverseJournalEntriesResultItem[] · required

Result rows pairing each original ID with its newly created reversal ID.

POST/v1/journal-entries/batch-reverse
curl https://api.ledgerbee.com/api/v1/journal-entries/batch-reverse \ --request POST \ --header 'Content-Type: application/json' \ --header 'x-api-key: <api-key>' \ --data '{ "journalEntryIds": [ "550e8400-e29b-41d4-a716-446655440000", "550e8400-e29b-41d4-a716-446655440001" ], "reversalDate": "2026-06-01", "reason": "Bulk reversal of misclassified subscription invoices" }'
Example Request Body
{ "journalEntryIds": [ "550e8400-e29b-41d4-a716-446655440000", "550e8400-e29b-41d4-a716-446655440001" ], "reversalDate": "2026-06-01", "reason": "Bulk reversal of misclassified subscription invoices" }
json
application/json
Example Responses
{ "totalReversed": 2, "results": [ { "originalId": "550e8400-e29b-41d4-a716-446655440000", "reversalId": "550e8400-e29b-41d4-a716-446655440010" } ] }
json
application/json

Preview reversing posted journal entries in batch

POST
https://api.ledgerbee.com/api
/v1/journal-entries/batch-reverse/preview
x-api-key (header)
or
OAuth 2.0

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

Takes the same body as POST /api/v1/journal-entries/batch-reverse and answers whether that call would succeed, without posting anything. The batch runs for real inside a transaction and is rolled back, so the first refusal the batch would raise — an entry already reversed, a reversal of a reversal, a closed posting period, an invoice whose payment is still live and not in the batch — comes back here with the same 400 the write would answer.

On success the response lists each original entry with its entry number and the date its reversal would post on.

Required Scope

  • journal-entries-write

Preview reversing posted journal entries in batch › Headers

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

Optional idempotency key for safely retrying mutating requests.

Preview reversing posted journal entries in batch › Request Body

BatchReverseJournalEntriesRequest
journalEntryIds
​string[] · minItems: 1 · maxItems: 100 · required

IDs 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.

Example: ["550e8400-e29b-41d4-a716-446655440000","550e8400-e29b-41d4-a716-446655440001"]
reversalDate
​string

Date 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.

Example: 2026-06-01
reason
​string · maxLength: 500

Free-text reason appended to every reversal description for audit purposes.

Example: Bulk reversal of misclassified subscription invoices

Preview reversing posted journal entries in batch › Responses

Preview produced. Nothing was posted.

BatchReverseJournalEntriesPreviewResponse
totalReversible
​number · required

Number of reversals the batch would post. Equals the count of unique IDs in the request.

Example: 2
​BatchReverseJournalEntriesPreviewItem[] · required

Each original entry the batch would reverse, with the date its reversal would carry.

POST/v1/journal-entries/batch-reverse/preview
curl https://api.ledgerbee.com/api/v1/journal-entries/batch-reverse/preview \ --request POST \ --header 'Content-Type: application/json' \ --header 'x-api-key: <api-key>' \ --data '{ "journalEntryIds": [ "550e8400-e29b-41d4-a716-446655440000", "550e8400-e29b-41d4-a716-446655440001" ], "reversalDate": "2026-06-01", "reason": "Bulk reversal of misclassified subscription invoices" }'
Example Request Body
{ "journalEntryIds": [ "550e8400-e29b-41d4-a716-446655440000", "550e8400-e29b-41d4-a716-446655440001" ], "reversalDate": "2026-06-01", "reason": "Bulk reversal of misclassified subscription invoices" }
json
application/json
Example Responses
{ "totalReversible": 2, "results": [ { "originalId": "550e8400-e29b-41d4-a716-446655440000", "originalEntryNumber": "JE-00468", "reversalDate": "2026-06-01" } ] }
json
application/json

Reverse a posted journal entry

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

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

Reverses a single posted journal entry. Mirrors the gated app's "Reverse only, post immediately" correction option — a new POSTED journal entry is created with the original's Dr/Cr lines flipped. The original entry is left untouched; both entries remain visible in ledger / aging / balance reports so the audit trail is preserved.

Date handling: when reversalDate is omitted, the reversal is dated to the original entry so the pair lands in the same posting period. The posting period for the resolved date must be open.

Eligibility: the source entry must be POSTED and not already part of a correction chain that disallows further reversal. The endpoint rejects ineligible entries with 400.

Required Scope

  • journal-entries-write

Reverse a posted journal entry › Headers

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

Optional idempotency key for safely retrying mutating requests.

Reverse a posted journal entry › Request Body

ReverseJournalEntryRequest
journalEntryId
​string · required

UUID of the posted journal entry to reverse.

Example: 550e8400-e29b-41d4-a716-446655440000
reversalDate
​string

Date 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.

Example: 2026-06-01
reason
​string · maxLength: 500

Free-text reason appended to the reversal description for audit purposes.

Example: Vendor invoice was duplicated

Reverse a posted journal entry › Responses

Reversal posted successfully

ReverseJournalEntryResponse
reversalId
​string · required

Unique identifier of the posted reversal journal entry.

Example: 550e8400-e29b-41d4-a716-446655440000
POST/v1/journal-entries/reverse
curl https://api.ledgerbee.com/api/v1/journal-entries/reverse \ --request POST \ --header 'Content-Type: application/json' \ --header 'x-api-key: <api-key>' \ --data '{ "journalEntryId": "550e8400-e29b-41d4-a716-446655440000", "reversalDate": "2026-06-01", "reason": "Vendor invoice was duplicated" }'
Example Request Body
{ "journalEntryId": "550e8400-e29b-41d4-a716-446655440000", "reversalDate": "2026-06-01", "reason": "Vendor invoice was duplicated" }
json
application/json
Example Responses
{ "reversalId": "550e8400-e29b-41d4-a716-446655440000" }
json
application/json

Preview reversing a posted journal entry

POST
https://api.ledgerbee.com/api
/v1/journal-entries/reverse/preview
x-api-key (header)
or
OAuth 2.0

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

Takes the same body as POST /api/v1/journal-entries/reverse and answers with the reversal that call would post, without posting it. The reversal is run for real inside a transaction and rolled back, so the response is the entry it would create and every eligibility rule applies: an entry that is already reversed answers 400 JOURNAL_ENTRY_ALREADY_REVERSED, a reversal of a reversal 400 JOURNAL_ENTRY_CANNOT_CORRECT_REVERSAL, and a date in a closed period is refused as the write would be.

Required Scope

  • journal-entries-write

Preview reversing a posted journal entry › Headers

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

Optional idempotency key for safely retrying mutating requests.

Preview reversing a posted journal entry › Request Body

ReverseJournalEntryRequest
journalEntryId
​string · required

UUID of the posted journal entry to reverse.

Example: 550e8400-e29b-41d4-a716-446655440000
reversalDate
​string

Date 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.

Example: 2026-06-01
reason
​string · maxLength: 500

Free-text reason appended to the reversal description for audit purposes.

Example: Vendor invoice was duplicated

Preview reversing a posted journal entry › Responses

Preview produced. Nothing was posted.

JournalEntryCorrectionPreviewResponse
​object · required

The reversal that would neutralise the original.

​object

The entry as it stands today, for comparison. Present on a reclassification preview.

​object

The replacement entry. Absent for reverseOnly, which posts no replacement.

POST/v1/journal-entries/reverse/preview
curl https://api.ledgerbee.com/api/v1/journal-entries/reverse/preview \ --request POST \ --header 'Content-Type: application/json' \ --header 'x-api-key: <api-key>' \ --data '{ "journalEntryId": "550e8400-e29b-41d4-a716-446655440000", "reversalDate": "2026-06-01", "reason": "Vendor invoice was duplicated" }'
Example Request Body
{ "journalEntryId": "550e8400-e29b-41d4-a716-446655440000", "reversalDate": "2026-06-01", "reason": "Vendor invoice was duplicated" }
json
application/json
Example Responses
{ "originalEntry": { "description": "Correction of INV-1042", "date": "2026-06-01", "entryType": "reversal", "isDraft": true, "lines": [ { "accountNumber": "6200", "accountName": "Brændstof", "amount": 5000, "type": "debit", "currency": "DKK", "vatCodeName": "I25", "isChanged": true, "isVatTransaction": true } ], "totalDebit": 5000, "totalCredit": 5000, "totalCurrency": "DKK", "enteredAs": { "amount": 1000, "currency": "EUR", "exchangeRate": 7.45 } }, "reversalEntry": { "description": "Correction of INV-1042", "date": "2026-06-01", "entryType": "reversal", "isDraft": true, "lines": [ { "accountNumber": "6200", "accountName": "Brændstof", "amount": 5000, "type": "debit", "currency": "DKK", "vatCodeName": "I25", "isChanged": true, "isVatTransaction": true } ], "totalDebit": 5000, "totalCredit": 5000, "totalCurrency": "DKK", "enteredAs": { "amount": 1000, "currency": "EUR", "exchangeRate": 7.45 } }, "newEntry": { "description": "Correction of INV-1042", "date": "2026-06-01", "entryType": "reversal", "isDraft": true, "lines": [ { "accountNumber": "6200", "accountName": "Brændstof", "amount": 5000, "type": "debit", "currency": "DKK", "vatCodeName": "I25", "isChanged": true, "isVatTransaction": true } ], "totalDebit": 5000, "totalCredit": 5000, "totalCurrency": "DKK", "enteredAs": { "amount": 1000, "currency": "EUR", "exchangeRate": 7.45 } } }
json
application/json

Journal CategoriesJournal Entries (v2)