# Saldo

Consulta el saldo de la cuenta bancaria asociada a la API Key.

## Endpoint

```
GET /api/external/balance
```

## Headers

| Header | Tipo | Obligatorio | Descripcion |
|--------|------|-------------|-------------|
| `Authorization` | String | Si | `ApiKey {client_id}:{client_secret}` |
| `X-Key-Case` | String | No | Defina como `camelCase` para recibir los campos de la respuesta en camelCase (default es snake_case) |

## Ejemplo

```bash
curl -X GET https://api.monetarie.com/api/external/balance \
  -H "Authorization: ApiKey $CLIENT_ID:$CLIENT_SECRET"
```

## Respuesta de Exito (200)

```json
{
  "worked": true,
  "balance": 3000000,
  "available": 2700000,
  "pending": 300000,
  "currency": "BRL"
}
```

| Campo | Tipo | Descripcion |
|-------|------|-------------|
| `worked` | Boolean | `true` indica exito en la operacion |
| `balance` | Integer | Saldo seguro en **unidades base** (÷ 10.000 para reales). `3000000` = R$ 300,00 |
| `available` | Integer | Saldo disponible para operaciones en unidades base. `2700000` = R$ 270,00 |
| `pending` | Integer | Valor retenido en transacciones pendientes en unidades base. `300000` = R$ 30,00 |
| `currency` | String | Codigo de la moneda (siempre `BRL`) |

::: danger Valores de respuesta en unidades base
Todos los valores de respuesta son enteros en **unidades base**. Para convertir a reales, divida por 10.000.
Ejemplo: `3000000` ÷ 10.000 = **R$ 300,00**. Nunca use punto flotante.
:::

## Calculo del saldo

| Campo | Definicion |
|---|---|
| `balance` | **Saldo seguro** = `min(saldo_tigerbeetle, saldo_postgres)`. Si hay divergencia TB↔PG, el menor valor es usado |
| `available` | `balance - pending` - saldo efectivamente disponible para nuevas operaciones |
| `pending` | Suma de los **debitos pendientes** en el TigerBeetle (`account.debits_pending`) |

El campo `balance` protege contra saldo inflado en escenarios de divergencia temporal entre TigerBeetle y PostgreSQL (ej: bloqueo MED, reconciliacion pos-deploy). Usted **nunca** vera aqui un valor mayor al realmente disponible en el sistema de ledger - siempre el menor de los dos sistemas.

### Lo que compone `pending` (debitos pendientes en el TigerBeetle)

Cada item abajo es un **pending transfer** en el TigerBeetle que reduce el `available` hasta ser posted o voided:

| Origen | Cuando aparece | Cuando es liberado |
|---|---|---|
| **PIX OUT en vuelo** (pending TB de la wallet → COSIF in-transit) | Durante el envio, mientras aguarda confirmacion BACEN (~1,6s tipico) | Posted al recibir `pix.payout.confirmed` (settled); voided al recibir `pix.payout.failed` |
| **Valor en disputa MED** | Cuando un caso MED exige una reserva temporal del valor disputado | Liberado o liquidado segun la decision final. Acompanhe `pix.infraction.resolved` y vea [Infracciones](/es/infractions). |
| **Cuarentena (stage=5)** | PIX OUT sin respuesta BACEN >30min - saldo queda en limbo | Posted/voided solo despues de decision manual de la reserva Monetarie (puede tardar horas o D+1). Ver [pix-lifecycle](/es/pix-lifecycle#cuarentena-operaciones-sin-respuesta-bacen). |
| **Otros holds internos** | Raros - normalmente ligados a fees o ajustes especificos | Depende del tipo |

::: info Situaciones donde `balance < saldo bruto TB`
- **Divergencia TB↔PG**: en casos raros (ej: ventana de remediacion pos-deploy, incidente session 142 TB-PG equalization), `balance` refleja el **menor** entre los dos sistemas hasta la convergencia. Nunca vemos saldo inflado; a lo maximo, subdimensionado por algunos minutos.
:::

::: warning `available` puede quedar "parado" incluso con PIX IN creciente
Si usted ve `balance` subiendo (recibimientos) pero `available` no crece en la misma proporcion, **muy probablemente hay bloqueo MED activo**. Consulte [`GET /api/external/med`](/es/med-list) para listar los bloqueos cautelares. Todo bloqueo tiene origen en una infraccion - vea [Infracciones](/es/infractions) para el flujo completo.
:::

::: warning Cache y consistencia
El saldo es calculado en tiempo real (latencia tipica <10ms) - no hay cache. Sin embargo, en ventanas pos-liquidacion (<200ms despues del webhook `pix.charge.paid`), el PostgreSQL puede aun no haber sido actualizado. Para conciliacion critica, aguarde el webhook antes de consultar el saldo.
:::

## Respuesta de Error (401)

```json
{
  "worked": false,
  "errors": {
    "unauthorized": "Missing API key credentials. Use Authorization: ApiKey <client_id>:<client_secret>"
  }
}
```
