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

Draft Journal Entries (v2)

Download schema

Create draft journal entries in batch (v2)

POST
https://api.ledgerbee.com/api
/v2/draft-journal-batches
x-api-key (header)
or
OAuth 2.0

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

Atomically creates 1–100 draft journal entries in a single transaction. Each entry follows the same restrictions as POST /api/v2/draft-journal-entries: auto-append of the AR/AP leg for locked types, tenant-scoped customerId / supplierId / journalCategoryId / line accountId validation.

If any entry fails validation or persistence the entire batch is rolled back — no draft rows are created. journalCategoryId / customerId / supplierId / accountId from another tenant rejects the whole batch with the matching error code.

Answers with every created draft in entries, in request order, each as GET /api/v2/draft-journal-entries/:id returns it. A retry with the same x-api-idempotency-key creates nothing and answers { idempotentReplay: true, id: null }; a retry while the first is still running answers 409 IDEMPOTENT_REQUEST_IN_PROGRESS, and a key already used on a different endpoint answers 422 IDEMPOTENCY_KEY_REUSED. The body is not compared: the same key with a different body also answers the replay above and creates nothing.

Attachments: each entry may include up to 10 base64-encoded attachments[]. A failure on any entry rolls back the whole batch and deletes every already-uploaded blob — no orphan documents survive.

Required Scope

  • journal-entries-write

Create draft journal entries in batch (v2) › Headers

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

Optional idempotency key for safely retrying mutating requests.

Create draft journal entries in batch (v2) › Request Body

CreateDraftJournalEntryV2BatchRequest
​CreateDraftJournalEntryV2Request[] · minItems: 1 · maxItems: 100 · required

Array of 1–100 draft journal entries, carrying at most 10000 lines in total across the batch. Wrapped in a single transaction; one bad entry rolls back the whole batch.

Create draft journal entries in batch (v2) › Responses

Batch created — every draft persisted

CreateDraftJournalEntryV2BatchResponse
totalCreated
​number · required

Number of drafts created (= entries.length on success).

​DraftJournalEntryResponse[] · required

Created draft journal entries, ordered to match the request entries[].

POST/v2/draft-journal-batches
curl https://api.ledgerbee.com/api/v2/draft-journal-batches \ --request POST \ --header 'Content-Type: application/json' \ --header 'x-api-key: <api-key>' \ --data '{ "entries": [ { "entryType": "journal", "date": "string", "documentDate": "2026-03-28", "dueDate": "2026-04-27", "originalAmount": 0, "customerId": "string", "supplierId": "string", "vendorId": "string", "description": "string", "reference": "string", "externalSystemId": "erp-7f3a2c91", "lines": [], "tagIds": [ "string" ], "journalCategoryId": "string", "attachments": [], "originalCurrency": "EUR", "currency": "EUR", "originalCurrencyToBaseCurrencyExchangeRate": 7.4612, "exchangeRate": 7.4612 } ] }'
Example Request Body
{ "entries": [ { "entryType": "journal", "date": "string", "documentDate": "2026-03-28", "dueDate": "2026-04-27", "originalAmount": 0, "customerId": "string", "supplierId": "string", "vendorId": "string", "description": "string", "reference": "string", "externalSystemId": "erp-7f3a2c91", "lines": [], "tagIds": [ "string" ], "journalCategoryId": "string", "attachments": [], "originalCurrency": "EUR", "currency": "EUR", "originalCurrencyToBaseCurrencyExchangeRate": 7.4612, "exchangeRate": 7.4612 } ] }
json
application/json
Example Responses
{ "totalCreated": 0, "entries": [ { "id": "550e8400-e29b-41d4-a716-446655440000", "date": "2026-01-15", "documentDate": "2026-01-15", "dueDate": "2026-02-14", "baseCurrencyAmount": 7450, "originalAmount": 1000, "originalCurrency": "EUR", "originalCurrencyToBaseCurrencyExchangeRate": 7.45, "originalCurrencyToBaseCurrencyExchangeRateDate": "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", "accountId": "550e8400-e29b-41d4-a716-446655440000", "contraAccountId": "550e8400-e29b-41d4-a716-446655440001", "customerId": "550e8400-e29b-41d4-a716-446655440002", "supplierId": "550e8400-e29b-41d4-a716-446655440003", "vatCodeId": "550e8400-e29b-41d4-a716-446655440000", "tagIds": [ "string" ], "documentRefs": [ "string" ], "lines": [ { "accountId": "550e8400-e29b-41d4-a716-446655440000", "type": "debit", "amount": 500, "vatCodeId": "550e8400-e29b-41d4-a716-446655440000", "description": "Consulting hours - March", "tagIds": [ "string" ] } ], "status": "DRAFT", "createdAt": "2026-01-15T10:30:00.000Z", "updatedAt": "2026-01-15T10:30:00.000Z", "amount": 7450, "currency": "EUR", "exchangeRate": 7.45, "exchangeRateDate": "2026-01-15", "vendorId": "550e8400-e29b-41d4-a716-446655440003", "splitEntries": [ { "accountId": "550e8400-e29b-41d4-a716-446655440000", "type": "debit", "amount": 500, "vatCodeId": "550e8400-e29b-41d4-a716-446655440000", "description": "Consulting hours — March", "tagIds": [ "string" ] } ] } ] }
json
application/json

List draft journal entries (v2)

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

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

Returns a paginated list of draft journal entries owned by the API key's app company. Tenant-scoped: drafts created by other companies are never visible here. Identical response shape to GET /api/v1/draft-journal-entries.

Required Scope

  • journal-entries-read

List draft journal entries (v2) › 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 items per page

Default: 25
fromDate
​string

Only include drafts on or after this date (YYYY-MM-DD)

Example: 2026-01-01
toDate
​string

Only include drafts on or before this date (YYYY-MM-DD)

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

Filter by account ID (matches any draft line on this account)

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 drafts in this journal category

minBaseCurrencyAmount
​number

Only include drafts whose baseCurrencyAmount (the draft in your company base currency) is greater than or equal to this value (inclusive).

Example: 100
maxBaseCurrencyAmount
​number

Only include drafts whose baseCurrencyAmount (the draft in your company base currency) is less than or equal to this value (inclusive).

Example: 10000
minAmount
​number · deprecated

Deprecated — use minBaseCurrencyAmount. The same filter under its old name. Sending both with different values returns 400 DRAFT_DEPRECATED_FIELD_CONFLICT.

Example: 100
maxAmount
​number · deprecated

