Read a trial balance
const url = 'https://api.aerandil.com/v1/analytics/trial-balance?property_id=2489E9AD-2EE2-8E00-8EC9-32D5F69181C0&business_date=2026-04-15';const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request GET \ --url 'https://api.aerandil.com/v1/analytics/trial-balance?property_id=2489E9AD-2EE2-8E00-8EC9-32D5F69181C0&business_date=2026-04-15' \ --header 'Authorization: Bearer <token>'The night audit’s trial balance for one property and one business date, folded from the ledgers’ entries (folio.balance_moved.recorded, and ledger.balance_moved.recorded for the ledgers no folio holds): the guest, deposit, A/R, package and inter-hotel ledgers with their opening, the day’s debits and credits, and their closing; the day’s revenue by USALI department, tax, gratuities, payments by method, internal transfers and drift corrections; and the proof — the folio ledgers’ (guest, deposit, A/R) closing (ledger_total) against the folios’ own stored balances at that close (stored_total: read live, brought back to the day’s close by the entries dated after it), in_balance when difference is zero.
Dated by posting. An entry belongs to the hotel date it was posted on — the business date the property had open, so a posting after midnight and before the close lands on the day still open (the night audit’s room nights to the day it closes) — and a closed day’s figures never move; a correction lands on the day it is made.
Deterministic. Everything but projection and the totals’ stored_total / difference / in_balance is a pure function of the event log: the same date reads byte-identically after any re-fold. Those three compare the fold with the folios as they stand at read time, so the rollup never stores them. projection reports the fold’s freshness (lag_events > 0 means entries are still to be folded, and shows as a difference).
Live data: always Cache-Control: no-store.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Query Parameters
Section titled “Query Parameters”Property whose ledgers to read.
The business date, YYYY-MM-DD.
Responses
Section titled “Responses”The trial balance. A property or day with no entries is an empty statement, not a 404.
object
Guest, deposit, ar, package, inter_hotel — in that order, per currency. The package ledger is allowance set aside from the room rate and not yet consumed or cleared (a credit balance); the inter-hotel ledger is what the group’s other houses owe this one.
object
The day’s movements by section (revenue, tax, non_revenue, payment, transfer, opening, adjustment) and line; net = debits − credits from the folios’ side.
object
The payouts in the close (2026-10-18): the day’s card payments (received in the house’s calendar day, settled or since refunded) with the day their money became available to pay out — pending until the payout carrying it has reconciled — and the payouts that arrived (arrival_date) or failed that day, with their reconciliation counts. A fold over the ledger’s rows, byte-identical on re-read.
object
object
object
YYYY-MM-DD, or pending.
object
Freshness of the fold — not part of the statement.
object
object
Stored_total − ledger_total: drift between the folios’ cached balances and their entries (or entries not yet folded — see projection.lag_events).
Difference is zero (and brought forward plus the day’s transactions equals the ledgers’ closing).
The folio ledgers’ (guest, deposit, ar) closing — what the folios should hold at this day’s close.
The folios’ stored balances, read live and brought back to this day’s close by the folio-ledger entries dated after it.
Example
{ "ledgers": [ { "ledger": "guest" } ]}Headers
Section titled “Headers”Always no-store — live data.
Token lacks the analytics:read scope.
Structured error wrapper. Every non-2xx response from any Aerandil endpoint serialises to this shape; the HTTP status carries the failure class (4xx/5xx), the body adds a stable code for programmatic dispatch plus a human-readable message.
object
object
Stable, programmatic error code (e.g. unauthorized, forbidden, not_found, invalid_body, invalid_url, precondition_failed, no_secondary_key). Clients dispatch on code, not on the message (which may be localised or contextualised in future versions).
Request-id correlation handle echoed on the request-id response header — support teams correlate without scraping logs.
Human-readable explanation of the failure.
Per-error structured detail. The shape varies by code (e.g. forbidden_action carries {"action": "..."}; precondition_failed carries {"current_version": N}).
Examplegenerated
{ "error": { "code": "example", "instance_id": "example", "message": "example", "parameters": "example" }}Malformed business_date.
Structured error wrapper. Every non-2xx response from any Aerandil endpoint serialises to this shape; the HTTP status carries the failure class (4xx/5xx), the body adds a stable code for programmatic dispatch plus a human-readable message.
object
object
Stable, programmatic error code (e.g. unauthorized, forbidden, not_found, invalid_body, invalid_url, precondition_failed, no_secondary_key). Clients dispatch on code, not on the message (which may be localised or contextualised in future versions).
Request-id correlation handle echoed on the request-id response header — support teams correlate without scraping logs.
Human-readable explanation of the failure.
Per-error structured detail. The shape varies by code (e.g. forbidden_action carries {"action": "..."}; precondition_failed carries {"current_version": N}).
Examplegenerated
{ "error": { "code": "example", "instance_id": "example", "message": "example", "parameters": "example" }}The trial_balance projection has not completed a healthy tick (projection_unavailable); retry after Retry-After.
Structured error wrapper. Every non-2xx response from any Aerandil endpoint serialises to this shape; the HTTP status carries the failure class (4xx/5xx), the body adds a stable code for programmatic dispatch plus a human-readable message.
object
object
Stable, programmatic error code (e.g. unauthorized, forbidden, not_found, invalid_body, invalid_url, precondition_failed, no_secondary_key). Clients dispatch on code, not on the message (which may be localised or contextualised in future versions).
Request-id correlation handle echoed on the request-id response header — support teams correlate without scraping logs.
Human-readable explanation of the failure.
Per-error structured detail. The shape varies by code (e.g. forbidden_action carries {"action": "..."}; precondition_failed carries {"current_version": N}).
Examplegenerated
{ "error": { "code": "example", "instance_id": "example", "message": "example", "parameters": "example" }}