Account Statement

Read all balances and a paginated list of operations for a user over a window.

POST /api/account/statement

Returns the API key user's current balances on every supported network plus a paginated feed of operations (deposits, withdrawals, payouts, transfers) within a date range.

GET /api/account/statement is also accepted, with the same parameters sent as query string (?from=...&to=...&limit=50&type=payout&type=transfer).

All amounts are in the asset's native units (e.g. USDC, not cents). BRL is the only currency expressed as integer cents on receipt and decimal string here.

Request

curl --request POST \
  --url https://api.hodle.com.br/api/account/statement \
  --header "Authorization: Bearer $API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "from": "2026-04-01T00:00:00Z",
    "to":   "2026-05-01T00:00:00Z",
    "limit": 50
  }'
const res = await fetch('https://api.hodle.com.br/api/account/statement', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.HODLE_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    from: '2026-04-01T00:00:00Z',
    to: '2026-05-01T00:00:00Z',
    limit: 50,
  }),
})
const data = await res.json()
import os, requests

res = requests.post(
    "https://api.hodle.com.br/api/account/statement",
    headers={
        "Authorization": f"Bearer {os.environ['HODLE_API_KEY']}",
        "Content-Type": "application/json",
    },
    json={
        "from": "2026-04-01T00:00:00Z",
        "to":   "2026-05-01T00:00:00Z",
        "limit": 50,
    },
)
data = res.json()

Parameters

FieldTypeRequiredDescription
fromstringNoISO start of window (inclusive). Defaults to 30 days ago. Max window 90 days.
tostringNoISO end of window (exclusive). Defaults to now.
limitintegerNo1–200. Default 50.
cursorstringNoContinuation token from a previous response's nextCursor.
typestringNoFilter: deposit, withdraw, payout, transfer. Repeat to combine.

Response

200 OK
{
  "success": true,
  "data": {
    "balances": [
      { "network": "polygon", "asset": "USDT", "amount": "182.45" },
      { "network": "base",    "asset": "USDC", "amount": "0.00"   },
      { "network": "tron",    "asset": "USDT", "amount": "0.00"   },
      { "network": "solana",  "asset": "USDC", "amount": "12.34"  }
    ],
    "rails": { "onRamp": "configured-on-ramp", "offRamp": "configured-off-ramp" },
    "operations": [
      {
        "id": "op_8f3a...",
        "type": "payout",
        "status": "COMPLETED",
        "amount": "5.00",
        "asset": "USDT",
        "network": "polygon",
        "valueInBrl": "27.40",
        "fee": "1.55",
        "txHash": "0xeafe9c...",
        "endToEndId": "E12345...",
        "reference": null,
        "provider": "avenia",
        "direction": "out",
        "createdAt": "2026-04-28T23:32:10.000Z",
        "completedAt": "2026-04-28T23:33:42.000Z"
      },
      {
        "id": "op_b21f...",
        "type": "deposit",
        "status": "COMPLETED",
        "amount": "100.00",
        "asset": "USDC",
        "network": "base",
        "valueInBrl": "545.00",
        "fee": "0.00",
        "txHash": "0xa1b2...",
        "provider": "configured-provider",
        "direction": "in",
        "createdAt": "2026-04-26T14:11:02.000Z",
        "completedAt": "2026-04-26T14:13:55.000Z"
      }
    ],
    "nextCursor": "c2Vla180MjkyMjEz",
    "total": 137
  }
}
FieldTypeDescription
data.balancesarraySame shape as POST /api/wallet/get.
data.railsobjectRail serving each side of your fiat flow: onRamp and offRamp.
data.operationsarrayOne row per operation, sorted by createdAt desc.
data.nextCursorstring?If present, pass back as cursor to fetch the next page.
data.totalintegerTotal count for the window — useful for pagination UIs.

Rails

Every operation carries the rail that executed it, so a statement can be reconciled provider by provider.

FieldTypeDescription
operation.providerstring?Provider identifier for the fiat rail, or null for on-chain sends that never touch a fiat rail.
operation.directionstringin for money entering the account, out for money leaving it.
data.rails.onRampstringIdentifier of the rail used for PIX in.
data.rails.offRampstringIdentifier of the rail used for PIX out.

operation.provider reflects what actually ran: the rail recorded on the operation always wins, and data.rails is the fallback for older rows that predate rail recording.

Operation types

TypeSource endpointDirection
deposit/api/deposit/assetIn
withdrawLegacy Liquid off-ramp (no longer offered)Out
payout/api/wallet/payoutOut
transfer/api/wallet/transferOut
lightning/api/lightning/invoice (paid)In

Errors

400 — window too wide
{ "success": false, "error": "Window must be at most 90 days" }
400 — invalid cursor
{ "success": false, "error": "Invalid or expired cursor" }