Deprecated — use maxBaseCurrencyAmount. The same filter under its old name. Sending both with different values returns 400 DRAFT_DEPRECATED_FIELD_CONFLICT.

Example: 10000
externalSystemId
​string · maxLength: 255

Exact-match filter on your own system's id. Not unique — several drafts may share one id, so expect zero or more results.

Example: erp-7f3a2c91
search
​string

Free-text search in description and reference fields

List draft journal entries (v2) › Responses

Drafts retrieved

ListDraftJournalEntriesResponse
​DraftJournalEntryResponse[] · required

List of draft journal entries

total
​number · required

Total number of matching drafts

Example: 42
limit
​number · required

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: 2
GET/v2/draft-journal-entries
curl https://api.ledgerbee.com/api/v2/draft-journal-entries \ --header 'x-api-key: <api-key>'
Example Responses
{ "data": [ { "id": "550e8400-e29b-41d4-a716-446655440000", "date": "2026-01-15", "documentDate": "2026-01-15", "dueDate": "2026-02-14", "baseCurrencyAmount": 7450, "originalAmount": 1000, "originalCurrency": "EUR", "originalCurrencyToBaseCurrencyExchangeRate": 7.45, "originalCurrencyToBaseCurrencyExchangeRateDate": "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", "accountId": "550e8400-e29b-41d4-a716-446655440000", "contraAccountId": "550e8400-e29b-41d4-a716-446655440001", "customerId": "550e8400-e29b-41d4-a716-446655440002", "supplierId": "550e8400-e29b-41d4-a716-446655440003", "vatCodeId": "550e8400-e29b-41d4-a716-446655440000", "tagIds": [ "string" ], "documentRefs": [ "string" ], "lines": [ { "accountId": "550e8400-e29b-41d4-a716-446655440000", "type": "debit", "amount": 500, "vatCodeId": "550e8400-e29b-41d4-a716-446655440000", "description": "Consulting hours - March", "tagIds": [ "string" ] } ], "status": "DRAFT", "createdAt": "2026-01-15T10:30:00.000Z", "updatedAt": "2026-01-15T10:30:00.000Z", "amount": 7450, "currency": "EUR", "exchangeRate": 7.45, "exchangeRateDate": "2026-01-15", "vendorId": "550e8400-e29b-41d4-a716-446655440003", "splitEntries": [ { "accountId": "550e8400-e29b-41d4-a716-446655440000", "type": "debit", "amount": 500, "vatCodeId": "550e8400-e29b-41d4-a716-446655440000", "description": "Consulting hours — March", "tagIds": [ "string" ] } ] } ], "total": 42, "page": 1, "limit": 25, "totalPages": 2, "nextCursor": "eyJ2IjoxLCJmIjoiOWMxZjQyYWIzMTA4ZDc2ZSIsImsiOlsiMjAyNi0wMS0yMCJdfQ", "hasMore": true }
json
application/json

Create a draft journal entry (v2)

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

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

Creates a draft journal entry with the V2 restriction matrix enforced at create-time (unlike v1, which only validates on book). For CUSTOMER_INVOICE / CUSTOMER_PAYMENT / SUPPLIER_INVOICE / SUPPLIER_PAYMENT submit only the counter-side lines — the server auto-appends the AR/AP leg on the partner group default account.

Answers with the created draft, the body GET /api/v2/draft-journal-entries/:id returns. A retry with the same x-api-idempotency-key creates nothing and answers { idempotentReplay: true, id }; a retry while the first is still running answers 409 IDEMPOTENT_REQUEST_IN_PROGRESS, and a key already used on a different endpoint answers 422 IDEMPOTENCY_KEY_REUSED. The body is not compared: the same key with a different body also answers the replay above and creates nothing.

Tenant scoping: every customerId / supplierId / journalCategoryId / line accountId is validated against the API key's app company. Cross-tenant or unknown ids reject with 400 (JOURNAL_CATEGORY_NOT_FOUND, ACCOUNT_NOT_FOUND, CUSTOMER_HAS_NO_GROUP, SUPPLIER_HAS_NO_GROUP, INVOICE_AR_LEG_NOT_ON_GROUP_DEFAULT, PAYMENT_AR_LEG_NOT_ON_GROUP_DEFAULT, INVOICE_AP_LEG_NOT_ON_GROUP_DEFAULT, PAYMENT_AP_LEG_NOT_ON_GROUP_DEFAULT).

Attachments: include up to 10 base64-encoded files in the optional attachments[] field — same shape and limits as POST /api/v2/journal-entries. Each becomes a Document linked to the draft; when the draft is booked, the documents migrate to the posted JE and surface via GET /api/v1/journal-entries/:id/attachments. Rejection paths: an invalid MIME type rejects at DTO validation with 400 SHARED_VALIDATION_FAILED; malformed base64 reaches the service and rejects with 400 JOURNAL_ENTRY_INVALID_ATTACHMENT_TYPE.

Required Scope

  • journal-entries-write

Create a draft journal entry (v2) › Headers

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

Optional idempotency key for safely retrying mutating requests.

Create a draft journal entry (v2) › Request Body

CreateDraftJournalEntryV2Request
entryType
​string · enum · required

Journal type. For CUSTOMER_INVOICE / CUSTOMER_PAYMENT / SUPPLIER_INVOICE / SUPPLIER_PAYMENT the AR/AP leg is appended automatically; do not include it in lines.

Enum values:
journal
invoice
payment
supplier_invoice
supplier_payment
customer_invoice
customer_payment
date
​string · required

Posting date (YYYY-MM-DD).

originalAmount
​number · required

Face value of the document — what the counterparty is invoiced or pays. NOT the sum of lines. On CUSTOMER_INVOICE / CUSTOMER_PAYMENT / SUPPLIER_INVOICE / SUPPLIER_PAYMENT this value IS the appended AR/AP leg (its absolute value), so an account that appears on both sides of the entry — a clearing or pass-through account — must not be counted into it. Sign carries direction: positive = invoice / payment, negative = credit-note / refund.

​SplitEntryLine[] · minItems: 1 · maxItems: 1000 · required

Counter-side lines (revenue / expense / bank / outlay). For locked types do NOT include the AR/AP leg. The cap is per ENTRY, not per request or per journal category — nothing accumulates across entries, so a company with many unposted drafts is never refused for that reason.

documentDate
​string | null

Document date (YYYY-MM-DD): the date printed on the invoice or voucher. The VAT period follows it, so a supplier invoice dated 28 March and booked on 3 April lands in March. Omit it and the entry has no document date of its own; its VAT period then follows date. null is read as omitted.

Example: 2026-03-28
dueDate
​string | null

