Skip to main content
Read a client through three surfaces: its balance, its ledger, and its exports. Send X-Hevn-Account: cl_… with your own access token to act for one client. On a resource route like GET /banks the header is optional: omit it and the call acts on your integrator account instead. The singular /client* routes require it — the header is the only thing that names the account — and /clients and /escrow* refuse it.
The whole table — where the header is optional, where it is required and where it is refused — is in Sessions. The balance route is the strictest of the three: no client id appears in the path, so X-Hevn-Account is required rather than optional. Omit it and the call answers 422 validation_failed for a missing header — reading your own account means sending your own cl_….

Balance

Response — 200
Every number is a decimal string in the major unit — no atomic units, no floats. balance carries the token’s own precision, usdValue and totalUsd are rounded to cents. baseSmartWallet is the address funds live at and the address a crypto payer sends to; it is the only address on this surface. The read hits the chain, so it is the truth about spendable funds — and it is what POST /dapi/v1/payouts checks before it lets you sign. A payout refused with insufficient_funds and a balance that looks sufficient means the difference is an in-flight debit, not a stale cache.

Walk the ledger

GET /dapi/v1/transactions is cursor-paged, newest first. Pass nextCursor back as cursor until it is gone. There is no offset and no total.
Response — 200
from is what left the source side and to what arrived at the destination; on a same-asset movement they are equal. isIncome is the direction, counterparty is the resolved name of the other party, and txHash is the on-chain leg where there is one. A cursor belongs to the query that produced it: change a filter and start again, or the call answers 400 invalid_cursor.

Filters

Every filter is a query parameter, camelCase, and the list-shaped ones take comma-separated values. Values are matched exactly, case included. A value outside the set answers 400 invalid_request with the offending one in details.reason, rather than returning a silently narrower page.

Totals for the same filters

GET /dapi/v1/transactions/summary takes the same filters and answers the aggregate, in USD, settled and pending kept apart:
Response — 200
It is its own route, so an aggregate is never folded into a page and never depends on which page you asked for.

One transaction

GET /dapi/v1/transactions/{transactionId} returns the same row plus description, explorerUrl, traceNumber and attachmentIds (doc_…). Use it when you have an id — from a payout’s transactionId, from a sandbox credit, or from a row you are reconciling.

Exports

GET /dapi/v1/transactions/export streams a file. The name arrives in Content-Disposition; there is no JSON body and no document to fetch afterwards.
download is the one method that writes bytes instead of parsing JSON — the reference client has it. Every ledger filter applies to an export as well, so a statement can be narrowed the same way a page can. A statement with no from/to covers the current month to now. Asking for a combination the table does not list — a receipt as xlsx, a statement without bankId — answers 422 validation_failed naming the parameter at fault.

Reconciling

The ledger is the durable record of everything the other pages produce: a confirmed payout, a transfer, a settled payin, a sandbox credit. Reconcile with a watermark rather than a re-read:
  1. Keep the newest createdAt you have processed, per client.
  2. Ask for from=<watermark> and walk the cursor to the end.
  3. Match your own records on id, and a payout on the transactionId its read returns — txHash identifies the on-chain leg, not the payment.
  4. Move the watermark only after the whole walk succeeded. Ids are stable, so replaying an overlap costs a comparison, and skipping a row costs a missing payment.
Rows appear when the partner reports or the chain confirms, not when you call. A pending row is not an error; a row that never appears is, and its payin or payout id is where to look.

Next: Escrow

Lock one client’s funds in an on-chain contract while another delivers: the marketplace order, end to end.