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

# Saques

> Entenda como solicitar saques por API em produção.

# Saques

`POST /v1/withdrawals` cria uma solicitação de saque em produção.

Saques pela API são uma operação sensível: use apenas no backend, com uma chave `trq_live_` que tenha permissão de saque.

<Warning>
  Saques estão disponíveis somente em produção. Use o ambiente de teste para validar checkouts, saldo, webhooks e tratamento de erros sem movimentar fundos reais.
</Warning>

## Antes de chamar a API

Para criar um saque pela API, sua conta precisa atender a todos estes pontos:

* conta aprovada para produção
* telefone verificado
* destino de saque cadastrado e aprovado para o trilho escolhido
* saldo disponível suficiente em `availableAmount`
* chave de API com permissão de saque
* header `Idempotency-Key` enviado na criação

<Info>
  O destino do saque não é enviado no corpo da requisição. A API usa o destino já cadastrado e aprovado na sua conta.
</Info>

<Info>
  No piloto atual, criar um saque reserva o valor imediatamente e abre uma solicitação operacional. O valor fica em `reservedAmount` até o time concluir o pagamento e marcar o saque como pago. Essa revisão manual é intencional enquanto a operação aumenta volume com segurança.
</Info>

## Criar saque

```bash theme={null}
curl https://api.troqpay.com/v1/withdrawals \
  -X POST \
  -H "Authorization: Bearer trq_live_xxxxxxxxx" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: withdrawal_1001" \
  -d '{
    "rail": "BRL_PIX",
    "amount": "100.00"
  }'
```

Campos do corpo:

| Campo    | Tipo           | Obrigatório | Descrição                                        |
| -------- | -------------- | ----------- | ------------------------------------------------ |
| `rail`   | string         | Sim         | Trilho do saque. Use `BRL_PIX` ou `USDT_WALLET`. |
| `amount` | string decimal | Sim         | Valor bruto solicitado em BRL.                   |

O retorno usa o mesmo recurso de saque para criação e consulta:

```json theme={null}
{
  "id": "wdr_4a8b3c1d5e6f2a9b0c1d",
  "livemode": true,
  "rail": "BRL_PIX",
  "currency": "BRL",
  "status": "REQUESTED",
  "requestedAmount": "100.00",
  "destination": {
    "summary": "Pix CPF • 1234...7890",
    "label": "Maria Silva"
  },
  "quote": {
    "sourceAmount": "100.00",
    "sourceCurrency": "BRL",
    "withdrawalFeeAmount": "2.99",
    "withdrawalFeeCurrency": "BRL",
    "netSourceAmount": "97.01",
    "netSourceCurrency": "BRL",
    "destinationAmount": "97.01",
    "destinationCurrency": "BRL",
    "quotedRateBrlPerUsdt": null,
    "quotedAt": null,
    "quoteSource": "BRL_PIX_TERMS_V1",
    "network": null,
    "feePolicyVersion": "v1",
    "monthlyWithdrawalCountAtRequest": 0,
    "appliedFeeTier": "STANDARD"
  },
  "requestedAt": "2026-05-09T12:00:00.000Z",
  "approvedAt": null,
  "processingAt": null,
  "completedAt": null,
  "failedAt": null,
  "cancelledAt": null,
  "failure": null
}
```

## Tarifa do saque BRL

Cada saque em BRL via Pix tem uma tarifa que vem direto no `quote` da resposta. Você não precisa calcular nada.

Por padrão, a tarifa é **R$ 2,99** por saque. Se você fizer mais de 20 saques no mesmo mês, a partir do 21º o valor passa a ser **R$ 3,50**. O contador zera no início de cada mês, e saques recusados ou cancelados não contam.

A tarifa fica travada no momento da criação do saque. Os campos relevantes na resposta são:

* `quote.withdrawalFeeAmount`: o valor cobrado, em BRL
* `quote.appliedFeeTier`: `STANDARD` para R$ 2,99 ou `OVER_THRESHOLD` para R$ 3,50

<Tip>
  Se você quiser acompanhar quantos saques já fez no mês, leia `quote.monthlyWithdrawalCountAtRequest`. É o contador imediatamente antes do saque atual.
</Tip>

## Saque em USDT

Para o trilho `USDT_WALLET`, o `quote` da resposta traz a conversão de BRL para USDT. A cotação é travada no momento da criação do saque: o valor em USDT (`quote.destinationAmount`) e a taxa usada (`quote.quotedRateBrlPerUsdt`) ficam registrados no recurso e não mudam depois.