Due date (YYYY-MM-DD) of a customer or supplier invoice, used exactly as sent. Omit it and the due date is calculated from the customer's or supplier's payment term (else the company default), counted from documentDate when sent and from date otherwise. Accepted only on customer_invoice, supplier_invoice and the deprecated invoice, and only with a reference, which is what registers the invoice the due date belongs to. Sent on any other entry type, it is refused with 400 JOURNAL_ENTRY_DUE_DATE_NOT_ALLOWED; sent without a reference, with 400 JOURNAL_ENTRY_DUE_DATE_REQUIRES_REFERENCE. null is read as omitted.

Example: 2026-04-27
customerId
​string

Customer reference. Required for CUSTOMER_* types.

supplierId
​string

Supplier reference. Required for SUPPLIER_* types.

description
​string · maxLength: 2000

Optional human-readable description.

reference
​string

Invoice number / external reference. On CUSTOMER_PAYMENT it names the invoice being paid, and the appended receivable leg follows where that invoice was booked: on the one account it sits on, which is the customer group account unless the invoice lines sent the receivable elsewhere (a deposit invoice). An invoice owed across several receivable accounts is cleared one leg per account when the payment pays everything it still has open; a part payment of such an invoice is refused with JOURNAL_ENTRY_RECEIVABLE_SPLIT_REQUIRED, because nothing here states which account it clears and it is never divided in proportion.

externalSystemId
​string · maxLength: 255

Your own system's id for this draft. Carried onto the booked journal entry. Not unique — several drafts/entries may share one id. Filter the list endpoint by externalSystemId.

Example: erp-7f3a2c91
tagIds
​string[]

Tag IDs applied at the entry level.

journalCategoryId
​string

Journal category ID (UUID). Must belong to the API key's app company; cross-tenant or unknown IDs are rejected with 400 JOURNAL_CATEGORY_NOT_FOUND. When omitted the entry uses the company's default category.

​AttachmentRequest[] · maxItems: 10

Inline file attachments (base64-encoded). Same shape and limits as v1: maximum 10 attachments per entry, a 10MB ceiling on each file measured AFTER base64 decoding (over it is rejected with DOCUMENT_UPLOAD_FILE_TOO_LARGE), and a 15MB ceiling on the total request body (JSON + base64 payload). Either can be the binding one: base64 inflates a payload by about a third, so two 6MB files each clear the per-file bound and exceed the request one. Each attachment becomes a Document linked to the created journal entry — equivalent to what GET /api/v1/journal-entries/:id/attachments returns. An invalid MIME type rejects at DTO validation with 400 SHARED_VALIDATION_FAILED; malformed base64 reaches the service and rejects with 400 JOURNAL_ENTRY_INVALID_ATTACHMENT_TYPE. Either rejects the whole entry, and in a batch the whole batch rolls back.

originalCurrency
​string | null · minLength: 3 · maxLength: 3 · pattern: ^[A-Za-z]{3}$

ISO 4217 alpha-3 code of the currency the draft is entered in; originalAmount and lines[].amount are in this currency. Omitted under both names, the draft is in your company base currency.

Example: EUR
originalCurrencyToBaseCurrencyExchangeRate
​number

What one unit of originalCurrency is worth in your company base currency, e.g. 7.4612 for EUR to DKK. Must be greater than zero; a non-positive rate is rejected whatever the draft currency. Omit it and exchangeRate to have the rate resolved from the rate feed at the posting date. Not applied when the draft is already in your company base currency, where the conversion is the identity.

Example: 7.4612
vendorId
​string · deprecated

Deprecated — use supplierId. Legacy alias; sending both with different values returns 400.

currency
​string | null · minLength: 3 · maxLength: 3 · deprecated · pattern: ^[A-Za-z]{3}$

Deprecated — use originalCurrency. The same currency code under its old name. Sending both with different codes returns 400 DRAFT_DEPRECATED_FIELD_CONFLICT.

Example: EUR
exchangeRate
​number · deprecated

Deprecated — use originalCurrencyToBaseCurrencyExchangeRate. The same rate under its old name. Sending both with different values returns 400 DRAFT_DEPRECATED_FIELD_CONFLICT.

Example: 7.4612

Create a draft journal entry (v2) › Responses

Draft created

DraftJournalEntryResponse
id
​string · required

Draft journal entry ID

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

Date in YYYY-MM-DD format

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

How large this draft is, in your company base currency — the one your company reports in. A draft entered as EUR 1,000 by a company reporting in DKK is 7450 here.

Do not display this number beside originalCurrency. That field names the currency the draft was entered in (EUR in the example), while this number is in DKK. originalAmount is the figure that belongs beside originalCurrency.

Reads 0 on a draft that holds no figure in this currency. The minBaseCurrencyAmount and maxBaseCurrencyAmount list filters run on this field, so a draft reading 0 here is excluded whenever either filter is applied.

Example: 7450
originalAmount
​number · required

How large this draft is, in the currency it was entered in — the currency originalCurrency names, and the one lines[].amount uses. A draft entered as EUR 1,000 is 1000 here, whatever your company reports in.

This is the figure to display beside originalCurrency. baseCurrencyAmount is the same draft in your company base currency: on that EUR draft this field reads 1000 and baseCurrencyAmount reads 7450. Reads 0 on a draft that carries no amount yet.

Example: 1000
originalCurrency
​string · required

The currency this draft was entered in — EUR for a supplier invoice received in EUR. originalAmount and lines[].amount are in this currency; baseCurrencyAmount is in your company base currency, which is this one only when the draft was entered in it.

Example: EUR
journalType
​string · required

Journal type

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

ID of the journal category the draft is in. Set it with journalCategoryId on the v2 draft create and on PATCH /v2/draft-journal-entries/{id}. Booking the draft keeps it on the journal entry. List the categories with GET /v1/journal-categories. Null when the draft has no category.

Example: 550e8400-e29b-41d4-a716-446655440004
​DraftJournalEntryLine[] · required

Every line of the draft. Always present, an empty array included, so a client never has to distinguish absent from empty. The name matches the lines the v2 draft endpoints take, so a draft reads back through the field it was written with.

status
​string · required

Always "DRAFT" for draft journal entries

Example: DRAFT
createdAt
​string · required

Creation timestamp

Example: 2026-01-15T10:30:00.000Z
updatedAt
​string · required

Last update timestamp

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

Document date (date on the invoice/voucher). Null when not set.

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

Due date stated on the draft (YYYY-MM-DD). Null when none was stated; booking a customer or supplier invoice then calculates one from the payment term.

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

