> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.api.corpx.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.api.corpx.com/_mcp/server.

# Limites de cashout

O teto de saída é por conta, por operação e por janela. Não é uma regra de
[política](/baas/guias/autenticacao/politicas): `pixOut.maxAmount` não é mais
avaliado. Quem estoura o teto recebe `422 limit_exceeded_transaction`.

## Ler o disponível

`GET /v1/accounts/{accountId}/limits/available` devolve PIX, TED, boleto e
transferência interna, cada um com quatro janelas, usado e restante.

| Campo em `GET /limits/available` | O que é        | Horário (America/Sao\_Paulo) |
| -------------------------------- | -------------- | ---------------------------- |
| `singleTransfer`                 | Uma operação   | —                            |
| `daytime`                        | Janela diurna  | 06:00–20:00                  |
| `nighttime`                      | Janela noturna | 20:00–06:00                  |
| `monthly`                        | Mês calendário | —                            |

`operation` é `pix_out`, `ted_out`, `boleto` ou `internal_out`.

Sem teto efetivo a janela é fail-open: o pagamento não é barrado por limite
local. A precedência do teto é a célula da própria conta, depois o padrão do
tenant, depois o padrão global. `source` na janela diz qual dos três valeu.
Um teto local de PIX não substitui o teto do liquidante.

`GET /v1/accounts/{accountId}/pix/limits` está **deprecated**. Devolve só os
tetos de PIX do liquidante, sem usado, e aponta `Link` para
`/limits/available`.

## Pedir um aumento

`POST /v1/accounts/{accountId}/limit-requests` abre um pedido. **Não muda o
teto.** A CorpX analisa e, ao aprovar, aplica o valor na hora. `effectiveAt`
fica `null` enquanto não houver carência.

```bash
curl -X POST "https://tenant.api.corpx.com/v1/accounts/$ACCOUNT_ID/limit-requests" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Tenant-Id: $TENANT_ID" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 3f1c0b6e-9a2d-4c71-8e55-1b7a0d4c9e21" \
  -H "X-Acting-Document: 39053344705" \
  -H "X-Acting-Ip: 200.10.20.30" \
  -d '{
    "operation": "pix_out",
    "window": "daytime",
    "requestedLimitBrl": 50000,
    "justification": "Folha de pagamento do mês.",
    "identifier": "3f1c0b6e-9a2d-4c71-8e55-1b7a0d4c9e21",
    "risk": {
      "provider": "castle",
      "action": "allow",
      "score": 0.12,
      "policyName": "ib-limit-increase",
      "evaluatedAt": "2026-10-02T18:00:00Z"
    }
  }'
```

`201`:

```json
{
  "id": "lr_01J9XQ8K2M3N4P5Q6R7S8T9U0V",
  "status": "pending_review",
  "operation": "pix_out",
  "window": "daytime",
  "currentLimitBrl": 20000,
  "requestedLimitBrl": 50000,
  "approvedLimitBrl": null,
  "justification": "Folha de pagamento do mês.",
  "identifier": "3f1c0b6e-9a2d-4c71-8e55-1b7a0d4c9e21",
  "decisionMessage": null,
  "effectiveAt": null,
  "createdAt": "2026-10-02T18:00:01Z"
}
```

### Nomes da janela

Nesta rota a janela é snake\_case. No `GET /limits/available` o mesmo conceito
é camelCase. Não misture os dois.

| Pedido (`window`) | Leitura (`GET /limits/available`) |
| ----------------- | --------------------------------- |
| `single_transfer` | `singleTransfer`                  |
| `daytime`         | `daytime`                         |
| `nighttime`       | `nighttime`                       |
| `monthly`         | `monthly`                         |

`requestedLimitBrl` tem de ser **maior** que o teto efetivo daquela janela.
Sem teto, `currentLimitBrl` é `0` e qualquer valor positivo passa dessa
checagem. Valor igual ou menor é `422 limit_request_not_above_current`.