```json theme={null}
{
  "id": "wdr_7c2e9f1a4b6d8e3f0a2b",
  "livemode": true,
  "rail": "USDT_WALLET",
  "currency": "BRL",
  "status": "REQUESTED",
  "requestedAmount": "500.00",
  "destination": {
    "summary": "POLYGON • 0x1234...abcdef",
    "label": "Carteira USDT"
  },
  "quote": {
    "sourceAmount": "500.00",
    "sourceCurrency": "BRL",
    "withdrawalFeeAmount": "0.00",
    "withdrawalFeeCurrency": "BRL",
    "netSourceAmount": "500.00",
    "netSourceCurrency": "BRL",
    "destinationAmount": "84.745762",
    "destinationCurrency": "USDT",
    "quotedRateBrlPerUsdt": "5.900000",
    "quotedAt": "2026-05-09T12:00:00.000Z",
    "quoteSource": "COMPRAR_BITCOIN_OTC_V1",
    "network": "POLYGON",
    "feePolicyVersion": null,
    "monthlyWithdrawalCountAtRequest": null,
    "appliedFeeTier": null
  },
  "requestedAt": "2026-05-09T12:00:00.000Z",
  "approvedAt": null,
  "processingAt": null,
  "completedAt": null,
  "failedAt": null,
  "cancelledAt": null,
  "failure": null
}
```

Campos do `quote` específicos do trilho `USDT_WALLET`:

* `quote.destinationCurrency`: `USDT`
* `quote.destinationAmount`: o valor a receber em USDT, com 6 casas decimais
* `quote.quotedRateBrlPerUsdt`: a taxa de conversão em BRL por USDT travada na criação
* `quote.network`: a rede do destino (por exemplo, `POLYGON`)
* `quote.quotedAt`: o momento em que a cotação foi obtida

<Info>
  A cotação fica travada no momento da criação do saque. A disponibilidade da cotação depende do provedor externo: quando não é possível cotar, a criação retorna `422 quote_unavailable` e nenhum fundo é movimentado. Nesse caso, tente novamente.
</Info>

## Consultar saque

```bash theme={null}
curl https://api.troqpay.com/v1/withdrawals/wdr_4a8b3c1d5e6f2a9b0c1d \
  -H "Authorization: Bearer trq_live_xxxxxxxxx"
```

## Idempotência

`Idempotency-Key` é obrigatório em `POST /v1/withdrawals`.

* mesma chave e mesmo corpo retornam o mesmo saque
* mesma chave com corpo diferente retorna `409 idempotency_conflict`
* use uma chave estável do seu sistema para a tentativa de saque, como `withdrawal_1001`

Quando a solicitação é aceita, o saldo solicitado fica reservado. Repetir a mesma tentativa com a mesma `Idempotency-Key` retorna o mesmo saque em vez de reservar saldo de novo.

## Erros comuns

| HTTP  | `code`                           | Quando aparece                                                                                                                                    |
| ----- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `400` | `idempotency_key_required`       | Falta o header `Idempotency-Key`.                                                                                                                 |
| `403` | `test_withdrawals_not_supported` | A chave usada não é de produção.                                                                                                                  |
| `403` | `api_key_scope_forbidden`        | A chave não tem permissão de saque.                                                                                                               |
| `403` | `withdrawal_readiness_required`  | A conta ainda não completou a configuração necessária para sacar.                                                                                 |
| `403` | `withdrawals_blocked`            | Saques estão temporariamente bloqueados para a conta.                                                                                             |
| `409` | `idempotency_conflict`           | A mesma `Idempotency-Key` foi usada com outro corpo.                                                                                              |
| `422` | `invalid_amount`                 | O `amount` é inválido. O valor mínimo por saque é R\$ 10,00 e precisa ser maior que zero (e, para `USDT_WALLET`, maior que a tarifa configurada). |
| `422` | `limit_exceeded`                 | O valor excede o teto de R$ 50.000,00 por transação ou o teto de R$ 100.000,00 por dia.                                                           |
| `422` | `invalid_destination`            | O destino cadastrado é inválido para o trilho `USDT_WALLET` (endereço fora do formato da rede ou rede incompatível).                              |
| `422` | `quote_unavailable`              | Não foi possível obter a cotação para o saque `USDT_WALLET` no momento. Tente novamente.                                                          |
| `422` | `insufficient_balance`           | O saldo disponível não cobre o valor solicitado.                                                                                                  |
| `429` | `rate_limit_exceeded`            | O limite de requisições foi excedido. Faça retry com backoff (veja o header `Retry-After`).                                                       |

## Próximos passos

<CardGroup cols={3}>
  <Card title="Consultar saldo" href="/flows/saldo">
    Use `availableAmount` para decidir se o saque pode ser solicitado.
  </Card>

  <Card title="Revisar autenticação" href="/authentication">
    Entenda chaves, produção, idempotência e permissões.
  </Card>

  <Card title="Entender erros" href="/flows/errors">
    Veja o envelope de erro e como tratar cada `code`.
  </Card>
</CardGroup>