What one unit of originalCurrency is worth in your company base currency. 7.45 on a EUR draft of a company reporting in DKK means 1 EUR buys 7.45 DKK.

This is the rate the draft is converted at, not a factor between the two amounts on this response. baseCurrencyAmount is built from the draft lines rather than from originalAmount, so multiplying originalAmount by this rate does not reliably reproduce it — on a draft whose sides disagree the two figures differ with no rate involved at all. A draft already entered in your own currency carries 1. Null only while a foreign-currency draft has no rate yet — booking gives it one.

Example: 7.45
originalCurrencyToBaseCurrencyExchangeRateDate
​string | null

Date the originalCurrencyToBaseCurrencyExchangeRate was captured for. Null whenever that rate is.

Example: 2026-01-15
description
​string

Description

Example: Office supplies purchase
reference
​string

Reference number

Example: REF-2026-001
externalSystemId
​string | null

Your own system's id for this draft, when set. Not unique. null when unset or cleared.

Example: erp-7f3a2c91
type
​string

Transaction type (debit or credit)

Example: debit
accountId
​string

Primary account ID

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

Contra account ID

Example: 550e8400-e29b-41d4-a716-446655440001
customerId
​string

Customer ID

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

Supplier ID

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

VAT/Tax code ID

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

Tag/Dimension IDs

documentRefs
​string[]

Document IDs attached to the draft

amount
​number · deprecated

Deprecated — use baseCurrencyAmount, which carries the same value. The draft in your company base currency. Do not display it beside currency: that names the currency the draft was entered in. The v1 create takes a request field of the same name carrying the figure the draft is entered in, so a EUR draft sent as amount: 1000 is returned with amount: 7450 — one name, two currencies.

Example: 7450
currency
​string · deprecated

Deprecated — use originalCurrency, which carries the same value. The currency the draft was entered in.

Example: EUR
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
​DraftSplitEntryLineResponse[] · deprecated

Deprecated — use lines. Present only on drafts that need it: a plain one-debit-one-credit draft with no per-line memo or dimensions reports its accounts through accountId / contraAccountId and omits this field entirely. It also reports a placeholder line's account as "", which the write side rejects. lines is populated either way and round-trips.

POST/v2/draft-journal-entries
curl https://api.ledgerbee.com/api/v2/draft-journal-entries \ --request POST \ --header 'Content-Type: application/json' \ --header 'x-api-key: <api-key>' \ --data '{ "entryType": "journal", "date": "string", "documentDate": "2026-03-28", "dueDate": "2026-04-27", "originalAmount": 0, "customerId": "string", "supplierId": "string", "vendorId": "string", "description": "string", "reference": "string", "externalSystemId": "erp-7f3a2c91", "lines": [ { "accountId": "550e8400-e29b-41d4-a716-446655440000", "type": "debit", "amount": 500, "vatCodeId": "550e8400-e29b-41d4-a716-446655440000", "description": "Consulting hours — March", "tagIds": [ "550e8400-e29b-41d4-a716-446655440003" ] } ], "tagIds": [ "string" ], "journalCategoryId": "string", "attachments": [ { "filename": "invoice.pdf", "content": "JVBERi0xLjQKJeLjz9MKMyAwIG9iago8PC...", "mimeType": "application/pdf" } ], "originalCurrency": "EUR", "currency": "EUR", "originalCurrencyToBaseCurrencyExchangeRate": 7.4612, "exchangeRate": 7.4612 }'
Example Request Body
{ "entryType": "journal", "date": "string", "documentDate": "2026-03-28", "dueDate": "2026-04-27", "originalAmount": 0, "customerId": "string", "supplierId": "string", "vendorId": "string", "description": "string", "reference": "string", "externalSystemId": "erp-7f3a2c91", "lines": [ { "accountId": "550e8400-e29b-41d4-a716-446655440000", "type": "debit", "amount": 500, "vatCodeId": "550e8400-e29b-41d4-a716-446655440000", "description": "Consulting hours — March", "tagIds": [ "550e8400-e29b-41d4-a716-446655440003" ] } ], "tagIds": [ "string" ], "journalCategoryId": "string", "attachments": [ { "filename": "invoice.pdf", "content": "JVBERi0xLjQKJeLjz9MKMyAwIG9iago8PC...", "mimeType": "application/pdf" } ], "originalCurrency": "EUR", "currency": "EUR", "originalCurrencyToBaseCurrencyExchangeRate": 7.4612, "exchangeRate": 7.4612 }
json
application/json
Example Responses
{ "id": "550e8400-e29b-41d4-a716-446655440000", "date": "2026-01-15", "documentDate": "2026-01-15", "dueDate": "2026-02-14", "baseCurrencyAmount": 7450, "originalAmount": 1000, "originalCurrency": "EUR", "originalCurrencyToBaseCurrencyExchangeRate": 7.45, "originalCurrencyToBaseCurrencyExchangeRateDate": "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", "accountId": "550e8400-e29b-41d4-a716-446655440000", "contraAccountId": "550e8400-e29b-41d4-a716-446655440001", "customerId": "550e8400-e29b-41d4-a716-446655440002", "supplierId": "550e8400-e29b-41d4-a716-446655440003", "vatCodeId": "550e8400-e29b-41d4-a716-446655440000", "tagIds": [ "string" ], "documentRefs": [ "string" ], "lines": [ { "accountId": "550e8400-e29b-41d4-a716-446655440000", "type": "debit", "amount": 500, "vatCodeId": "550e8400-e29b-41d4-a716-446655440000", "description": "Consulting hours - March", "tagIds": [ "string" ] } ], "status": "DRAFT", "createdAt": "2026-01-15T10:30:00.000Z", "updatedAt": "2026-01-15T10:30:00.000Z", "amount": 7450, "currency": "EUR", "exchangeRate": 7.45, "exchangeRateDate": "2026-01-15", "vendorId": "550e8400-e29b-41d4-a716-446655440003", "splitEntries": [ { "accountId": "550e8400-e29b-41d4-a716-446655440000", "type": "debit", "amount": 500, "vatCodeId": "550e8400-e29b-41d4-a716-446655440000", "description": "Consulting hours — March", "tagIds": [ "string" ] } ] }
json
application/json

Get a draft journal entry (v2)

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

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

Returns the draft if it belongs to the API key's app company; 404 otherwise. Identical response shape to GET /api/v1/draft-journal-entries/:id. Each amount, currency and rate field is named for the currency it is in: originalAmount and originalCurrency are the draft as entered, baseCurrencyAmount is the draft in your company base currency, and originalCurrencyToBaseCurrencyExchangeRate / originalCurrencyToBaseCurrencyExchangeRateDate are the rate from originalCurrency into your company base currency and its date. The deprecated amount, currency, exchangeRate and exchangeRateDate carry the same values as baseCurrencyAmount, originalCurrency and the two rate fields.

