> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cakto.com.br/llms.txt
> Use this file to discover all available pages before exploring further.

# Saldo

> Consulte quanto está disponível para saque agora e quanto ainda vai liberar. É a mesma informação do cartão de saldo do painel.

#### Escopo

```bash theme={null}
    read payments
```

## O que é este endpoint?

É a versão consultável por API do cartão de saldo do painel. Ele separa o dinheiro em **cinco parcelas disjuntas** — cada real aparece em no máximo uma delas, e há dinheiro a receber que não aparece em nenhuma (ver "As cinco parcelas não se sobrepõem", abaixo):

* **`available`** — o que dá para sacar **agora**;
* **`reserved`** — a reserva de segurança, retida até passar a janela de risco da venda;
* **`pending`** — o que ainda vai liberar e **ainda não** entrou na janela de antecipação;
* **`anticipatable`** — o que **já** entrou nessa janela e pode ser antecipado hoje pelo painel. **Não é um recorte de `pending`**: é um balde próprio, e os dois não se sobrepõem;
* **`refundBlocked`** — o **total** bloqueado por pedidos de reembolso em processamento.

E mais três campos que **detalham de onde veio** o `refundBlocked`, em vez de somar com as parcelas acima:

* **`heldByRefund`** — a fatia do bloqueio que já foi descontada de `available`;
* **`refundBlockedFromPending`** — a fatia que saiu de `pending`;
* **`refundBlockedFromReserved`** — a fatia que saiu de `reserved`.

> [!NOTE]
>
> A operação lê **sempre a conta dona do token**. Não existe parâmetro de produtor: não há como consultar o saldo de outra conta, e mandar um identificador na query não muda o resultado.

***

## `refundBlocked` e `heldByRefund` não são o mesmo número

Quando um comprador pede reembolso, a parte que é sua naquele pedido fica bloqueada até a análise terminar. O efeito depende de onde esse dinheiro estava quando o pedido entrou:

* se já tinha **liberado** e estava sacável, ele sai de `available`;
* se ainda **não tinha liberado**, ele sai de `pending` ou de `reserved`, conforme o caso.

`heldByRefund` conta **só o primeiro caso** — a fatia que o saque de fato recusa. `refundBlocked` conta **os dois**, e é o total que a Cakto está de fato segurando por esses pedidos. Por isso `refundBlocked` é sempre maior ou igual a `heldByRefund`.

> [!WARNING]
>
> **`refundBlocked` nem sempre é o valor das vendas em análise.** Numa venda **parcialmente antecipada que ainda não liberou**, a parte que você já recebeu por antecipação saiu da conta como saque, e o bloqueio é só o resto. Uma venda de R$ 50,00 com R$ 20,00 já antecipados entra em `refundBlocked` por \*\*R$ 30,00** enquanto não libera, embora o pedido de reembolso apareça em "Minhas vendas" sobre os R$ 50,00.
>
> **Depois que a venda libera** — e também na venda antecipada por inteiro —, o bloqueio é o **valor cheio** da venda: os mesmos R\$ 50,00 do exemplo, em `refundBlocked` e em `heldByRefund`. Conciliar linha a linha contra o valor das vendas só acha diferença nas vendas parcialmente antecipadas e ainda não liberadas — e ali ela está certa.

### De onde saiu cada fatia

`refundBlockedFromPending` e `refundBlockedFromReserved` dizem quanto do bloqueio saiu de cada um desses campos. **As três fatias não somam o total:**

```
heldByRefund + refundBlockedFromPending + refundBlockedFromReserved  ≤  refundBlocked
```

A diferença é real: é o dinheiro bloqueado que **não aparece em nenhum outro campo** da resposta — pendente já dentro da janela de antecipação, e venda parcialmente antecipada ainda não liberada. Ele está em `refundBlocked`, e em nenhum outro lugar.

***

## As cinco parcelas não se sobrepõem

Somar as cinco **não conta nada duas vezes**:

```
available + pending + reserved + anticipatable + refundBlocked
```

> [!WARNING]
>
> **Isso não é "o patrimônio da conta", e não monte um card de total com essa soma.** Uma venda parcialmente antecipada que **não** esteja sob pedido de reembolso deixa o resto a receber fora dos cinco campos — ele não entra em `pending`, nem em `anticipatable`, nem em `refundBlocked`. A garantia deste endpoint é de **não duplicar**, não de somar tudo o que você tem a receber. Para o que cai e quando, use [Agenda de Recebimentos](/api-reference/balance/schedule.md).

