List balance ledger entries
https://api.triport.io/v1/balance/entries?limit=50Returns a cursor-paginated, newest-first slice of your account's balance ledger (every credit and debit).
GET /v1/balance/entries reads your account's balance journal — the
append-only ledger of every change to your balance. Each row records a single
credit or debit, its source, and when it was applied. Use it to render an
account-activity / billing-history view, to reconcile invoices against
payments, or to audit adjustments and refunds.
Entries are returned newest-first and are cursor-paginated on the id of
the last (oldest) entry in the current page. A balance entry is immutable once
written, so a cursor walk is stable: re-fetching the same after_id always
yields the same following rows.
All amounts are expressed in micro-USD (1 USD = 1_000_000 micro). A
positive delta_micro is a credit to your balance; a negative value is a debit.
The server is authoritative for these values — do not derive a running balance
on the client by summing deltas; read the snapshot from
GET /v1/balance or the balance event stream instead.
This endpoint requires an authenticated Console session (sent as a cookie). A
brand-new account with no activity returns an empty entries array with HTTP
200, not a 404.
Parameters
All parameters are optional query-string values.
limitintegeroptionalafter_idintegeroptionalnext_cursor.Response
Response fields
| Field | Type | Description |
|---|---|---|
entries | array | The page of ledger entries, newest-first. Empty array when the account has no (further) activity. |
entries[].id | integer | Monotonic ledger entry id. Use the id of the last entry as the next page's after_id. |
entries[].delta_micro | integer | Signed balance change in micro-USD. Positive = credit, negative = debit. |
entries[].kind | string | What produced the row: payment_credit, invoice_debit, refund, or adjust. |
entries[].ref_invoice_id | string | null | The invoice this entry relates to, if any (e.g. for invoice_debit). Absent/null otherwise. |
entries[].ref_payment_id | integer | null | The payment this entry relates to, if any (e.g. for payment_credit). Absent/null otherwise. |
entries[].reason | string | Human-readable note describing the entry. May be empty. |
entries[].created_at | integer | When the entry was written, in Unix seconds. Multiply by 1000 for a JavaScript Date. |
next_cursor | integer | null | The id of the last (oldest) entry in this page, to be passed as the next request's after_id. Absent/null only when entries is empty. |
Errors
Errors use the shared envelope { "error": "<message>" } — see
errors.md for the full contract.
| Code | Meaning | When it happens |
|---|---|---|
401 | auth required | No valid Console session cookie was presented. |
500 | internal: <detail> | Unexpected server-side failure while reading the ledger. |
503 | session resolver not configured | Authentication is temporarily unavailable on this node; retry shortly. |
Examples
JavaScript (fetch)
async function listBalanceEntries({ limit, afterId } = {}) {
const q = new URLSearchParams();
if (limit != null) q.set('limit', String(limit));
if (afterId != null) q.set('after_id', String(afterId));
const qs = q.toString();
const res = await fetch(
`https://api.triport.io/v1/balance/entries${qs ? `?${qs}` : ''}`,
{ credentials: 'include', headers: { 'Content-Type': 'application/json' } },
);
if (!res.ok) throw new Error((await res.json().catch(() => ({}))).error ?? `HTTP ${res.status}`);
return res.json(); // { entries, next_cursor }
}
// Walk the whole journal, newest-first.
async function* allEntries() {
let afterId;
for (;;) {
const { entries, next_cursor } = await listBalanceEntries({ limit: 100, afterId });
if (entries.length === 0) return;
yield* entries;
if (next_cursor == null) return;
afterId = next_cursor;
}
}TypeScript SDK (@triport/sdk)
import { Triport } from '@triport/sdk';
const triport = new Triport({ session: process.env.TRIPORT_SESSION! });
const page = await triport.balance.listEntries({ limit: 50 });
for (const e of page.entries) {
const sign = e.delta_micro >= 0 ? '+' : '-';
console.log(`#${e.id} ${e.kind} ${sign}${Math.abs(e.delta_micro) / 1_000_000} USD`);
}
if (page.next_cursor != null) {
const next = await triport.balance.listEntries({ limit: 50, after_id: page.next_cursor });
// ...
}Python (triport-sdk)
import os
from triport import Triport
triport = Triport(session=os.environ["TRIPORT_SESSION"])
after_id = None
while True:
page = triport.balance.list_entries(limit=100, after_id=after_id)
for e in page["entries"]:
usd = e["delta_micro"] / 1_000_000
print(f'#{e["id"]} {e["kind"]} {usd:+.6f} USD')
if not page["entries"] or page.get("next_cursor") is None:
break
after_id = page["next_cursor"]Notes
- Pagination terminates on an empty page.
next_cursoris the id of the last entry returned and is present on every non-empty page — including the final one. Don't treat "next_cursoris set" as "more data exists." Instead, keep passingafter_id=next_cursoruntil a request returnsentries: [](at which pointnext_cursoris absent/null). - No
kindfilter. This endpoint does not filter by entry kind; filtering bypayment_credit/invoice_debit/refund/adjustis done client-side. - Timestamps are Unix seconds, not milliseconds — multiply by
1000before constructing a JSDate. - Related:
GET /v1/balancefor the current balance snapshot, and the balance event stream for live credit/debit pushes.