Required Scope

  • journal-entries-read

Get a draft journal entry (v2) › path Parameters

id
​string · required

Draft journal entry ID (UUID)

Get a draft journal entry (v2) › Responses

Draft retrieved

DraftJournalEntryResponse
id
​string · required

Draft journal entry ID

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

Date in YYYY-MM-DD format

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

How large this draft is, in your company base currency — the one your company reports in. A draft entered as EUR 1,000 by a company reporting in DKK is 7450 here.

Do not display this number beside originalCurrency. That field names the currency the draft was entered in (EUR in the example), while this number is in DKK. originalAmount is the figure that belongs beside originalCurrency.

Reads 0 on a draft that holds no figure in this currency. The minBaseCurrencyAmount and maxBaseCurrencyAmount list filters run on this field, so a draft reading 0 here is excluded whenever either filter is applied.

Example: 7450
originalAmount
​number · required

How large this draft is, in the currency it was entered in — the currency originalCurrency names, and the one lines[].amount uses. A draft entered as EUR 1,000 is 1000 here, whatever your company reports in.

This is the figure to display beside originalCurrency. baseCurrencyAmount is the same draft in your company base currency: on that EUR draft this field reads 1000 and baseCurrencyAmount reads 7450. Reads 0 on a draft that carries no amount yet.

Example: 1000
originalCurrency
​string · required

The currency this draft was entered in — EUR for a supplier invoice received in EUR. originalAmount and lines[].amount are in this currency; baseCurrencyAmount is in your company base currency, which is this one only when the draft was entered in it.

Example: EUR
journalType
​string · required

Journal type

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

ID of the journal category the draft is in. Set it with journalCategoryId on the v2 draft create and on PATCH /v2/draft-journal-entries/{id}. Booking the draft keeps it on the journal entry. List the categories with GET /v1/journal-categories. Null when the draft has no category.

Example: 550e8400-e29b-41d4-a716-446655440004
​DraftJournalEntryLine[] · required

Every line of the draft. Always present, an empty array included, so a client never has to distinguish absent from empty. The name matches the lines the v2 draft endpoints take, so a draft reads back through the field it was written with.

status
​string · required

Always "DRAFT" for draft journal entries

Example: DRAFT
createdAt
​string · required

Creation timestamp

Example: 2026-01-15T10:30:00.000Z
updatedAt
​string · required

Last update timestamp

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

Document date (date on the invoice/voucher). Null when not set.

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

Due date stated on the draft (YYYY-MM-DD). Null when none was stated; booking a customer or supplier invoice then calculates one from the payment term.

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

What one unit of originalCurrency is worth in your company base currency. 7.45 on a EUR draft of a company reporting in DKK means 1 EUR buys 7.45 DKK.

This is the rate the draft is converted at, not a factor between the two amounts on this response. baseCurrencyAmount is built from the draft lines rather than from originalAmount, so multiplying originalAmount by this rate does not reliably reproduce it — on a draft whose sides disagree the two figures differ with no rate involved at all. A draft already entered in your own currency carries 1. Null only while a foreign-currency draft has no rate yet — booking gives it one.

Example: 7.45
originalCurrencyToBaseCurrencyExchangeRateDate
​string | null

Date the originalCurrencyToBaseCurrencyExchangeRate was captured for. Null whenever that rate is.

Example: 2026-01-15
description
​string

Description

Example: Office supplies purchase
reference
​string

Reference number

Example: REF-2026-001
externalSystemId
​string | null

Your own system's id for this draft, when set. Not unique. null when unset or cleared.

Example: erp-7f3a2c91
type
​string

Transaction type (debit or credit)

Example: debit
accountId
​string

Primary account ID

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

Contra account ID

Example: 550e8400-e29b-41d4-a716-446655440001
customerId
​string

Customer ID

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

Supplier ID

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

VAT/Tax code ID

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

Tag/Dimension IDs

documentRefs
​string[]

Document IDs attached to the draft

amount
​number · deprecated

Deprecated — use baseCurrencyAmount, which carries the same value. The draft in your company base currency. Do not display it beside currency: that names the currency the draft was entered in. The v1 create takes a request field of the same name carrying the figure the draft is entered in, so a EUR draft sent as amount: 1000 is returned with amount: 7450 — one name, two currencies.

Example: 7450
currency
​string · deprecated

Deprecated — use originalCurrency, which carries the same value. The currency the draft was entered in.

Example: EUR
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
​DraftSplitEntryLineResponse[] · deprecated

Deprecated — use lines. Present only on drafts that need it: a plain one-debit-one-credit draft with no per-line memo or dimensions reports its accounts through accountId / contraAccountId and omits this field entirely. It also reports a placeholder line's account as "", which the write side rejects. lines is populated either way and round-trips.

GET/v2/draft-journal-entries/{id}
curl https://api.ledgerbee.com/api/v2/draft-journal-entries/:id \ --header 'x-api-key: <api-key>'
Example Responses
{ "id": "550e8400-e29b-41d4-a716-446655440000", "date": "2026-01-15", "documentDate": "2026-01-15", "dueDate": "2026-02-14", "baseCurrencyAmount": 7450, "originalAmount": 1000, "originalCurrency": "EUR", "originalCurrencyToBaseCurrencyExchangeRate": 7.45, "originalCurrencyToBaseCurrencyExchangeRateDate": "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", "accountId": "550e8400-e29b-41d4-a716-446655440000", "contraAccountId": "550e8400-e29b-41d4-a716-446655440001", "customerId": "550e8400-e29b-41d4-a716-446655440002", "supplierId": "550e8400-e29b-41d4-a716-446655440003", "vatCodeId": "550e8400-e29b-41d4-a716-446655440000", "tagIds": [ "string" ], "documentRefs": [ "string" ], "lines": [ { "accountId": "550e8400-e29b-41d4-a716-446655440000", "type": "debit", "amount": 500, "vatCodeId": "550e8400-e29b-41d4-a716-446655440000", "description": "Consulting hours - March", "tagIds": [ "string" ] } ], "status": "DRAFT", "createdAt": "2026-01-15T10:30:00.000Z", "updatedAt": "2026-01-15T10:30:00.000Z", "amount": 7450, "currency": "EUR", "exchangeRate": 7.45, "exchangeRateDate": "2026-01-15", "vendorId": "550e8400-e29b-41d4-a716-446655440003", "splitEntries": [ { "accountId": "550e8400-e29b-41d4-a716-446655440000", "type": "debit", "amount": 500, "vatCodeId": "550e8400-e29b-41d4-a716-446655440000", "description": "Consulting hours — March", "tagIds": [ "string" ] } ] }
json
application/json