> [!WARNING]
>
> **`refundBlocked` pode vir `null`, e `null` não é zero.** Significa que não há número a publicar — a retenção não está ativa para a sua conta, ou a apuração falhou nesta chamada. Zero de verdade vem `"0.00"`. Um cliente que leia `null` como zero anuncia ao produtor que nada está bloqueado, o que pode ser falso.
>
> `refundBlockedFromPending` e `refundBlockedFromReserved` **acompanham** esse `null` — se não houve apuração, não há fatia a publicar. `heldByRefund` **não** acompanha: ele mantém o próprio valor, que é `"0.00"` com a retenção desligada e a fatia já descontada de `available` quando a apuração falhou.

> [!NOTE]
>
> **`pending` e `reserved` vêm descontados do que está retido.** Quando `refundBlocked` vem preenchido, a parte retida que estaria neles é `refundBlockedFromPending` e `refundBlockedFromReserved`, e conta só em `refundBlocked`. Com `refundBlocked: null` nada foi descontado deles.
>
> **Não use `refundBlocked - heldByRefund` no lugar das fatias.** Essa diferença mistura o que saiu de `pending`, o que saiu de `reserved` e o retido que não aparece em nenhum outro campo — ela não é a parcela de campo nenhum.
>
> Até 23/09/2026 a parte retida ainda aparecia dentro de `pending` e de `reserved`. Para reconstituir esses valores e conciliar com um histórico anterior, use as fórmulas do [Changelog](/mudancas.md).

***

## `available` pode ser negativo

Não é erro de cálculo. Retenção por pedido de reembolso, chargeback e MED descontam do disponível **sem piso**: se o dinheiro já tinha sido sacado quando a retenção entrou, o saldo fica negativo e representa **dívida real** com a plataforma. Saques são recusados enquanto isso, e vendas novas abatem o negativo antes de virar saldo.

Um cliente que trate saldo como "sempre ≥ 0" vai truncar esse número e mostrar zero ao produtor, escondendo exatamente a informação que ele precisa ver.

***

## Valores em string

Todo valor monetário sai como **string decimal** — `"1250.40"`, não `1250.4`. O motivo é o de sempre: `0.1 + 0.2` não é `0.3` em ponto flutuante, e dinheiro não tolera esse erro. Converta para o tipo decimal da sua linguagem (`Decimal` em Python, `BigDecimal` em Java), nunca para `float`.

***

## Exemplo

```python Python theme={null}
import requests
from decimal import Decimal

response = requests.get(
    "https://api.cakto.com.br/public_api/balance/",
    headers={"Authorization": "Bearer eyJhbGciOiJIUzI1NiIsIn..."},
    timeout=30,
)
response.raise_for_status()
saldo = response.json()

disponivel = Decimal(saldo["available"])
if disponivel < 0:
    print(f"Conta devedora: R$ {disponivel}")
else:
    print(f"Disponível para saque: R$ {disponivel}")
```

```javascript Node.js theme={null}
const response = await fetch("https://api.cakto.com.br/public_api/balance/", {
  headers: { Authorization: "Bearer eyJhbGciOiJIUzI1NiIsIn..." },
});

if (!response.ok) throw new Error(`Cakto API error ${response.status}`);

const saldo = await response.json();
// Sem biblioteca decimal, mantenha a string para exibir e só converta para comparar.
console.log(`Disponível: R$ ${saldo.available}`);
```

***

## Boas práticas

* **Não some `available` com `pending` para dizer "quanto eu tenho".** São dinheiros de momentos diferentes: um é sacável hoje, o outro é previsão. O que cai e quando está em [Agenda de Recebimentos](/api-reference/balance/schedule.md).
* **`heldByRefund`, `refundBlockedFromPending` e `refundBlockedFromReserved` não são parcelas novas.** Os três detalham `refundBlocked`; somá-los ao total conta o mesmo dinheiro duas vezes.
* **Para reconstituir o `available` de antes da retenção, some `heldByRefund`, não `refundBlocked`.** Só a fatia `heldByRefund` saiu de `available`; o resto de `refundBlocked` saiu de `pending` e de `reserved`, ou não aparece em nenhum outro campo.
* **Trate `null` como "não sei", nunca como zero.** `refundBlocked` e as duas fatias dele são as únicas respostas de valor deste endpoint que podem ser nulas, e vêm nulas juntas.
* **409 não significa "sem saldo".** Significa que o cadastro de recebimento não foi concluído no painel, e repetir a chamada não muda isso. Saldo zero responde `200` com `"0.00"`.
* **Consulte sob demanda, não em loop.** O saldo muda quando há venda, saque ou liberação — não a cada segundo.


