Balance
Queries the bank account balance associated with the API Key.
Endpoint
GET /api/external/balanceHeaders
| Header | Type | Required | Description |
|---|---|---|---|
Authorization | String | Yes | ApiKey {client_id}:{client_secret} |
X-Key-Case | String | No | Set to camelCase to receive response fields in camelCase (default is snake_case) |
Example
curl -X GET https://api.owem.com.br/api/external/balance \
-H "Authorization: ApiKey $CLIENT_ID:$CLIENT_SECRET"Success Response (200)
{
"worked": true,
"balance": 3000000,
"available": 2700000,
"pending": 300000,
"currency": "BRL"
}| Field | Type | Description |
|---|---|---|
worked | Boolean | true indicates operation success |
balance | Integer | Safe balance in base units (÷ 10,000 for BRL). 3000000 = R$ 300.00 |
available | Integer | Available balance for operations in base units. 2700000 = R$ 270.00 |
pending | Integer | Amount held in pending transactions in base units. 300000 = R$ 30.00 |
currency | String | Currency code (always BRL) |
Response values in base units
All response values are integers in base units. To convert to BRL, divide by 10,000. Example: 3000000 ÷ 10,000 = R$ 300.00. Never use floating point.
Balance calculation
| Field | Definition |
|---|---|
balance | Safe balance = min(tigerbeetle_balance, postgres_balance). If there is a TB↔PG divergence, the smaller value is used |
available | balance - pending — balance effectively available for new operations |
pending | Sum of pending debits in TigerBeetle (account.debits_pending) |
The balance field protects against inflated balance in scenarios of temporary divergence between TigerBeetle and PostgreSQL (e.g., MED block, post-deploy reconciliation). You will never see here a value higher than what is actually available in the ledger system — always the smaller of the two systems.
What composes pending (pending debits in TigerBeetle)
Each item below is a pending transfer in TigerBeetle that reduces available until it is posted or voided:
| Origin | When it appears | When it is released |
|---|---|---|
| PIX OUT in flight (TB pending from wallet → in-transit COSIF) | During sending, while awaiting BACEN confirmation (~1.6s typical) | Posted on pix.payout.confirmed (settled); voided on pix.payout.failed |
| MED preventive block (phantom hold, code 1032) | When an ACKNOWLEDGED infraction >R$1k is detected via ComplianceSyncWorker | Voided on analysis_result=DISAGREED (defense accepted); posted on AGREED (PACS.004 refund executed). See Infractions. |
| Quarantine (stage=5) | PIX OUT without BACEN response >30min — balance stays in limbo | Posted/voided only after manual decision by the Owem reserve team (may take hours or D+1). See pix-lifecycle. |
| Other internal holds | Rare — usually related to fees or specific adjustments | Depends on the type |
Situations where balance < raw TB balance
- TB↔PG divergence: in rare cases (e.g., post-deploy remediation window, session 142 TB-PG equalization incident),
balancereflects the smaller of the two systems until convergence. We never see an inflated balance; at most, it is underreported for a few minutes.
available may appear "stuck" even with growing PIX IN
If you see balance rising (inflows) but available not growing proportionally, an active MED block is very likely. Query GET /api/external/med to list the preventive blocks. Every block originates from an infraction — see Infractions for the complete flow.
Cache and consistency
The balance is computed in real time (typical latency <10ms) — there is no cache. However, in post-settlement windows (<200ms after the pix.charge.paid webhook), PostgreSQL may not yet be updated. For critical reconciliation, wait for the webhook before querying the balance.
Error Response (401)
{
"worked": false,
"errors": {
"unauthorized": "Missing API key credentials. Use Authorization: ApiKey <client_id>:<client_secret>"
}
}