Delete a draft journal entry (v2)

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

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

Deletes a draft journal entry. Returns 404 if the draft id does not belong to the API key's app company.

The draft's documents are deleted with it: they go to the bin in LedgerBee, where they can be restored for 30 days. Send ?detachDocuments=true to return them to the inbox instead. A document another draft or a journal entry still uses is never deleted; it stays where it is.

When a bank payment still references the draft, the delete is refused with 409 DRAFT_LINKED_TO_BANK_PAYMENT (the linked payment ids are in the error details); re-send with ?detachBankPayments=true to confirm — the payments survive, only their draft link is cleared.

Required Scope

  • journal-entries-write

Delete a draft journal entry (v2) › path Parameters

id
​string · required

Draft journal entry ID (UUID)

Delete a draft journal entry (v2) › query Parameters

detachBankPayments
​boolean

Confirm detaching any bank payments still linked to this draft.

detachDocuments
​boolean

Return the draft's documents to the inbox instead of deleting them.

Delete a draft journal entry (v2) › Headers

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

Optional idempotency key for safely retrying mutating requests.

Delete a draft journal entry (v2) › Responses

Draft deleted successfully

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

Update a draft journal entry (v2)

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

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

Partial update: every create-time field is accepted except entryType (the journal type pins constraints decided at creation and is immutable) and attachments (own lifecycle). Omitted fields keep their current values; lines, when provided, replaces the full line set.

externalSystemId is carried onto the booked journal entry when the draft is booked, and is not unique: several drafts or entries may share one id. Filter GET /draft-journal-entries?externalSystemId=... to list carriers.

Reviewed (locked) drafts reject updates with 400 DRAFT_REVIEWED_LOCKED — unmark the review first. Concurrent updates are last-write-wins.

Required Scope

  • journal-entries-write

Update a draft journal entry (v2) › path Parameters

id
​string · required

Draft journal entry ID (UUID)

Update a draft journal entry (v2) › Headers

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

Optional idempotency key for safely retrying mutating requests.

Update a draft journal entry (v2) › Request Body

UpdateDraftJournalEntryV2Request
date
​string

Posting date (YYYY-MM-DD).

documentDate
​string | null

Document date (YYYY-MM-DD). null clears it, so the VAT period follows date again; omitting the field keeps it.

Example: 2026-03-28
dueDate
​string | null

Due date (YYYY-MM-DD) of a customer or supplier invoice draft. null clears it, so booking calculates one from the payment term again; omitting the field keeps it. The same rules as on create apply: refused on other entry types (JOURNAL_ENTRY_DUE_DATE_NOT_ALLOWED) and on a draft without a reference (JOURNAL_ENTRY_DUE_DATE_REQUIRES_REFERENCE).

Example: 2026-04-27
originalAmount
​number

Face value of the document — what the counterparty is invoiced or pays. NOT the sum of lines. On CUSTOMER_INVOICE / CUSTOMER_PAYMENT / SUPPLIER_INVOICE / SUPPLIER_PAYMENT this value IS the appended AR/AP leg (its absolute value), so an account that appears on both sides of the entry — a clearing or pass-through account — must not be counted into it. Sign carries direction: positive = invoice / payment, negative = credit-note / refund.

customerId
​string | null · uuid

Customer reference. null clears it; omitting keeps it. Changing it reshapes the entry — requires lines and re-runs the per-entryType validation (CUSTOMER_* types cannot clear their counterparty).

supplierId
​string | null · uuid

Supplier reference. null clears it; omitting keeps it. Changing it reshapes the entry — requires lines and re-runs the per-entryType validation (SUPPLIER_* types cannot clear their counterparty).

description
​string · maxLength: 2000

Optional human-readable description.

reference
​string

Invoice number / external reference. On CUSTOMER_PAYMENT it names the invoice being paid, and the appended receivable leg follows where that invoice was booked: on the one account it sits on, which is the customer group account unless the invoice lines sent the receivable elsewhere (a deposit invoice). An invoice owed across several receivable accounts is cleared one leg per account when the payment pays everything it still has open; a part payment of such an invoice is refused with JOURNAL_ENTRY_RECEIVABLE_SPLIT_REQUIRED, because nothing here states which account it clears and it is never divided in proportion.

externalSystemId
​string | null · maxLength: 255

Your own system's id. null clears the value; omitting the field keeps it.

Example: erp-7f3a2c91
​SplitEntryLine[] · minItems: 1 · maxItems: 1000

Counter-side lines (revenue / expense / bank / outlay). For locked types do NOT include the AR/AP leg. The cap is per ENTRY, not per request or per journal category — nothing accumulates across entries, so a company with many unposted drafts is never refused for that reason.

tagIds
​string[]

Tag IDs applied at the entry level.

journalCategoryId
​string

Journal category ID (UUID). Must belong to the API key's app company; cross-tenant or unknown IDs are rejected with 400 JOURNAL_CATEGORY_NOT_FOUND. When omitted the entry uses the company's default category.

originalCurrency
​string | null · minLength: 3 · maxLength: 3 · pattern: ^[A-Za-z]{3}$

ISO 4217 alpha-3 code of the currency the draft is entered in. Omitting it under both names keeps the stored one.

Example: EUR
originalCurrencyToBaseCurrencyExchangeRate
​number

What one unit of originalCurrency is worth in your company base currency, e.g. 7.4612 for EUR to DKK. Must be greater than zero; a non-positive rate is rejected whatever the draft currency. Omit it and exchangeRate to have the rate resolved from the rate feed at the posting date. Not applied when the draft is already in your company base currency, where the conversion is the identity.

Example: 7.4612
vendorId
​string | null · uuid · deprecated

Deprecated — use supplierId. Legacy alias for the supplier reference (null clears it); sending both supplierId and vendorId with different values returns 400.

currency
​string | null · minLength: 3 · maxLength: 3 · deprecated · pattern: ^[A-Za-z]{3}$

Deprecated — use originalCurrency. The same currency code under its old name. Sending both with different codes returns 400 DRAFT_DEPRECATED_FIELD_CONFLICT.

Example: EUR
exchangeRate
​number · deprecated