## OpenAPI

````yaml GET /public_api/balance/
openapi: 3.0.3
info:
  title: Cakto API
  version: 1.0.0
  description: Documentação da API pública do Cakto.
servers:
  - url: https://api.cakto.com.br
    description: Cakto API
security: []
paths:
  /public_api/balance/:
    get:
      tags:
        - balance
      description: >-
        Saldo da conta autenticada.


        Devolve o que está disponível para saque agora e o que ainda vai
        liberar, na mesma

        composição que o painel exibe no cartão de saldo.


        A operação lê sempre a conta dona do token: não recebe identificador de
        produtor e não há

        como consultar o saldo de outra conta.


        `available` pode ser **negativo**: retenção por pedido de reembolso,
        chargeback e MED

        descontam do disponível sem piso, e o resultado é dívida real, não erro
        de cálculo.
      operationId: balance_retrieve
      parameters:
        - in: query
          name: currency
          schema:
            type: string
            enum:
              - BRL
              - USD
          description: Moeda dos valores. Default `BRL`.
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BalanceResponse'
              examples:
                Sucesso:
                  value:
                    currency: BRL
                    available: '1250.40'
                    pending: '3890.15'
                    reserved: '412.00'
                    anticipatable: '1100.00'
                    heldByRefund: '89.90'
                    refundBlocked: '289.90'
                    refundBlockedFromPending: '120.00'
                    refundBlockedFromReserved: '50.00'
          description: Saldo da conta autenticada, na moeda pedida.
        '400':
          content:
            application/json:
              schema:
                type: object
                properties:
                  detail:
                    type: string
              examples:
                MoedaNaoSuportada:
                  value:
                    detail: 'Moeda não suportada. Use uma de: BRL, USD.'
          description: Corpo da resposta status 400
        '401':
          description: Request não autenticado devido à ausência ou invalidez do token.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthenticatedError'
              examples:
                Token ausente ou inválido:
                  $ref: '#/components/examples/UnauthenticatedErrorExample'
        '403':
          content:
            application/json:
              schema:
                type: object
                properties:
                  detail:
                    type: string
              examples:
                EscopoInsuficiente:
                  value:
                    detail: Você não tem permissão para executar esta ação.
          description: Chave de API sem o escopo `payments`.
        '409':
          content:
            application/json:
              schema:
                type: object
                properties:
                  detail:
                    type: string
              examples:
                ContaSemRecebimento:
                  value:
                    detail: >-
                      Conta ainda não habilitada para recebimento. Conclua o
                      cadastro no painel da Cakto para que o saldo exista.
          description: >-
            A conta ainda não tem cadastro de recebimento concluído, então não
            há saldo a responder. Não vale repetir a chamada até que o cadastro
            seja concluído no painel — e este 409 nunca significa "sem saldo":
            saldo zero responde 200.
      security:
        - OAuth Token: []