### Idempotência

`Idempotency-Key` é obrigatório (até 128 caracteres) e `identifier` tem de
ser **idêntico** ao header. A mesma chave devolve o pedido original com
`201`, mesmo que o corpo mude. Outra chave, com um pedido ainda em
`pending_review` para a mesma operação e janela, é `409 limit_request_pending`.

### Quem pediu e o risco

`X-Acting-Document` é obrigatório: CPF (11 dígitos) ou CNPJ (14). É o
documento que volta no webhook para você avisar a pessoa certa.
`X-Acting-Ip` é o IP do operador, não o do seu servidor.

`risk` é opcional. `action` é `allow`, `challenge` ou `deny`; `score`, se
vier, fica entre 0 e 1. O bloco só é armazenado e mostrado ao analista.
**`deny` não recusa o pedido.**

`justification` é obrigatória, até 500 caracteres.

## Acompanhar e cancelar

`GET /v1/accounts/{accountId}/limit-requests?status=` devolve
`{ "items": [...] }`. `status` filtra `pending_review`, `approved`,
`refused` ou `cancelled`. Sem filtro, devolve todos.

`GET .../limit-requests/{id}` acrescenta `decisionMessage`, `effectiveAt` e
`events`: `[{ "at", "status", "message" }]`. Só entram eventos públicos. A
nota interna do analista não sai nesta API.

`POST .../limit-requests/{id}/cancel` cancela só `pending_review`. Qualquer
outro status é `409 limit_request_closed`. O cancelamento também dispara o
webhook.

## Status

| Status           | Significado                                                                                            |
| ---------------- | ------------------------------------------------------------------------------------------------------ |
| `pending_review` | Na fila. O teto ainda é o antigo.                                                                      |
| `approved`       | Aprovado **e aplicado**. `approvedLimitBrl` é o teto que passou a valer e pode ser menor que o pedido. |
| `refused`        | Recusado. O teto não mudou. `decisionMessage` explica.                                                 |
| `cancelled`      | Cancelado por quem pediu, ainda em análise.                                                            |

Não existe estado "aprovado mas ainda não aplicado".

## Webhook `limit_request.updated`

Sai na aprovação, na recusa e no cancelamento. Não sai na abertura: o `201`
já é a confirmação. Assinatura por conta recebe o evento porque `accountId`
vai no envelope.

`data`: `id`, `accountId`, `status`, `operation`, `window`,
`requestedLimitBrl`, `approvedLimitBrl`, `decisionMessage`, `effectiveAt`,
`actingDocument`, `identifier`.

O exemplo completo está em [Webhooks](/baas/guias/conta/webhooks).

## Erros

| Código                                | HTTP | Quando                                                        |
| ------------------------------------- | ---- | ------------------------------------------------------------- |
| `missing_idempotency_key`             | 400  | Sem `Idempotency-Key`, ou chave acima de 128 caracteres       |
| `invalid_identifier`                  | 400  | `identifier` diferente da chave                               |
| `invalid_justification`               | 400  | Vazia ou acima de 500 caracteres                              |
| `invalid_risk`                        | 400  | `action` ou `score` fora do contrato                          |
| `acting_document_required`            | 400  | Sem `X-Acting-Document`                                       |
| `invalid_acting_document`             | 400  | Documento que não é CPF nem CNPJ                              |
| `limit_request_operation_unavailable` | 422  | `operation` ou `window` fora da tabela acima                  |
| `limit_request_not_above_current`     | 422  | Valor pedido (ou aprovado) não supera o teto efetivo          |
| `limit_request_pending`               | 409  | Já existe pedido em análise para a mesma operação e janela    |
| `limit_request_closed`                | 409  | Cancelar ou decidir um pedido que já saiu de `pending_review` |
| `limit_request_not_found`             | 404  | `id` inexistente nesta conta                                  |