Deprecated — use originalCurrencyToBaseCurrencyExchangeRate. The same rate under its old name. Sending both with different values returns 400 DRAFT_DEPRECATED_FIELD_CONFLICT.

Example: 7.4612

Update a draft journal entry (v2) › Responses

Draft updated

DraftJournalEntryResponse
id
​string · required

Draft journal entry ID

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

Date in YYYY-MM-DD format

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

How large this draft is, in your company base currency — the one your company reports in. A draft entered as EUR 1,000 by a company reporting in DKK is 7450 here.

Do not display this number beside originalCurrency. That field names the currency the draft was entered in (EUR in the example), while this number is in DKK. originalAmount is the figure that belongs beside originalCurrency.

Reads 0 on a draft that holds no figure in this currency. The minBaseCurrencyAmount and maxBaseCurrencyAmount list filters run on this field, so a draft reading 0 here is excluded whenever either filter is applied.

Example: 7450
originalAmount
​number · required

How large this draft is, in the currency it was entered in — the currency originalCurrency names, and the one lines[].amount uses. A draft entered as EUR 1,000 is 1000 here, whatever your company reports in.

This is the figure to display beside originalCurrency. baseCurrencyAmount is the same draft in your company base currency: on that EUR draft this field reads 1000 and baseCurrencyAmount reads 7450. Reads 0 on a draft that carries no amount yet.

Example: 1000
originalCurrency
​string · required

The currency this draft was entered in — EUR for a supplier invoice received in EUR. originalAmount and lines[].amount are in this currency; baseCurrencyAmount is in your company base currency, which is this one only when the draft was entered in it.

Example: EUR
journalType
​string · required

Journal type

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

ID of the journal category the draft is in. Set it with journalCategoryId on the v2 draft create and on PATCH /v2/draft-journal-entries/{id}. Booking the draft keeps it on the journal entry. List the categories with GET /v1/journal-categories. Null when the draft has no category.

Example: 550e8400-e29b-41d4-a716-446655440004
​DraftJournalEntryLine[] · required

Every line of the draft. Always present, an empty array included, so a client never has to distinguish absent from empty. The name matches the lines the v2 draft endpoints take, so a draft reads back through the field it was written with.

status
​string · required

Always "DRAFT" for draft journal entries

Example: DRAFT
createdAt
​string · required

Creation timestamp

Example: 2026-01-15T10:30:00.000Z
updatedAt
​string · required

Last update timestamp

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

Document date (date on the invoice/voucher). Null when not set.

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

Due date stated on the draft (YYYY-MM-DD). Null when none was stated; booking a customer or supplier invoice then calculates one from the payment term.

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

What one unit of originalCurrency is worth in your company base currency. 7.45 on a EUR draft of a company reporting in DKK means 1 EUR buys 7.45 DKK.

This is the rate the draft is converted at, not a factor between the two amounts on this response. baseCurrencyAmount is built from the draft lines rather than from originalAmount, so multiplying originalAmount by this rate does not reliably reproduce it — on a draft whose sides disagree the two figures differ with no rate involved at all. A draft already entered in your own currency carries 1. Null only while a foreign-currency draft has no rate yet — booking gives it one.

Example: 7.45
originalCurrencyToBaseCurrencyExchangeRateDate
​string | null

Date the originalCurrencyToBaseCurrencyExchangeRate was captured for. Null whenever that rate is.

Example: 2026-01-15
description
​string

Description

Example: Office supplies purchase
reference
​string

Reference number

Example: REF-2026-001
externalSystemId
​string | null

Your own system's id for this draft, when set. Not unique. null when unset or cleared.

Example: erp-7f3a2c91
type
​string

Transaction type (debit or credit)

Example: debit
accountId
​string

Primary account ID

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

Contra account ID

Example: 550e8400-e29b-41d4-a716-446655440001
customerId
​string

Customer ID

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

Supplier ID

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

VAT/Tax code ID

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

Tag/Dimension IDs

documentRefs
​string[]

Document IDs attached to the draft

amount
​number · deprecated

Deprecated — use baseCurrencyAmount, which carries the same value. The draft in your company base currency. Do not display it beside currency: that names the currency the draft was entered in. The v1 create takes a request field of the same name carrying the figure the draft is entered in, so a EUR draft sent as amount: 1000 is returned with amount: 7450 — one name, two currencies.

Example: 7450
currency
​string · deprecated

Deprecated — use originalCurrency, which carries the same value. The currency the draft was entered in.

Example: EUR
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
​DraftSplitEntryLineResponse[] · deprecated

Deprecated — use lines. Present only on drafts that need it: a plain one-debit-one-credit draft with no per-line memo or dimensions reports its accounts through accountId / contraAccountId and omits this field entirely. It also reports a placeholder line's account as "", which the write side rejects. lines is populated either way and round-trips.