components:
  schemas:
    BalanceResponse:
      type: object
      properties:
        currency:
          type: string
          description: Moeda dos valores desta resposta (`BRL` ou `USD`).
        available:
          type: string
          format: decimal
          example: '2.49'
          description: >-
            Disponível para saque agora, como string decimal. **Pode ser
            negativo**: retenção por pedido de reembolso, chargeback e MED
            descontam sem piso, e o saldo negativo é dívida real, não erro de
            cálculo.
        pending:
          type: string
          format: decimal
          example: '2.49'
          description: >-
            A liberar em datas futuras, fora a reserva de segurança e fora o que
            já entrou na janela de antecipação. O detalhe por dia está em `GET
            /public_api/balance/schedule/`. Quando `refundBlocked` vem
            preenchido, este campo já está **líquido do que está retido por
            pedido de reembolso**: a parcela retida que estaria aqui é
            `refundBlockedFromPending` e conta só em `refundBlocked`. Com
            `refundBlocked: null` nada foi descontado deste campo. Para
            reconstituir o valor anterior a 23/09/2026, ver o Changelog.
        reserved:
          type: string
          format: decimal
          example: '2.49'
          description: >-
            Reserva de segurança retida pela Cakto. Libera depois da janela de
            risco da venda e não é sacável enquanto isso. Quando `refundBlocked`
            vem preenchido, a reserva sob pedido de reembolso em análise já saiu
            daqui (`refundBlockedFromReserved`) e conta só em `refundBlocked`.
            Com `refundBlocked: null` nada foi descontado deste campo.
        anticipatable:
          type: string
          format: decimal
          example: '2.49'
          description: >-
            O que pode ser antecipado hoje pelo painel. **Não é um recorte de
            `pending`**: é um balde próprio e disjunto dele — `pending` só conta
            o que ainda NÃO entrou na janela de antecipação, e este campo só o
            que já entrou. Somar os dois não conta nada duas vezes. Antecipação
            não é operação da API pública.
        heldByRefund:
          type: string
          format: decimal
          example: '2.49'
          description: >-
            Retido por pedido de reembolso em análise **e já descontado de
            `available`** — a parcela do bloqueio que o saque de fato recusa.
            Quando `refundBlocked` vem preenchido, é um subconjunto dele, nunca
            maior. Vem `"0.00"` quando a retenção não está ativa para a sua
            conta; quando a apuração de `refundBlocked` falha, continua trazendo
            o valor descontado de `available`.
        refundBlocked:
          type: string
          format: decimal
          example: '2.49'
          nullable: true
          description: >-
            Total bloqueado por pedidos de reembolso em processamento: a soma de
            todas as partes da sua conta nesses pedidos, independentemente de o
            dinheiro já ter liberado ou não. Só a fatia `heldByRefund` dele está
            descontada de `available`; o resto já está fora de `pending` e de
            `reserved`. **`available`, `pending`, `reserved`, `anticipatable` e
            `refundBlocked` são parcelas disjuntas** — cada real aparece em no
            máximo um desses campos, então somá-los não conta nada duas vezes. A
            soma não é o patrimônio da conta: há dinheiro a receber fora das
            cinco.


            Vem `null` quando não há número a publicar: a retenção não está
            ativa para a sua conta, ou a apuração falhou nesta chamada. **`null`
            não é zero** — tratá-lo como zero esconde um bloqueio que pode
            existir. Zero de verdade vem `"0.00"`.
        refundBlockedFromPending:
          type: string
          format: decimal
          example: '2.49'
          nullable: true
          description: >-
            A parte de `refundBlocked` que está descontada de `pending`. Não é
            `refundBlocked - heldByRefund`: essa diferença mistura esta fatia
            com a de `reserved` e com o retido que não aparece em nenhum outro
            campo.


            Acompanha `refundBlocked`: vem `null` exatamente quando ele vem
            `null`, e `"0.00"` só quando a apuração aconteceu e nada foi
            descontado de `pending`.
        refundBlockedFromReserved:
          type: string
          format: decimal
          example: '2.49'
          nullable: true
          description: >-
            A parte de `refundBlocked` que está descontada de `reserved` — é o
            que distingue a reserva retida do pendente retido.


            **As fatias não somam `refundBlocked`.** `refundBlockedFromPending +
            refundBlockedFromReserved + heldByRefund` pode ser menor que ele, e
            a diferença é real: é o retido que não aparece em nenhum outro campo
            — pendente já dentro da janela de antecipação e venda parcialmente
            antecipada ainda não liberada.
      required:
        - anticipatable
        - available
        - currency
        - heldByRefund
        - pending
        - refundBlocked
        - refundBlockedFromPending
        - refundBlockedFromReserved
        - reserved
    UnauthenticatedError:
      type: object
      properties:
        detail:
          type: string
  examples:
    UnauthenticatedErrorExample:
      summary: Token ausente ou inválido
      description: Token ausente ou inválido
      value:
        detail: As credenciais de autenticação não foram fornecidas.
  securitySchemes:
    OAuth Token:
      type: http
      scheme: bearer
      in: header
      name: Authorization
      description: >-
        Token de autenticação do tipo `Bearer {access_token}`, onde
        `{access_token}` é o token obtido no fluxo de
        [autenticação](/authentication).

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.