Entries
An entry is one account's share of a transaction: a debit or a credit, never both, never negative.
Read-only. There is no POST. Entries are created only as part of a
transaction, because an entry writable on its own could leave a transaction
unbalanced — and the single write path exists precisely so that cannot happen.
See transactions.
When to use this instead of transactions
/api/v1/transactions answers what happened. This answers what landed on
this account, in this period, under this cost centre.
For a question like "every entry against Rent Expense in Q1", going through the transactions endpoint means fetching whole transactions to look at one line of each and filtering client-side — most of the ledger over the wire to answer a question about a fraction of it.
GET /api/v1/entries
| Param | Notes |
|---|---|
account | Account id |
account_subtree | A group id — every postable account beneath it |
account_type | asset, liability, equity, income or expense |
date_from, date_to | Inclusive, on the parent's accounting date |
status | Parent status. Defaults to posted; all opts out |
type | Parent transaction type |
transaction | Entries of one transaction |
dimension.<key> | e.g. dimension.cost_centre=Mumbai |
has_dimension | false finds unallocated entries, true allocated ones |
page, limit | Default 100 per page, max 500 |
has_dimension cannot be combined with a dimension.<key> filter — the key
filter already implies the entry has that dimension, so the combination is
either redundant or impossible.
The posted default matters. An entry on a draft is not part of the books.
Including one silently would put a figure into an analysis that no report would
agree with.
account_subtree and account_type are how a report
figure is drilled into. A group's figure is the sum of its descendants and a
section total the sum of a type, so neither can be expressed as a single
account id — without them the most interesting figures in a statement would be
the only ones you could not trace back to entries.
Response
Each entry carries its parent's date, narration, type, status and source alongside its own amounts — an entry without them is a number with no context, and every caller would otherwise make the same follow-up request.
{
"data": [
{
"id": "e1f2g3h4i5j6",
"transaction": "t1u2v3w4x5y6",
"account": "a1b2c3d4e5f6",
"debit": 3000000,
"credit": 0,
"memo": null,
"dimensions": { "cost_centre": "Mumbai" },
"date": "2026-08-05",
"narration": "Rent paid — Aug 2026",
"transaction_type": "vendor_paid",
"transaction_status": "posted",
"source": "sap",
"source_ref": "4900001234"
}
],
"page_context": { "count": 1, "page": 1, "per_page": 100, "total": 1, "has_more": false }
}
Useful queries
An account ledger for a period
curl "…/api/v1/entries?account=a1b2c3d4e5f6&date_from=2026-04-01&date_to=2026-06-30&sort_order=ASC" \
-H "api-key: $KEY" -H "api-secret: $SECRET"
Everything under one cost centre
curl "…/api/v1/entries?dimension.cost_centre=Mumbai&date_from=2026-04-01&date_to=2027-03-31"
What is missing a cost centre — run this before trusting any dimension-filtered total, since unallocated entries are exactly what such a report leaves out:
curl "…/api/v1/entries?has_dimension=false&date_from=2026-04-01&date_to=2027-03-31"
Reading the amounts
Every entry has exactly one of debit or credit non-zero, both in minor units.
There are no negative amounts anywhere in the ledger.
To turn entries into a balance a person would recognise, subtract in the direction the account's type normally sits:
- debit-normal (asset, expense):
sum(debit) - sum(credit) - credit-normal (liability, equity, income):
sum(credit) - sum(debit)
The normal_balance field on
accounts tells you which applies, so this never
has to be guessed from the type.