PATCH/v2/draft-journal-entries/{id}
curl https://api.ledgerbee.com/api/v2/draft-journal-entries/:id \ --request PATCH \ --header 'Content-Type: application/json' \ --header 'x-api-key: <api-key>' \ --data '{ "date": "string", "documentDate": "2026-03-28", "dueDate": "2026-04-27", "originalAmount": 0, "customerId": "3f2b6f1e-8c4d-4e0b-9d5a-7a1c2e3f4b5d", "supplierId": "3f2b6f1e-8c4d-4e0b-9d5a-7a1c2e3f4b5d", "vendorId": "3f2b6f1e-8c4d-4e0b-9d5a-7a1c2e3f4b5d", "description": "string", "reference": "string", "externalSystemId": "erp-7f3a2c91", "lines": [ { "accountId": "550e8400-e29b-41d4-a716-446655440000", "type": "debit", "amount": 500, "vatCodeId": "550e8400-e29b-41d4-a716-446655440000", "description": "Consulting hours — March", "tagIds": [ "550e8400-e29b-41d4-a716-446655440003" ] } ], "tagIds": [ "string" ], "journalCategoryId": "string", "originalCurrency": "EUR", "currency": "EUR", "originalCurrencyToBaseCurrencyExchangeRate": 7.4612, "exchangeRate": 7.4612 }'
Example Request Body
{ "date": "string", "documentDate": "2026-03-28", "dueDate": "2026-04-27", "originalAmount": 0, "customerId": "3f2b6f1e-8c4d-4e0b-9d5a-7a1c2e3f4b5d", "supplierId": "3f2b6f1e-8c4d-4e0b-9d5a-7a1c2e3f4b5d", "vendorId": "3f2b6f1e-8c4d-4e0b-9d5a-7a1c2e3f4b5d", "description": "string", "reference": "string", "externalSystemId": "erp-7f3a2c91", "lines": [ { "accountId": "550e8400-e29b-41d4-a716-446655440000", "type": "debit", "amount": 500, "vatCodeId": "550e8400-e29b-41d4-a716-446655440000", "description": "Consulting hours — March", "tagIds": [ "550e8400-e29b-41d4-a716-446655440003" ] } ], "tagIds": [ "string" ], "journalCategoryId": "string", "originalCurrency": "EUR", "currency": "EUR", "originalCurrencyToBaseCurrencyExchangeRate": 7.4612, "exchangeRate": 7.4612 }
json
application/json
Example Responses
{ "id": "550e8400-e29b-41d4-a716-446655440000", "date": "2026-01-15", "documentDate": "2026-01-15", "dueDate": "2026-02-14", "baseCurrencyAmount": 7450, "originalAmount": 1000, "originalCurrency": "EUR", "originalCurrencyToBaseCurrencyExchangeRate": 7.45, "originalCurrencyToBaseCurrencyExchangeRateDate": "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", "accountId": "550e8400-e29b-41d4-a716-446655440000", "contraAccountId": "550e8400-e29b-41d4-a716-446655440001", "customerId": "550e8400-e29b-41d4-a716-446655440002", "supplierId": "550e8400-e29b-41d4-a716-446655440003", "vatCodeId": "550e8400-e29b-41d4-a716-446655440000", "tagIds": [ "string" ], "documentRefs": [ "string" ], "lines": [ { "accountId": "550e8400-e29b-41d4-a716-446655440000", "type": "debit", "amount": 500, "vatCodeId": "550e8400-e29b-41d4-a716-446655440000", "description": "Consulting hours - March", "tagIds": [ "string" ] } ], "status": "DRAFT", "createdAt": "2026-01-15T10:30:00.000Z", "updatedAt": "2026-01-15T10:30:00.000Z", "amount": 7450, "currency": "EUR", "exchangeRate": 7.45, "exchangeRateDate": "2026-01-15", "vendorId": "550e8400-e29b-41d4-a716-446655440003", "splitEntries": [ { "accountId": "550e8400-e29b-41d4-a716-446655440000", "type": "debit", "amount": 500, "vatCodeId": "550e8400-e29b-41d4-a716-446655440000", "description": "Consulting hours — March", "tagIds": [ "string" ] } ] }
json
application/json

Get attachments for a draft journal entry (v2)

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

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

Retrieves the documents attached to a draft journal entry, with their content base64-encoded. Each is also listed by id in the draft's documentRefs; a document whose file cannot be read is left out of this list.

Required Scope

  • journal-entries-read

Get attachments for a draft journal entry (v2) › path Parameters

id
​string · required

Draft journal entry ID (UUID)

Get attachments for a draft journal entry (v2) › Responses

Attachments retrieved

DraftJournalEntryAttachmentsListResponse
draftJournalEntryId
​string · required

Draft journal entry ID the attachments belong to

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

List of attachments

GET/v2/draft-journal-entries/{id}/attachments
curl https://api.ledgerbee.com/api/v2/draft-journal-entries/:id/attachments \ --header 'x-api-key: <api-key>'
Example Responses
{ "draftJournalEntryId": "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 draft journal entry (v2)

POST
https://api.ledgerbee.com/api
/v2/draft-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 an existing draft. When the draft is booked, its documents move onto the journal entry.

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.

Reviewed (locked) drafts reject the upload with 400 DRAFT_REVIEWED_LOCKED; the review has to be undone in LedgerBee first. A draft frozen by a pending or granted approval rejects it with 400 DRAFT_EDIT_BLOCKED_BY_APPROVAL.

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

Required Scope

  • journal-entries-write

Add a document to a draft journal entry (v2) › path Parameters

id
​string · required

Draft journal entry ID (UUID)

Add a document to a draft journal entry (v2) › Headers

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

Optional idempotency key for safely retrying mutating requests.

Add a document to a draft journal entry (v2) › Request Body

file
​string · required

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

Add a document to a draft journal entry (v2) › Responses

Document attached

DraftJournalEntryAttachmentAddedResponse
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
draftJournalEntryId
​string · required

Draft journal entry ID the attachment was added to

Example: 550e8400-e29b-41d4-a716-446655440000
POST/v2/draft-journal-entries/{id}/attachments
curl https://api.ledgerbee.com/api/v2/draft-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", "draftJournalEntryId": "550e8400-e29b-41d4-a716-446655440000" }
json
application/json

Remove a document from a draft journal entry (v2)

DELETE
https://api.ledgerbee.com/api
/v2/draft-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 draft, leaving its other documents in place, and deletes it: it goes to the bin in LedgerBee, where it can be restored for 30 days. Send ?detach=true to return it to the inbox instead. A document another draft or a journal entry still uses is never deleted; it stays where it is.

Reviewed (locked) drafts reject the removal with 400 DRAFT_REVIEWED_LOCKED, and a draft frozen by an approval with 400 DRAFT_EDIT_BLOCKED_BY_APPROVAL. Returns 404 DRAFT_DOCUMENT_NOT_ATTACHED when the document is not attached to the draft.

Required Scope

  • journal-entries-write

Remove a document from a draft journal entry (v2) › path Parameters

id
​string · required

Draft journal entry ID (UUID)

documentId
​string · required

Document ID (UUID), as listed in the draft's documentRefs

Remove a document from a draft journal entry (v2) › query Parameters

detach
​boolean

Return the document to the inbox instead of deleting it.

Remove a document from a draft journal entry (v2) › Headers

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

Optional idempotency key for safely retrying mutating requests.

Remove a document from a draft journal entry (v2) › Responses

Document removed from the draft

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

Book a draft journal entry (v2)

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

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

Converts a draft journal entry into a posted journal entry. Validates the posting period and balance, then permanently deletes the draft. V2 drafts already carry the auto-appended AR/AP leg, so booking is a clean handoff to the posted-JE pipeline — no duplicate anchor leg is created. Returns 404 if the draft id does not belong to the API key's app company.

Required Scope

  • journal-entries-write

Book a draft journal entry (v2) › path Parameters

id
​string · required

Draft journal entry ID (UUID)

Book a draft journal entry (v2) › Headers

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

Optional idempotency key for safely retrying mutating requests.

Book a draft journal entry (v2) › Responses

Draft booked successfully — returns the created journal entry

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
POST/v2/draft-journal-entries/{id}/book
curl https://api.ledgerbee.com/api/v2/draft-journal-entries/:id/book \ --request POST \ --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

Draft Journal EntriesEntitlements