Browse and search
API reference
Operational reserve: BRL 1 per new PIX-key (pix_key_reserve_usd) or Copia e Cola (copia_e_cola_buffer_usd) order, already included in the quote. Existing orders and DePix keep their terms. Full contract 1.44.2.
Fields, routes and responses from the published contract. Start with the manual to choose your flow.
New: US$ 1,000 partner prize
Until Oct 31, 2026, the first partner whose production key settles 100,000 USDT buying (cashin.settled) and 100,000 USDT selling (COMPLETED with the Pix paid) wins US$ 1,000 in USDT. Full rules.
New: USDT/USDC wallet
Deposit USDT or USDC on several networks and pay PIX from that balance, by key or Copia e Cola code, through the API (/carteira-usdt) or the dashboard. Enabled for every production key; test it with a lun_test_ key, which uses the simulator. How it works · Reference.
2026-10-08 · OpenAPI 1.44.0: for DePix sales, refund_address is no longer required at creation: the refund wallet is requested only if the sale fails (AWAITING_REFUND_ADDRESS, the cashout.awaiting_refund_address webhook and POST /cash-outs/{cashout_id}/refund-address), and DePix already sent to the provider is refunded only after the return is confirmed, at most what came back. In the partner dashboard: new accounts are activated with a 6-digit email code, Encerrar as outras sessões (End other sessions) under Meu acesso, an email when the password changes, Pagar com cripto (Pay with crypto) with stablecoins and the top 30 cryptocurrencies, and commission withdrawals from US$ 10. Crypto sale flowchart · Refund wallet · Dashboard · Everything that changed.
2026-10-08 · OpenAPI 1.43.1: a deposit request is valid for 1 hour (deposit_validity_hours = 1; expires_at = creation + 1 h); send within that window and the credit is automatic once the network confirms. In the new partner dashboard (parceiros.luniumpay.com, same sign-in), the request shows the address QR code and a countdown; the dashboard also brings a business summary, PDF receipts, notifications and team roles. About the dashboard.
Pricing
LuniumPay pricing is set per partner and drops with volume. Standard integration: 2% + R$ 2.00 per operation. Volume partners: negotiated rates down to 35 bps over the USDT market reference price for exclusive partners. Your key's current rate is returned by GET /keys/me and every quote is already net of fees. No monthly fee; start at any volume. Rates by product.
Receive reais. Choose the withdrawal destination later.
02 / WITHDRAWBalance to cryptoChoose asset, network and wallet for each withdrawal.
03 / OPERATEAPI via TelegramCharges, balance and withdrawals in your project group.
No matching section. Try another term.
Using this reference
Authentication: X-API-Key. Base: https://api.luniumpay.com. Request bodies use JSON. Optional fields do not bypass other operation validations.
Flows, Telegram, webhooks and checklist: open the integration manual.
Keep Portuguese wire identifiers unchanged: saldo means balance, erro is the error code and acao is the recommended action. Read the international integration glossary.
GET /carteira-usdt
USDT wallet balance and state
Available, reserved and confirming balance; networks accepted right now; minimums. Start here.
Responses
200 OK
JSON schema · 200
{
"type": "object",
"description": "State and balance of the project's USDT wallet.",
"properties": {
"enabled": {
"type": "boolean",
"description": "Wallet ready to operate now."
},
"sandbox": {
"type": "boolean",
"description": "Present and true only with a test key (simulator)."
},
"funding_source": {
"type": "string",
"enum": [
"crypto_usdt"
]
},
"currency": {
"type": "string",
"enum": [
"USDT"
]
},
"pix_rules": {
"type": "object",
"properties": {
"recipient_document_required": {
"type": "boolean"
}
}
},
"networks": {
"type": "array",
"description": "Networks accepted RIGHT NOW for deposits, with each one's assets and estimated crediting time.",
"items": {
"type": "object",
"properties": {
"network": {
"type": "string",
"example": "polygon"
},
"name": {
"type": "string",
"example": "Polygon"
},
"assets": {
"type": "array",
"items": {
"type": "string",
"enum": [
"USDT",
"USDC"
]
}
},
"eta_minutes": {
"type": [
"integer",
"null"
]
}
}
}
},
"balance": {
"type": "object",
"properties": {
"available": {
"type": "string",
"pattern": "^-?\\d+\\.\\d{6}$",
"description": "Available to pay Pix, in USDT (6 decimals)."
},
"reserved": {
"type": "string",
"pattern": "^-?\\d+\\.\\d{6}$",
"description": "Reserved by Pix payments in progress."
},
"confirming": {
"type": "string",
"pattern": "^-?\\d+\\.\\d{6}$",
"description": "Deposits seen, waiting for custody confirmation."
}
}
},
"min_deposit": {
"type": "string",
"pattern": "^-?\\d+\\.\\d{6}$",
"description": "Minimum deposit in USDT."
},
"min_payment_brl": {
"type": "string",
"example": "25.00",
"description": "Smallest Pix paid with USDT, in BRL."
},
"deposit_validity_hours": {
"type": "number",
"description": "Validity of a deposit request, in hours (currently 1)."
},
"payments_enabled": {
"type": "boolean"
},
"payment_methods": {
"type": "object",
"properties": {
"pix_key": {
"type": "boolean"
},
"br_code": {
"type": "boolean"
}
}
}
}
}401 Missing or invalid key.
403 carteira_nao_liberada: the wallet is not enabled for this project.
503 carteira_indisponivel / pagamentos_indisponiveis: retry shortly (acao: esperar).
GET /carteira-usdt/deposits
List deposits
The 100 most recent requests and what was credited.
Responses
200 OK
JSON schema · 200
{
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"type": "object",
"description": "Deposit request. The EXACT AMOUNT that arrives identifies the deposit: send `amount_to_send` on the given network before `expires_at`.",
"properties": {
"deposit_id": {
"type": "string",
"example": "ud_3f9c0a1b2c3d4e5f6a7b"
},
"status": {
"type": "string",
"enum": [
"waiting",
"confirming",
"available",
"expired",
"under_review",
"reversed"
],
"description": "`waiting` awaiting transfer · `confirming` seen, confirming · `available` credited to the balance · `expired` deadline passed without a deposit · `under_review` being checked · `reversed` undone."
},
"amount_to_send": {
"type": "string",
"pattern": "^-?\\d+\\.\\d{6}$",
"description": "Exact amount to send (the trailing decimals identify your deposit)."
},
"amount_received": {
"type": [
"string",
"null"
],
"description": "What arrived (credited)."
},
"address": {
"type": "string",
"description": "Destination address on the chosen network. In test mode it is fictitious (`SANDBOX-NAO-ENVIE-FUNDOS`)."
},
"network": {
"type": "string"
},
"network_name": {
"type": "string"
},
"asset": {
"type": "string"
},
"accepted_assets": {
"type": "array",
"items": {
"type": "string"
}
},
"expires_at": {
"type": "string",
"format": "date-time",
"description": "Request deadline: 1 hour after creation (`created_at` + `deposit_validity_hours`). Send within the deadline."
},
"created_at": {
"type": "string",
"format": "date-time"
},
"credited_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"origin": {
"type": "string",
"enum": [
"request",
"assigned_by_support"
]
},
"instructions": {
"type": "string",
"description": "Only on creation: the text to show the user."
},
"sandbox": {
"type": "boolean"
}
}
}
}
}
}401 Missing or invalid key.
403 carteira_nao_liberada: the wallet is not enabled for this project.
503 carteira_indisponivel / pagamentos_indisponiveis: retry shortly (acao: esperar).
POST /carteira-usdt/deposits
Request a deposit (USDT/USDC)
Opens a request with an EXACT AMOUNT and a 1-hour deadline (expires_at). Show the user amount_to_send, network_name and address. Crediting is automatic; follow GET /carteira-usdt/deposits or the wallet.deposit_credited webhook. USDC is credited 1:1.
JSON body
| Field | Type | Required | Description |
|---|---|---|---|
amount | string | true | USDT with up to 6 decimals; minimum in min_deposit. |
network | string | false | One of the networks from GET /carteira-usdt (networks[].network). |
Request schema
{
"type": "object",
"required": [
"amount"
],
"properties": {
"amount": {
"type": "string",
"example": "100",
"description": "USDT with up to 6 decimals; minimum in min_deposit."
},
"network": {
"type": "string",
"default": "polygon",
"description": "One of the networks from GET /carteira-usdt (networks[].network)."
}
}
}Example
{
"amount": "100",
"network": "tron"
}Responses
201 Request created.
JSON schema · 201
{
"type": "object",
"description": "Deposit request. The EXACT AMOUNT that arrives identifies the deposit: send `amount_to_send` on the given network before `expires_at`.",
"properties": {
"deposit_id": {
"type": "string",
"example": "ud_3f9c0a1b2c3d4e5f6a7b"
},
"status": {
"type": "string",
"enum": [
"waiting",
"confirming",
"available",
"expired",
"under_review",
"reversed"
],
"description": "`waiting` awaiting transfer · `confirming` seen, confirming · `available` credited to the balance · `expired` deadline passed without a deposit · `under_review` being checked · `reversed` undone."
},
"amount_to_send": {
"type": "string",
"pattern": "^-?\\d+\\.\\d{6}$",
"description": "Exact amount to send (the trailing decimals identify your deposit)."
},
"amount_received": {
"type": [
"string",
"null"
],
"description": "What arrived (credited)."
},
"address": {
"type": "string",
"description": "Destination address on the chosen network. In test mode it is fictitious (`SANDBOX-NAO-ENVIE-FUNDOS`)."
},
"network": {
"type": "string"
},
"network_name": {
"type": "string"
},
"asset": {
"type": "string"
},
"accepted_assets": {
"type": "array",
"items": {
"type": "string"
}
},
"expires_at": {
"type": "string",
"format": "date-time",
"description": "Request deadline: 1 hour after creation (`created_at` + `deposit_validity_hours`). Send within the deadline."
},
"created_at": {
"type": "string",
"format": "date-time"
},
"credited_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"origin": {
"type": "string",
"enum": [
"request",
"assigned_by_support"
]
},
"instructions": {
"type": "string",
"description": "Only on creation: the text to show the user."
},
"sandbox": {
"type": "boolean"
}
}
}400 valor_invalido, valor_abaixo_do_minimo (min_usdt), rede_indisponivel.
409 muitos_pedidos_abertos.
401 Missing or invalid key.
403 carteira_nao_liberada: the wallet is not enabled for this project.
503 carteira_indisponivel / pagamentos_indisponiveis: retry shortly (acao: esperar).
GET /carteira-usdt/payments
List payments
The 100 most recent. Completed ones include E2E, name, partial CPF and the receipt link.
Responses
200 OK
JSON schema · 200
{
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"type": "object",
"description": "Pix paid with the USDT balance.",
"properties": {
"payment_id": {
"type": "string",
"example": "cu_8a7b6c5d4e3f2a1b0c9d"
},
"external_id": {
"type": [
"string",
"null"
]
},
"status": {
"type": "string",
"enum": [
"reservado",
"ordem_criada",
"aceita",
"sacando",
"enviado",
"revisao",
"concluido",
"falhou",
"falhou_apos_envio"
],
"description": "Final: `concluido` (Pix paid), `falhou` (not executed; the reserve returned to the balance), `falhou_apos_envio` (under investigation; the reserve is NOT returned automatically). `revisao`: being checked — not a failure, keep following. The others are in-progress steps."
},
"final": {
"type": "boolean",
"description": "true when the state will not change anymore."
},
"payment_method": {
"type": "string",
"enum": [
"pix_key",
"br_code"
]
},
"brl_amount": {
"type": "string"
},
"pix_key": {
"type": [
"string",
"null"
],
"description": "Masked."
},
"usdt_reserved": {
"type": "string",
"pattern": "^-?\\d+\\.\\d{6}$",
"description": ""
},
"usdt_debited": {
"type": [
"string",
"null"
]
},
"usdt_order": {
"type": [
"string",
"null"
]
},
"withdrawal_fee": {
"type": [
"string",
"null"
]
},
"cashout_id": {
"type": [
"string",
"null"
],
"description": "The order that paid the Pix (GET /cash-outs/{cashout_id} has the detail)."
},
"error": {
"type": [
"string",
"null"
]
},
"pix_e2e": {
"type": "string",
"description": "Only on `concluido`: the Pix E2E identifier."
},
"recipient_name": {
"type": "string",
"description": "Only on `concluido`: recipient name."
},
"recipient_document": {
"type": [
"string",
"null"
],
"description": "Only on `concluido`: partial CPF (Central Bank format) or CNPJ."
},
"receipt_url": {
"type": [
"string",
"null"
],
"description": "Only on `concluido`: public link to the official receipt (null in test mode)."
},
"created_at": {
"type": "string",
"format": "date-time"
},
"updated_at": {
"type": "string",
"format": "date-time"
},
"sandbox": {
"type": "boolean"
}
}
}
}
}
}401 Missing or invalid key.
403 carteira_nao_liberada: the wallet is not enabled for this project.
503 carteira_indisponivel / pagamentos_indisponiveis: retry shortly (acao: esperar).
POST /carteira-usdt/payments
Pay a Pix with the USDT balance
Reserves the USDT, pays the Pix and debits what it cost (the leftover reserve is returned). Asynchronous: answers with reservado; follow GET /carteira-usdt/payments/{payment_id} or the wallet.payment_completed / wallet.payment_failed webhooks. Send external_id to retry safely: the same external_id with the same data returns the same payment (200).
JSON body
| Field | Type | Required | Description |
|---|---|---|---|
brl_amount | string | false | Amount the recipient receives, in BRL. Use EITHER brl_amount (with pix_key) OR br_code. |
br_code | string | false | Pix Copia e Cola code (starts with 000201). Amount and recipient come from the code; do not send brl_amount. |
funding_source | string | false | Optional; only crypto_usdt is accepted. |
pix_key | string | false | Recipient Pix key (required with brl_amount). |
pix_key_type | string | false | Recommended when the key has 11 digits (CPF or phone). |
quote_id | string | false | With br_code: the quote_id from the quote (optional). |
external_id | string | false | Your idempotency identifier. |
Request schema
{
"type": "object",
"properties": {
"brl_amount": {
"type": "string",
"example": "50.00",
"description": "Amount the recipient receives, in BRL. Use EITHER brl_amount (with pix_key) OR br_code."
},
"br_code": {
"type": "string",
"description": "Pix Copia e Cola code (starts with 000201). Amount and recipient come from the code; do not send brl_amount."
},
"funding_source": {
"type": "string",
"enum": [
"crypto_usdt"
],
"description": "Optional; only crypto_usdt is accepted."
},
"pix_key": {
"type": "string",
"description": "Recipient Pix key (required with brl_amount)."
},
"pix_key_type": {
"type": "string",
"enum": [
"cpf",
"cnpj",
"email",
"phone",
"random"
],
"description": "Recommended when the key has 11 digits (CPF or phone)."
},
"quote_id": {
"type": "string",
"description": "With br_code: the quote_id from the quote (optional)."
},
"external_id": {
"type": "string",
"maxLength": 64,
"description": "Your idempotency identifier."
}
}
}Example
{
"brl_amount": "50.00",
"pix_key": "cliente@exemplo.com",
"pix_key_type": "email",
"external_id": "pedido-123"
}Responses
201 Payment created.
JSON schema · 201
{
"type": "object",
"description": "Pix paid with the USDT balance.",
"properties": {
"payment_id": {
"type": "string",
"example": "cu_8a7b6c5d4e3f2a1b0c9d"
},
"external_id": {
"type": [
"string",
"null"
]
},
"status": {
"type": "string",
"enum": [
"reservado",
"ordem_criada",
"aceita",
"sacando",
"enviado",
"revisao",
"concluido",
"falhou",
"falhou_apos_envio"
],
"description": "Final: `concluido` (Pix paid), `falhou` (not executed; the reserve returned to the balance), `falhou_apos_envio` (under investigation; the reserve is NOT returned automatically). `revisao`: being checked — not a failure, keep following. The others are in-progress steps."
},
"final": {
"type": "boolean",
"description": "true when the state will not change anymore."
},
"payment_method": {
"type": "string",
"enum": [
"pix_key",
"br_code"
]
},
"brl_amount": {
"type": "string"
},
"pix_key": {
"type": [
"string",
"null"
],
"description": "Masked."
},
"usdt_reserved": {
"type": "string",
"pattern": "^-?\\d+\\.\\d{6}$",
"description": ""
},
"usdt_debited": {
"type": [
"string",
"null"
]
},
"usdt_order": {
"type": [
"string",
"null"
]
},
"withdrawal_fee": {
"type": [
"string",
"null"
]
},
"cashout_id": {
"type": [
"string",
"null"
],
"description": "The order that paid the Pix (GET /cash-outs/{cashout_id} has the detail)."
},
"error": {
"type": [
"string",
"null"
]
},
"pix_e2e": {
"type": "string",
"description": "Only on `concluido`: the Pix E2E identifier."
},
"recipient_name": {
"type": "string",
"description": "Only on `concluido`: recipient name."
},
"recipient_document": {
"type": [
"string",
"null"
],
"description": "Only on `concluido`: partial CPF (Central Bank format) or CNPJ."
},
"receipt_url": {
"type": [
"string",
"null"
],
"description": "Only on `concluido`: public link to the official receipt (null in test mode)."
},
"created_at": {
"type": "string",
"format": "date-time"
},
"updated_at": {
"type": "string",
"format": "date-time"
},
"sandbox": {
"type": "boolean"
}
}
}200 Retry of the same external_id: the existing payment.
JSON schema · 200
{
"type": "object",
"description": "Pix paid with the USDT balance.",
"properties": {
"payment_id": {
"type": "string",
"example": "cu_8a7b6c5d4e3f2a1b0c9d"
},
"external_id": {
"type": [
"string",
"null"
]
},
"status": {
"type": "string",
"enum": [
"reservado",
"ordem_criada",
"aceita",
"sacando",
"enviado",
"revisao",
"concluido",
"falhou",
"falhou_apos_envio"
],
"description": "Final: `concluido` (Pix paid), `falhou` (not executed; the reserve returned to the balance), `falhou_apos_envio` (under investigation; the reserve is NOT returned automatically). `revisao`: being checked — not a failure, keep following. The others are in-progress steps."
},
"final": {
"type": "boolean",
"description": "true when the state will not change anymore."
},
"payment_method": {
"type": "string",
"enum": [
"pix_key",
"br_code"
]
},
"brl_amount": {
"type": "string"
},
"pix_key": {
"type": [
"string",
"null"
],
"description": "Masked."
},
"usdt_reserved": {
"type": "string",
"pattern": "^-?\\d+\\.\\d{6}$",
"description": ""
},
"usdt_debited": {
"type": [
"string",
"null"
]
},
"usdt_order": {
"type": [
"string",
"null"
]
},
"withdrawal_fee": {
"type": [
"string",
"null"
]
},
"cashout_id": {
"type": [
"string",
"null"
],
"description": "The order that paid the Pix (GET /cash-outs/{cashout_id} has the detail)."
},
"error": {
"type": [
"string",
"null"
]
},
"pix_e2e": {
"type": "string",
"description": "Only on `concluido`: the Pix E2E identifier."
},
"recipient_name": {
"type": "string",
"description": "Only on `concluido`: recipient name."
},
"recipient_document": {
"type": [
"string",
"null"
],
"description": "Only on `concluido`: partial CPF (Central Bank format) or CNPJ."
},
"receipt_url": {
"type": [
"string",
"null"
],
"description": "Only on `concluido`: public link to the official receipt (null in test mode)."
},
"created_at": {
"type": "string",
"format": "date-time"
},
"updated_at": {
"type": "string",
"format": "date-time"
},
"sandbox": {
"type": "boolean"
}
}
}400 valor_invalido, valor_abaixo_do_minimo, pix_key_obrigatoria, br_code_invalido, campos_conflitantes, cotacao_recusada.
409 saldo_insuficiente, external_id_divergente, cotacao_divergente.
401 Missing or invalid key.
403 carteira_nao_liberada: the wallet is not enabled for this project.
503 carteira_indisponivel / pagamentos_indisponiveis: retry shortly (acao: esperar).
GET /carteira-usdt/payments/{payment_id}
Follow a payment
Current state of the Pix paid with USDT. Completed includes E2E, name, partial CPF and receipt_url.
Parameters
| Field | In | Required | Description |
|---|---|---|---|
payment_id | path | true |
Responses
200 OK
JSON schema · 200
{
"type": "object",
"description": "Pix paid with the USDT balance.",
"properties": {
"payment_id": {
"type": "string",
"example": "cu_8a7b6c5d4e3f2a1b0c9d"
},
"external_id": {
"type": [
"string",
"null"
]
},
"status": {
"type": "string",
"enum": [
"reservado",
"ordem_criada",
"aceita",
"sacando",
"enviado",
"revisao",
"concluido",
"falhou",
"falhou_apos_envio"
],
"description": "Final: `concluido` (Pix paid), `falhou` (not executed; the reserve returned to the balance), `falhou_apos_envio` (under investigation; the reserve is NOT returned automatically). `revisao`: being checked — not a failure, keep following. The others are in-progress steps."
},
"final": {
"type": "boolean",
"description": "true when the state will not change anymore."
},
"payment_method": {
"type": "string",
"enum": [
"pix_key",
"br_code"
]
},
"brl_amount": {
"type": "string"
},
"pix_key": {
"type": [
"string",
"null"
],
"description": "Masked."
},
"usdt_reserved": {
"type": "string",
"pattern": "^-?\\d+\\.\\d{6}$",
"description": ""
},
"usdt_debited": {
"type": [
"string",
"null"
]
},
"usdt_order": {
"type": [
"string",
"null"
]
},
"withdrawal_fee": {
"type": [
"string",
"null"
]
},
"cashout_id": {
"type": [
"string",
"null"
],
"description": "The order that paid the Pix (GET /cash-outs/{cashout_id} has the detail)."
},
"error": {
"type": [
"string",
"null"
]
},
"pix_e2e": {
"type": "string",
"description": "Only on `concluido`: the Pix E2E identifier."
},
"recipient_name": {
"type": "string",
"description": "Only on `concluido`: recipient name."
},
"recipient_document": {
"type": [
"string",
"null"
],
"description": "Only on `concluido`: partial CPF (Central Bank format) or CNPJ."
},
"receipt_url": {
"type": [
"string",
"null"
],
"description": "Only on `concluido`: public link to the official receipt (null in test mode)."
},
"created_at": {
"type": "string",
"format": "date-time"
},
"updated_at": {
"type": "string",
"format": "date-time"
},
"sandbox": {
"type": "boolean"
}
}
}404 nao_encontrado.
401 Missing or invalid key.
403 carteira_nao_liberada: the wallet is not enabled for this project.
503 carteira_indisponivel / pagamentos_indisponiveis: retry shortly (acao: esperar).
POST /carteira-usdt/quote
Quote a Pix paid with USDT
No-effect preview: how much USDT is used to pay the Pix. Minimum Pix in min_payment_brl.
JSON body
| Field | Type | Required | Description |
|---|---|---|---|
brl_amount | string | false | Amount the recipient receives, in BRL. Use EITHER brl_amount (with pix_key) OR br_code. |
br_code | string | false | Pix Copia e Cola code (starts with 000201). Amount and recipient come from the code; do not send brl_amount. |
funding_source | string | false | Optional; only crypto_usdt is accepted. |
Request schema
{
"type": "object",
"properties": {
"brl_amount": {
"type": "string",
"example": "50.00",
"description": "Amount the recipient receives, in BRL. Use EITHER brl_amount (with pix_key) OR br_code."
},
"br_code": {
"type": "string",
"description": "Pix Copia e Cola code (starts with 000201). Amount and recipient come from the code; do not send brl_amount."
},
"funding_source": {
"type": "string",
"enum": [
"crypto_usdt"
],
"description": "Optional; only crypto_usdt is accepted."
}
}
}Example
{
"brl_amount": "50.00"
}Responses
200 OK
JSON schema · 200
{
"type": "object",
"description": "Preview of a Pix paid with USDT. Estimate: on confirmation the quote is redone and up to 1% extra is reserved (the leftover is returned).",
"properties": {
"payment_method": {
"type": "string",
"enum": [
"pix_key",
"br_code"
]
},
"brl_amount": {
"type": "string",
"example": "50.00"
},
"usdt_order": {
"type": "string",
"pattern": "^-?\\d+\\.\\d{6}$",
"description": "USDT converted to pay the Pix."
},
"withdrawal_fee": {
"type": "string",
"pattern": "^-?\\d+\\.\\d{6}$",
"description": "Transfer cost."
},
"usdt_total": {
"type": "string",
"pattern": "^-?\\d+\\.\\d{6}$",
"description": "Estimated total debited."
},
"usdt_reserved": {
"type": "string",
"pattern": "^-?\\d+\\.\\d{6}$",
"description": "How much stays reserved until the Pix completes."
},
"quote_id": {
"type": "string",
"description": "Only with br_code: send it to POST /carteira-usdt/payments to make sure it is the same code."
},
"merchant_name": {
"type": [
"string",
"null"
]
},
"pix_key": {
"type": [
"string",
"null"
]
},
"pix_key_type": {
"type": [
"string",
"null"
]
},
"expires_at": {
"type": "string",
"format": "date-time"
},
"note": {
"type": "string"
},
"sandbox": {
"type": "boolean"
}
}
}400 valor_invalido, valor_abaixo_do_minimo (min_brl), br_code_invalido, campos_conflitantes, cotacao_recusada, funding_source_invalido.
401 Missing or invalid key.
403 carteira_nao_liberada: the wallet is not enabled for this project.
503 carteira_indisponivel / pagamentos_indisponiveis: retry shortly (acao: esperar).
GET /carteira-usdt/statement
Wallet statement
The 200 most recent ledger lines, with the balance after each one.
Responses
200 OK
JSON schema · 200
{
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"type": "object",
"description": "Statement line. `amount` is always positive; `type` gives the direction.",
"properties": {
"entry_id": {
"type": "string"
},
"type": {
"type": "string",
"enum": [
"deposit",
"reserve",
"release",
"debit",
"reversal"
],
"description": "`deposit` deposit credit · `reserve` reserve for a Pix · `debit` Pix paid · `release` leftover or reserve returned to available · `reversal` deposit undone."
},
"amount": {
"type": "string",
"pattern": "^-?\\d+\\.\\d{6}$",
"description": ""
},
"available_after": {
"type": "string",
"pattern": "^-?\\d+\\.\\d{6}$",
"description": ""
},
"reserved_after": {
"type": "string",
"pattern": "^-?\\d+\\.\\d{6}$",
"description": ""
},
"reference": {
"type": "string",
"description": "The Pix `payment_id`, `deposit` or `adjustment`."
},
"created_at": {
"type": "string",
"format": "date-time"
}
}
}
}
}
}401 Missing or invalid key.
403 carteira_nao_liberada: the wallet is not enabled for this project.
503 carteira_indisponivel / pagamentos_indisponiveis: retry shortly (acao: esperar).
GET /cash-outs
List orders
Parameters
| Field | In | Required | Description |
|---|---|---|---|
state | query | false | |
limit | query | false | |
external_id | query | false | Idempotent recovery: returns the operation with this external_id, if any (0 or 1). Unique per key and product, case-sensitive and retained permanently. |
Responses
200 Orders belonging to your key, newest first.
401 Missing, unknown or incorrect X-API-Key.
JSON schema · 401
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}POST /cash-outs
Request a quote (step 1 of 3)
Create a quote for external crypto to PIX. The deposit address is returned only after acceptance. Send exactly one of amount or brl_amount as a decimal string, and a pair from GET /catalog. Read key and per-operation limits in GET /keys/me and effective recipient limits in the response. The mandate may impose additional restrictions. Supply refund_address to control the destination of any refund. br_code has separate availability and may return 503 br_code_indisponivel even when preview or sandbox accepts it. Production returns 200 on creation; sandbox may return 201.
JSON body
| Field | Type | Required | Description |
|---|---|---|---|
asset | string | true | Asset to sell. Use the EXACT id from GET /catalog (for example, "usdt"). The (asset, network) pair must exist in that catalog. |
network | string | true | Incoming crypto network from GET /catalog. Do not confuse it with delivery networks from /cashin/catalog. |
amount | string | false | Crypto quantity as a decimal string ( |
brl_amount | string | false | REVERSE quote: desired PIX amount in BRL as a decimal string with up to two decimal places ( |
pix_key | string | true | PIX key receiving BRL. Accepted formats are normalized to the settlement provider's format: CPF (11 digits), CNPJ (14 digits), international phone +55 followed by area code and number (for example, +5548996005588), email or UUID random key (for example, 6602ede6-b1a9-4e63-9178-c6883fd0095e). Invalid formats return 400 pix_key_invalida before any deposit is created. |
pix_key_type | string | false | Optional: inferred from email, CNPJ, UUID or a +55 phone number. Required for 11 bare digits, where CPF and phone numbers cannot be distinguished. In that case the API returns tipo_ambiguo instead of guessing. Values: |
token_address | string | false | Exact token contract address or mint. Required for tokens from |
external_id | string | false | Idempotency identifier, up to 64 characters. Keep the identifier and every request parameter unchanged on retries. Conflict detection differs by route; do not use a replay to modify an operation. 409 external_id_divergente indicates a detected conflict. |
refund_address | string | false | Your customer's RETURN wallet on the same network as the sale. Used for refunds, such as provider rejection, PIX reversal or failure before payout. Do not infer it from the on-chain source of the deposit, which may be an exchange's wallet rather than the customer's own wallet: without it, a refund waits in AWAITING_REFUND_ADDRESS until you send the wallet via POST /cash-outs/{cashout_id}/refund-address; read refund_asset, refund_network and refund_amount when returned. DePix sale: optional since 1.44.0 (it used to be required); when supplied, it must be a valid Liquid address (lq1…) of your customer, in the sandbox as well. |
br_code | string | false | PIX copy-and-paste string for a charge with a specified amount, when supported. USDT/USDC only; replaces pix_key, amount and brl_amount. May return 503 br_code_indisponivel in production. The quoted amount includes a fixed BRL 1.00 reserve (reserve_brl; USDT equivalent in copia_e_cola_buffer_usd) that guarantees the PIX at the exact QR amount; any unused part is kept by Lunium as a correction reserve and is not refunded. |
Request schema
{
"type": "object",
"required": [
"asset",
"network",
"pix_key"
],
"properties": {
"asset": {
"type": "string",
"examples": [
"USDT"
],
"description": "Asset to sell. Use the EXACT id from GET /catalog (for example, \"usdt\"). The (asset, network) pair must exist in that catalog."
},
"network": {
"type": "string",
"description": "Incoming crypto network from GET /catalog. Do not confuse it with delivery networks from /cashin/catalog.",
"examples": [
"polygon"
]
},
"amount": {
"type": "string",
"description": "Crypto quantity as a decimal string (`\"50\"`), never a floating-point number. Supply exactly one of `amount` or `brl_amount`.",
"examples": [
"50"
]
},
"brl_amount": {
"type": "string",
"description": "REVERSE quote: desired PIX amount in BRL as a decimal string with up to two decimal places (`\"250.00\"`). Lunium calculates the crypto amount; the response's `amount` is what the customer must deposit. Supply exactly one of `amount` or `brl_amount`. Range: R$6.00–R$250,000.00 per transaction, also subject to the recipient's R$100,000.00 daily cap; the lower limit applies.",
"examples": [
"250.00"
]
},
"pix_key": {
"type": "string",
"description": "PIX key receiving BRL. Accepted formats are normalized to the settlement provider's format: CPF (11 digits), CNPJ (14 digits), international phone +55 followed by area code and number (for example, +5548996005588), email or UUID random key (for example, 6602ede6-b1a9-4e63-9178-c6883fd0095e). Invalid formats return 400 pix_key_invalida before any deposit is created."
},
"pix_key_type": {
"type": "string",
"enum": [
"cpf",
"cnpj",
"phone",
"email",
"random"
],
"description": "Optional: inferred from email, CNPJ, UUID or a +55 phone number. Required for 11 bare digits, where CPF and phone numbers cannot be distinguished. In that case the API returns tipo_ambiguo instead of guessing."
},
"token_address": {
"type": "string",
"description": "Exact token contract address or mint. Required for tokens from `/catalog/dex`, where symbols may be shared by different tokens."
},
"external_id": {
"type": "string",
"description": "Idempotency identifier, up to 64 characters. Keep the identifier and every request parameter unchanged on retries. Conflict detection differs by route; do not use a replay to modify an operation. 409 external_id_divergente indicates a detected conflict.",
"maxLength": 64
},
"refund_address": {
"type": "string",
"description": "Your customer's RETURN wallet on the same network as the sale. Used for refunds, such as provider rejection, PIX reversal or failure before payout. Do not infer it from the on-chain source of the deposit, which may be an exchange's wallet rather than the customer's own wallet: without it, a refund waits in AWAITING_REFUND_ADDRESS until you send the wallet via POST /cash-outs/{cashout_id}/refund-address; read refund_asset, refund_network and refund_amount when returned. DePix sale: optional since 1.44.0 (it used to be required); when supplied, it must be a valid Liquid address (lq1…) of your customer, in the sandbox as well.",
"examples": [
"0x51e3d44172868acc60d68ca99591ce4230bc75e0"
]
},
"br_code": {
"type": "string",
"description": "PIX copy-and-paste string for a charge with a specified amount, when supported. USDT/USDC only; replaces pix_key, amount and brl_amount. May return 503 br_code_indisponivel in production. The quoted amount includes a fixed BRL 1.00 reserve (reserve_brl; USDT equivalent in copia_e_cola_buffer_usd) that guarantees the PIX at the exact QR amount; any unused part is kept by Lunium as a correction reserve and is not refunded.",
"examples": [
"00020126330014br.gov.bcb.pix0111498113948905204000053039865406…6304ABCD"
]
}
}
}Responses
201 Quote created.
JSON schema · 201
{
"type": "object",
"properties": {
"cashout_id": {
"type": "string",
"format": "uuid"
},
"state": {
"type": "string",
"enum": [
"QUOTE_CREATED",
"AWAITING_DEPOSIT",
"DEPOSIT_DETECTED",
"DEPOSIT_CONFIRMED",
"SELLING",
"SOLD",
"FORWARDING",
"PAYING_OUT",
"COMPLETED",
"MANUAL_REVIEW",
"REFUNDING_CRYPTO",
"REFUNDED",
"EXPIRED",
"FAILED",
"DELAYED",
"AWAITING_REFUND_ADDRESS",
"PROCESSING",
"REFUNDING"
],
"description": "Order state. COMPLETED confirms the PIX payment. Intermediate stages vary by settlement route. DELAYED belongs to a sandbox scenario. AWAITING_REFUND_ADDRESS: a refund is needed and the order has no return wallet; send it via POST /cash-outs/{cashout_id}/refund-address (crypto sales and, since 1.44.0, DePix sales). DePix sale: QUOTE_CREATED → AWAITING_DEPOSIT → DEPOSIT_DETECTED → PROCESSING → COMPLETED; if the Pix cannot be paid, REFUNDING → REFUNDED, or AWAITING_REFUND_ADDRESS when the wallet is missing. DePix already forwarded to the provider is refunded only after its return is confirmed: until then the order stays in MANUAL_REVIEW, and the refund is at most what came back."
},
"path": {
"type": [
"string",
"null"
],
"enum": [
"FAST",
"DEX",
"CONVERT",
null
],
"description": "FAST, DEX or CONVERT settlement route. Timing depends on the route, confirmations and processing."
},
"asset": {
"type": "string",
"examples": [
"USDT"
],
"description": "Asset to sell. Use the EXACT id from GET /catalog (for example, \"usdt\"). The (asset, network) pair must exist in that catalog."
},
"network": {
"type": "string",
"examples": [
"polygon"
],
"description": "Blockchain deposit network, as listed in the catalog (for example, \"polygon\"). The returned deposit address is valid only on this network."
},
"amount": {
"type": "string",
"description": "Crypto amount as a decimal string. Never use a floating-point number."
},
"brl_amount": {
"type": [
"string",
"null"
],
"description": "Amount in Brazilian reais (BRL) that the PIX recipient will receive."
},
"pix_key": {
"type": "string",
"description": "Destination PIX key: CPF, CNPJ, +55 phone number, email or random key. For 11 bare digits, also send pix_key_type (\"cpf\" or \"phone\"); otherwise the API returns erro=tipo_ambiguo instead of guessing."
},
"pix_key_type": {
"type": "string",
"enum": [
"cpf",
"cnpj",
"phone",
"email",
"random"
],
"description": "Usually omit it: the type is inferred from the key for e-mails, CNPJs, random keys and phones written with the +55 country code. Only required when the key is 11 bare digits, because a CPF and a phone number are the same length and guessing would pay the wrong person. An explicit type always wins over inference."
},
"deposit_address": {
"type": [
"string",
"null"
],
"description": "Address to which the customer sends crypto. Returned only after acceptance."
},
"deposit_tag": {
"type": [
"string",
"null"
],
"description": "Memo/tag that must accompany the deposit when returned by the accept operation. Use only networks listed in GET /catalog."
},
"external_id": {
"type": [
"string",
"null"
],
"description": "Idempotency identifier, up to 64 characters. Keep the identifier and every request parameter unchanged on retries. Conflict detection differs by route; do not use a replay to modify an operation. 409 external_id_divergente indicates a detected conflict.",
"maxLength": 64
},
"refund_address": {
"type": [
"string",
"null"
],
"description": "Return wallet supplied by the customer, at creation or via POST /cash-outs/{cashout_id}/refund-address: the destination of any refund. null means no wallet was supplied; Lunium never uses deposit_from in its place — if a refund is needed, the order waits in AWAITING_REFUND_ADDRESS. Also applies to DePix sales (Liquid lq1… address) since 1.44.0."
},
"refund_tx_hash": {
"type": [
"string",
"null"
],
"description": "Refund transaction hash when completed. Its presence does not imply a fixed refund amount or time for all cases."
},
"deposit_from": {
"type": [
"string",
"null"
],
"description": "Address that SENT the deposit, read on-chain; informational only. It may be an exchange's shared wallet, so it is never chosen automatically as a refund destination."
},
"br_code": {
"type": [
"string",
"null"
],
"description": "PIX copy-and-paste payment string supplied with the quote, if any. brl_amount is the QR payment amount."
},
"merchant_name": {
"type": [
"string",
"null"
],
"description": "Recipient name read from the PIX payment QR."
},
"expires_at": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "Quote expiration timestamp in ISO 8601 UTC (for example, 2026-09-02T14:03:00Z). Acceptance after this time fails with erro=cotacao_expirada. Request a new quote instead of retrying acceptance."
},
"pix_e2e": {
"type": [
"string",
"null"
],
"description": "The completed PIX payment's Central Bank end-to-end identifier. Anyone can verify it at GET /v1/verificar/{e2e} without an API key. Return it to your end customer as the payment reference.",
"examples": [
"E37293930202607312006361894c4a82"
]
},
"pix_paid_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"receipt_url": {
"type": [
"string",
"null"
],
"description": "Shareable receipt page that opens on the end customer's phone.",
"examples": [
"https://app.luniumpay.com/comprovante/uwscff6ASNS1oUcH2LHbvw"
]
},
"receipt_pdf_url": {
"type": [
"string",
"null"
],
"nullable": true,
"format": "uri",
"description": "Receipt as a PDF file for support tickets, customer messages or accounting. Contains recipient name, tax ID, institution, amount, date, E2E and verification link. Generated from the same data as the receipt page. null until the order reaches the state that supplies it.",
"example": "https://app.luniumpay.com/comprovante/qigpnCTx3gM-Ge7hN27Mvw.pdf"
},
"verify_url": {
"type": [
"string",
"null"
],
"nullable": true,
"format": "uri",
"description": "Public verification link requiring no API key. Share it so the counterparty can check the payment independently. Does not expose the PIX key, full name or tax ID. null until the order reaches the state that supplies it.",
"example": "https://api.luniumpay.com/v1/verificar/E3729393020260731214021222ac6ff1"
},
"created_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"updated_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"timeline": {
"type": "array",
"description": "Timeline timestamped by the SERVER at each transition, rather than by your polling: AWAITING_DEPOSIT → DEPOSIT_DETECTED → DEPOSIT_CONFIRMED → (SELLING → SOLD → FORWARDING, exchange route only) → PAYING_OUT → COMPLETED. Use it in the customer's tracker.",
"items": {
"type": "object",
"properties": {
"state": {
"type": "string"
},
"at": {
"type": "string",
"format": "date-time"
}
}
}
},
"confirmations": {
"type": [
"integer",
"null"
],
"description": "Deposit confirmations observed live. Returned only while the order is confirming; not persisted and may change with each block. Display progress using this field and confirmations_required."
},
"confirmations_required": {
"type": [
"integer",
"null"
],
"description": "Number of confirmations the exchange requires before crediting a deposit on this network."
},
"failure_reason": {
"type": [
"string",
"null"
],
"description": "Failure reason when returned, including sandbox scenarios."
},
"sandbox": {
"type": "boolean",
"description": "True for fictitious sandbox operations."
},
"simulation": {
"type": "object",
"additionalProperties": true
}
}
}200 Quote created.
JSON schema · 200
{
"type": "object",
"properties": {
"cashout_id": {
"type": "string",
"format": "uuid"
},
"state": {
"type": "string",
"enum": [
"QUOTE_CREATED",
"AWAITING_DEPOSIT",
"DEPOSIT_DETECTED",
"DEPOSIT_CONFIRMED",
"SELLING",
"SOLD",
"FORWARDING",
"PAYING_OUT",
"COMPLETED",
"MANUAL_REVIEW",
"REFUNDING_CRYPTO",
"REFUNDED",
"EXPIRED",
"FAILED",
"DELAYED",
"AWAITING_REFUND_ADDRESS",
"PROCESSING",
"REFUNDING"
],
"description": "Order state. COMPLETED confirms the PIX payment. Intermediate stages vary by settlement route. DELAYED belongs to a sandbox scenario. AWAITING_REFUND_ADDRESS: a refund is needed and the order has no return wallet; send it via POST /cash-outs/{cashout_id}/refund-address (crypto sales and, since 1.44.0, DePix sales). DePix sale: QUOTE_CREATED → AWAITING_DEPOSIT → DEPOSIT_DETECTED → PROCESSING → COMPLETED; if the Pix cannot be paid, REFUNDING → REFUNDED, or AWAITING_REFUND_ADDRESS when the wallet is missing. DePix already forwarded to the provider is refunded only after its return is confirmed: until then the order stays in MANUAL_REVIEW, and the refund is at most what came back."
},
"path": {
"type": [
"string",
"null"
],
"enum": [
"FAST",
"DEX",
"CONVERT",
null
],
"description": "FAST, DEX or CONVERT settlement route. Timing depends on the route, confirmations and processing."
},
"asset": {
"type": "string",
"examples": [
"USDT"
],
"description": "Asset to sell. Use the EXACT id from GET /catalog (for example, \"usdt\"). The (asset, network) pair must exist in that catalog."
},
"network": {
"type": "string",
"examples": [
"polygon"
],
"description": "Blockchain deposit network, as listed in the catalog (for example, \"polygon\"). The returned deposit address is valid only on this network."
},
"amount": {
"type": "string",
"description": "Crypto amount as a decimal string. Never use a floating-point number."
},
"brl_amount": {
"type": [
"string",
"null"
],
"description": "Amount in Brazilian reais (BRL) that the PIX recipient will receive."
},
"pix_key": {
"type": "string",
"description": "Destination PIX key: CPF, CNPJ, +55 phone number, email or random key. For 11 bare digits, also send pix_key_type (\"cpf\" or \"phone\"); otherwise the API returns erro=tipo_ambiguo instead of guessing."
},
"pix_key_type": {
"type": "string",
"enum": [
"cpf",
"cnpj",
"phone",
"email",
"random"
],
"description": "Usually omit it: the type is inferred from the key for e-mails, CNPJs, random keys and phones written with the +55 country code. Only required when the key is 11 bare digits, because a CPF and a phone number are the same length and guessing would pay the wrong person. An explicit type always wins over inference."
},
"deposit_address": {
"type": [
"string",
"null"
],
"description": "Address to which the customer sends crypto. Returned only after acceptance."
},
"deposit_tag": {
"type": [
"string",
"null"
],
"description": "Memo/tag that must accompany the deposit when returned by the accept operation. Use only networks listed in GET /catalog."
},
"external_id": {
"type": [
"string",
"null"
],
"description": "Idempotency identifier, up to 64 characters. Keep the identifier and every request parameter unchanged on retries. Conflict detection differs by route; do not use a replay to modify an operation. 409 external_id_divergente indicates a detected conflict.",
"maxLength": 64
},
"refund_address": {
"type": [
"string",
"null"
],
"description": "Return wallet supplied by the customer, at creation or via POST /cash-outs/{cashout_id}/refund-address: the destination of any refund. null means no wallet was supplied; Lunium never uses deposit_from in its place — if a refund is needed, the order waits in AWAITING_REFUND_ADDRESS. Also applies to DePix sales (Liquid lq1… address) since 1.44.0."
},
"refund_tx_hash": {
"type": [
"string",
"null"
],
"description": "Refund transaction hash when completed. Its presence does not imply a fixed refund amount or time for all cases."
},
"deposit_from": {
"type": [
"string",
"null"
],
"description": "Address that SENT the deposit, read on-chain; informational only. It may be an exchange's shared wallet, so it is never chosen automatically as a refund destination."
},
"br_code": {
"type": [
"string",
"null"
],
"description": "PIX copy-and-paste payment string supplied with the quote, if any. brl_amount is the QR payment amount."
},
"merchant_name": {
"type": [
"string",
"null"
],
"description": "Recipient name read from the PIX payment QR."
},
"expires_at": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "Quote expiration timestamp in ISO 8601 UTC (for example, 2026-09-02T14:03:00Z). Acceptance after this time fails with erro=cotacao_expirada. Request a new quote instead of retrying acceptance."
},
"pix_e2e": {
"type": [
"string",
"null"
],
"description": "The completed PIX payment's Central Bank end-to-end identifier. Anyone can verify it at GET /v1/verificar/{e2e} without an API key. Return it to your end customer as the payment reference.",
"examples": [
"E37293930202607312006361894c4a82"
]
},
"pix_paid_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"receipt_url": {
"type": [
"string",
"null"
],
"description": "Shareable receipt page that opens on the end customer's phone.",
"examples": [
"https://app.luniumpay.com/comprovante/uwscff6ASNS1oUcH2LHbvw"
]
},
"receipt_pdf_url": {
"type": [
"string",
"null"
],
"nullable": true,
"format": "uri",
"description": "Receipt as a PDF file for support tickets, customer messages or accounting. Contains recipient name, tax ID, institution, amount, date, E2E and verification link. Generated from the same data as the receipt page. null until the order reaches the state that supplies it.",
"example": "https://app.luniumpay.com/comprovante/qigpnCTx3gM-Ge7hN27Mvw.pdf"
},
"verify_url": {
"type": [
"string",
"null"
],
"nullable": true,
"format": "uri",
"description": "Public verification link requiring no API key. Share it so the counterparty can check the payment independently. Does not expose the PIX key, full name or tax ID. null until the order reaches the state that supplies it.",
"example": "https://api.luniumpay.com/v1/verificar/E3729393020260731214021222ac6ff1"
},
"created_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"updated_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"timeline": {
"type": "array",
"description": "Timeline timestamped by the SERVER at each transition, rather than by your polling: AWAITING_DEPOSIT → DEPOSIT_DETECTED → DEPOSIT_CONFIRMED → (SELLING → SOLD → FORWARDING, exchange route only) → PAYING_OUT → COMPLETED. Use it in the customer's tracker.",
"items": {
"type": "object",
"properties": {
"state": {
"type": "string"
},
"at": {
"type": "string",
"format": "date-time"
}
}
}
},
"confirmations": {
"type": [
"integer",
"null"
],
"description": "Deposit confirmations observed live. Returned only while the order is confirming; not persisted and may change with each block. Display progress using this field and confirmations_required."
},
"confirmations_required": {
"type": [
"integer",
"null"
],
"description": "Number of confirmations the exchange requires before crediting a deposit on this network."
},
"failure_reason": {
"type": [
"string",
"null"
],
"description": "Failure reason when returned, including sandbox scenarios."
},
"sandbox": {
"type": "boolean",
"description": "True for fictitious sandbox operations."
},
"simulation": {
"type": "object",
"additionalProperties": true
}
}
}400 Invalid request or unavailable network.
JSON schema · 400
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}409 `external_id` was already used with different parameters.
422 Semantically invalid parameters.
JSON schema · 422
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}401 Missing, unknown or incorrect X-API-Key.
JSON schema · 401
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}POST /cash-outs/preview
Preview a quote without creating an order
Preview conversion in either direction (amount OR brl_amount) without an order or pix_key. Does not reserve funds, limits or an address. Creation and acceptance enforce additional checks, including br_code availability, recipient limits and the mandate. A successful preview does not guarantee order acceptance.
JSON body
| Field | Type | Required | Description |
|---|---|---|---|
asset | string | true | Asset to sell. Use the EXACT id from GET /catalog (for example, "usdt"). The (asset, network) pair must exist in that catalog. |
network | string | true | Incoming crypto network from GET /catalog. Do not confuse it with delivery networks from /cashin/catalog. |
amount | string | false | Crypto quantity as a decimal string ( |
brl_amount | string | false | REVERSE quote: desired PIX amount in BRL as a decimal string with up to two decimal places ( |
token_address | string | false | Exact token contract address or mint. Required for tokens from |
br_code | string | false | PIX copy-and-paste string for a CHARGE with a specified amount. Preview decodes the QR and returns amount, brl_amount (QR amount), merchant_name and the masked PIX key without creating an order. With br_code, omit amount and brl_amount. Same rules as POST /cash-outs: USDT or USDC on a catalog network. |
Request schema
{
"type": "object",
"required": [
"asset",
"network"
],
"properties": {
"asset": {
"type": "string",
"examples": [
"USDT"
],
"description": "Asset to sell. Use the EXACT id from GET /catalog (for example, \"usdt\"). The (asset, network) pair must exist in that catalog."
},
"network": {
"type": "string",
"description": "Incoming crypto network from GET /catalog. Do not confuse it with delivery networks from /cashin/catalog.",
"examples": [
"polygon"
]
},
"amount": {
"type": "string",
"description": "Crypto quantity as a decimal string (`\"50\"`), never a floating-point number. Supply exactly one of `amount` or `brl_amount`.",
"examples": [
"50"
]
},
"brl_amount": {
"type": "string",
"description": "REVERSE quote: desired PIX amount in BRL as a decimal string with up to two decimal places (`\"250.00\"`). Lunium calculates the crypto amount; the response's `amount` is what the customer must deposit. Supply exactly one of `amount` or `brl_amount`. Range: R$6.00–R$250,000.00 per transaction, also subject to the recipient's R$100,000.00 daily cap; the lower limit applies.",
"examples": [
"250.00"
]
},
"token_address": {
"type": "string",
"description": "Exact token contract address or mint. Required for tokens from `/catalog/dex`, where symbols may be shared by different tokens."
},
"br_code": {
"type": "string",
"description": "PIX copy-and-paste string for a CHARGE with a specified amount. Preview decodes the QR and returns amount, brl_amount (QR amount), merchant_name and the masked PIX key without creating an order. With br_code, omit amount and brl_amount. Same rules as POST /cash-outs: USDT or USDC on a catalog network."
}
}
}Responses
200 Preview calculated; no order created.
JSON schema · 200
{
"type": "object",
"properties": {
"preview": {
"type": "boolean",
"const": true
},
"asset": {
"type": "string"
},
"network": {
"type": "string"
},
"path": {
"type": "string",
"enum": [
"FAST",
"DEX",
"CONVERT",
"simulated"
],
"description": "Settlement route the sale would use."
},
"amount": {
"type": "string",
"description": "Crypto amount to send, as a decimal string."
},
"brl_amount": {
"type": "string",
"description": "PIX amount in BRL."
},
"expires_at": {
"type": "string",
"format": "date-time",
"description": "Expiration the quote would have."
},
"merchant_name": {
"type": [
"string",
"null"
],
"description": "With br_code only: charge recipient's name."
},
"pix_key": {
"type": [
"string",
"null"
],
"description": "With br_code only: masked recipient PIX key."
},
"pix_key_type": {
"type": [
"string",
"null"
]
}
},
"required": [
"preview",
"asset",
"network",
"amount",
"brl_amount"
]
}400 Invalid request or unavailable network.
JSON schema · 400
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}401 Missing, unknown or incorrect X-API-Key.
JSON schema · 401
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}422 Semantically invalid parameters.
JSON schema · 422
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}GET /cash-outs/{cashout_id}
Track the order (step 3 of 3)
Prefer webhooks. If polling, query every 10–15 seconds; once per second alone uses the key's 60-requests-per-minute allowance.
Official receipt. In COMPLETED the order carries pix_e2e, receipt_url, receipt_pdf_url and verify_url: the same PIX receipt in four forms, also delivered by webhook (cashout.completed and cashout.receipt_ready), in the partner dashboard and on Telegram. What it contains and how to hand it to your customer.
When state is COMPLETED, pix_e2e, pix_paid_at and receipt_url are populated.
Parameters
| Field | In | Required | Description |
|---|---|---|---|
cashout_id | path | true |
Responses
200 Current state.
JSON schema · 200
{
"type": "object",
"properties": {
"cashout_id": {
"type": "string",
"format": "uuid"
},
"state": {
"type": "string",
"enum": [
"QUOTE_CREATED",
"AWAITING_DEPOSIT",
"DEPOSIT_DETECTED",
"DEPOSIT_CONFIRMED",
"SELLING",
"SOLD",
"FORWARDING",
"PAYING_OUT",
"COMPLETED",
"MANUAL_REVIEW",
"REFUNDING_CRYPTO",
"REFUNDED",
"EXPIRED",
"FAILED",
"DELAYED",
"AWAITING_REFUND_ADDRESS",
"PROCESSING",
"REFUNDING"
],
"description": "Order state. COMPLETED confirms the PIX payment. Intermediate stages vary by settlement route. DELAYED belongs to a sandbox scenario. AWAITING_REFUND_ADDRESS: a refund is needed and the order has no return wallet; send it via POST /cash-outs/{cashout_id}/refund-address (crypto sales and, since 1.44.0, DePix sales). DePix sale: QUOTE_CREATED → AWAITING_DEPOSIT → DEPOSIT_DETECTED → PROCESSING → COMPLETED; if the Pix cannot be paid, REFUNDING → REFUNDED, or AWAITING_REFUND_ADDRESS when the wallet is missing. DePix already forwarded to the provider is refunded only after its return is confirmed: until then the order stays in MANUAL_REVIEW, and the refund is at most what came back."
},
"path": {
"type": [
"string",
"null"
],
"enum": [
"FAST",
"DEX",
"CONVERT",
null
],
"description": "FAST, DEX or CONVERT settlement route. Timing depends on the route, confirmations and processing."
},
"asset": {
"type": "string",
"examples": [
"USDT"
],
"description": "Asset to sell. Use the EXACT id from GET /catalog (for example, \"usdt\"). The (asset, network) pair must exist in that catalog."
},
"network": {
"type": "string",
"examples": [
"polygon"
],
"description": "Blockchain deposit network, as listed in the catalog (for example, \"polygon\"). The returned deposit address is valid only on this network."
},
"amount": {
"type": "string",
"description": "Crypto amount as a decimal string. Never use a floating-point number."
},
"brl_amount": {
"type": [
"string",
"null"
],
"description": "Amount in Brazilian reais (BRL) that the PIX recipient will receive."
},
"pix_key": {
"type": "string",
"description": "Destination PIX key: CPF, CNPJ, +55 phone number, email or random key. For 11 bare digits, also send pix_key_type (\"cpf\" or \"phone\"); otherwise the API returns erro=tipo_ambiguo instead of guessing."
},
"pix_key_type": {
"type": "string",
"enum": [
"cpf",
"cnpj",
"phone",
"email",
"random"
],
"description": "Usually omit it: the type is inferred from the key for e-mails, CNPJs, random keys and phones written with the +55 country code. Only required when the key is 11 bare digits, because a CPF and a phone number are the same length and guessing would pay the wrong person. An explicit type always wins over inference."
},
"deposit_address": {
"type": [
"string",
"null"
],
"description": "Address to which the customer sends crypto. Returned only after acceptance."
},
"deposit_tag": {
"type": [
"string",
"null"
],
"description": "Memo/tag that must accompany the deposit when returned by the accept operation. Use only networks listed in GET /catalog."
},
"external_id": {
"type": [
"string",
"null"
],
"description": "Idempotency identifier, up to 64 characters. Keep the identifier and every request parameter unchanged on retries. Conflict detection differs by route; do not use a replay to modify an operation. 409 external_id_divergente indicates a detected conflict.",
"maxLength": 64
},
"refund_address": {
"type": [
"string",
"null"
],
"description": "Return wallet supplied by the customer, at creation or via POST /cash-outs/{cashout_id}/refund-address: the destination of any refund. null means no wallet was supplied; Lunium never uses deposit_from in its place — if a refund is needed, the order waits in AWAITING_REFUND_ADDRESS. Also applies to DePix sales (Liquid lq1… address) since 1.44.0."
},
"refund_tx_hash": {
"type": [
"string",
"null"
],
"description": "Refund transaction hash when completed. Its presence does not imply a fixed refund amount or time for all cases."
},
"deposit_from": {
"type": [
"string",
"null"
],
"description": "Address that SENT the deposit, read on-chain; informational only. It may be an exchange's shared wallet, so it is never chosen automatically as a refund destination."
},
"br_code": {
"type": [
"string",
"null"
],
"description": "PIX copy-and-paste payment string supplied with the quote, if any. brl_amount is the QR payment amount."
},
"merchant_name": {
"type": [
"string",
"null"
],
"description": "Recipient name read from the PIX payment QR."
},
"expires_at": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "Quote expiration timestamp in ISO 8601 UTC (for example, 2026-09-02T14:03:00Z). Acceptance after this time fails with erro=cotacao_expirada. Request a new quote instead of retrying acceptance."
},
"pix_e2e": {
"type": [
"string",
"null"
],
"description": "The completed PIX payment's Central Bank end-to-end identifier. Anyone can verify it at GET /v1/verificar/{e2e} without an API key. Return it to your end customer as the payment reference.",
"examples": [
"E37293930202607312006361894c4a82"
]
},
"pix_paid_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"receipt_url": {
"type": [
"string",
"null"
],
"description": "Shareable receipt page that opens on the end customer's phone.",
"examples": [
"https://app.luniumpay.com/comprovante/uwscff6ASNS1oUcH2LHbvw"
]
},
"receipt_pdf_url": {
"type": [
"string",
"null"
],
"nullable": true,
"format": "uri",
"description": "Receipt as a PDF file for support tickets, customer messages or accounting. Contains recipient name, tax ID, institution, amount, date, E2E and verification link. Generated from the same data as the receipt page. null until the order reaches the state that supplies it.",
"example": "https://app.luniumpay.com/comprovante/qigpnCTx3gM-Ge7hN27Mvw.pdf"
},
"verify_url": {
"type": [
"string",
"null"
],
"nullable": true,
"format": "uri",
"description": "Public verification link requiring no API key. Share it so the counterparty can check the payment independently. Does not expose the PIX key, full name or tax ID. null until the order reaches the state that supplies it.",
"example": "https://api.luniumpay.com/v1/verificar/E3729393020260731214021222ac6ff1"
},
"created_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"updated_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"timeline": {
"type": "array",
"description": "Timeline timestamped by the SERVER at each transition, rather than by your polling: AWAITING_DEPOSIT → DEPOSIT_DETECTED → DEPOSIT_CONFIRMED → (SELLING → SOLD → FORWARDING, exchange route only) → PAYING_OUT → COMPLETED. Use it in the customer's tracker.",
"items": {
"type": "object",
"properties": {
"state": {
"type": "string"
},
"at": {
"type": "string",
"format": "date-time"
}
}
}
},
"confirmations": {
"type": [
"integer",
"null"
],
"description": "Deposit confirmations observed live. Returned only while the order is confirming; not persisted and may change with each block. Display progress using this field and confirmations_required."
},
"confirmations_required": {
"type": [
"integer",
"null"
],
"description": "Number of confirmations the exchange requires before crediting a deposit on this network."
},
"failure_reason": {
"type": [
"string",
"null"
],
"description": "Failure reason when returned, including sandbox scenarios."
},
"sandbox": {
"type": "boolean",
"description": "True for fictitious sandbox operations."
},
"simulation": {
"type": "object",
"additionalProperties": true
}
}
}401 Missing, unknown or incorrect X-API-Key.
JSON schema · 401
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}POST /cash-outs/{cashout_id}/accept
Accept the quote and obtain a deposit address (step 2 of 3)
Lock the quote and receive deposit_address. Send EXACTLY the quoted crypto amount.
If the network requires a memo/tag, acceptance returns deposit_tag. Omitting it may prevent the deposit from being credited.
Parameters
| Field | In | Required | Description |
|---|---|---|---|
cashout_id | path | true |
Responses
200 Deposit address.
JSON schema · 200
{
"type": "object",
"properties": {
"cashout_id": {
"type": "string",
"format": "uuid"
},
"state": {
"type": "string",
"enum": [
"QUOTE_CREATED",
"AWAITING_DEPOSIT",
"DEPOSIT_DETECTED",
"DEPOSIT_CONFIRMED",
"SELLING",
"SOLD",
"FORWARDING",
"PAYING_OUT",
"COMPLETED",
"MANUAL_REVIEW",
"REFUNDING_CRYPTO",
"REFUNDED",
"EXPIRED",
"FAILED",
"DELAYED",
"AWAITING_REFUND_ADDRESS",
"PROCESSING",
"REFUNDING"
],
"description": "Order state. COMPLETED confirms the PIX payment. Intermediate stages vary by settlement route. DELAYED belongs to a sandbox scenario. AWAITING_REFUND_ADDRESS: a refund is needed and the order has no return wallet; send it via POST /cash-outs/{cashout_id}/refund-address (crypto sales and, since 1.44.0, DePix sales). DePix sale: QUOTE_CREATED → AWAITING_DEPOSIT → DEPOSIT_DETECTED → PROCESSING → COMPLETED; if the Pix cannot be paid, REFUNDING → REFUNDED, or AWAITING_REFUND_ADDRESS when the wallet is missing. DePix already forwarded to the provider is refunded only after its return is confirmed: until then the order stays in MANUAL_REVIEW, and the refund is at most what came back."
},
"path": {
"type": [
"string",
"null"
],
"enum": [
"FAST",
"DEX",
"CONVERT",
null
],
"description": "FAST, DEX or CONVERT settlement route. Timing depends on the route, confirmations and processing."
},
"asset": {
"type": "string",
"examples": [
"USDT"
],
"description": "Asset to sell. Use the EXACT id from GET /catalog (for example, \"usdt\"). The (asset, network) pair must exist in that catalog."
},
"network": {
"type": "string",
"examples": [
"polygon"
],
"description": "Blockchain deposit network, as listed in the catalog (for example, \"polygon\"). The returned deposit address is valid only on this network."
},
"amount": {
"type": "string",
"description": "Crypto amount as a decimal string. Never use a floating-point number."
},
"brl_amount": {
"type": [
"string",
"null"
],
"description": "Amount in Brazilian reais (BRL) that the PIX recipient will receive."
},
"pix_key": {
"type": "string",
"description": "Destination PIX key: CPF, CNPJ, +55 phone number, email or random key. For 11 bare digits, also send pix_key_type (\"cpf\" or \"phone\"); otherwise the API returns erro=tipo_ambiguo instead of guessing."
},
"pix_key_type": {
"type": "string",
"enum": [
"cpf",
"cnpj",
"phone",
"email",
"random"
],
"description": "Usually omit it: the type is inferred from the key for e-mails, CNPJs, random keys and phones written with the +55 country code. Only required when the key is 11 bare digits, because a CPF and a phone number are the same length and guessing would pay the wrong person. An explicit type always wins over inference."
},
"deposit_address": {
"type": [
"string",
"null"
],
"description": "Address to which the customer sends crypto. Returned only after acceptance."
},
"deposit_tag": {
"type": [
"string",
"null"
],
"description": "Memo/tag that must accompany the deposit when returned by the accept operation. Use only networks listed in GET /catalog."
},
"external_id": {
"type": [
"string",
"null"
],
"description": "Idempotency identifier, up to 64 characters. Keep the identifier and every request parameter unchanged on retries. Conflict detection differs by route; do not use a replay to modify an operation. 409 external_id_divergente indicates a detected conflict.",
"maxLength": 64
},
"refund_address": {
"type": [
"string",
"null"
],
"description": "Return wallet supplied by the customer, at creation or via POST /cash-outs/{cashout_id}/refund-address: the destination of any refund. null means no wallet was supplied; Lunium never uses deposit_from in its place — if a refund is needed, the order waits in AWAITING_REFUND_ADDRESS. Also applies to DePix sales (Liquid lq1… address) since 1.44.0."
},
"refund_tx_hash": {
"type": [
"string",
"null"
],
"description": "Refund transaction hash when completed. Its presence does not imply a fixed refund amount or time for all cases."
},
"deposit_from": {
"type": [
"string",
"null"
],
"description": "Address that SENT the deposit, read on-chain; informational only. It may be an exchange's shared wallet, so it is never chosen automatically as a refund destination."
},
"br_code": {
"type": [
"string",
"null"
],
"description": "PIX copy-and-paste payment string supplied with the quote, if any. brl_amount is the QR payment amount."
},
"merchant_name": {
"type": [
"string",
"null"
],
"description": "Recipient name read from the PIX payment QR."
},
"expires_at": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "Quote expiration timestamp in ISO 8601 UTC (for example, 2026-09-02T14:03:00Z). Acceptance after this time fails with erro=cotacao_expirada. Request a new quote instead of retrying acceptance."
},
"pix_e2e": {
"type": [
"string",
"null"
],
"description": "The completed PIX payment's Central Bank end-to-end identifier. Anyone can verify it at GET /v1/verificar/{e2e} without an API key. Return it to your end customer as the payment reference.",
"examples": [
"E37293930202607312006361894c4a82"
]
},
"pix_paid_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"receipt_url": {
"type": [
"string",
"null"
],
"description": "Shareable receipt page that opens on the end customer's phone.",
"examples": [
"https://app.luniumpay.com/comprovante/uwscff6ASNS1oUcH2LHbvw"
]
},
"receipt_pdf_url": {
"type": [
"string",
"null"
],
"nullable": true,
"format": "uri",
"description": "Receipt as a PDF file for support tickets, customer messages or accounting. Contains recipient name, tax ID, institution, amount, date, E2E and verification link. Generated from the same data as the receipt page. null until the order reaches the state that supplies it.",
"example": "https://app.luniumpay.com/comprovante/qigpnCTx3gM-Ge7hN27Mvw.pdf"
},
"verify_url": {
"type": [
"string",
"null"
],
"nullable": true,
"format": "uri",
"description": "Public verification link requiring no API key. Share it so the counterparty can check the payment independently. Does not expose the PIX key, full name or tax ID. null until the order reaches the state that supplies it.",
"example": "https://api.luniumpay.com/v1/verificar/E3729393020260731214021222ac6ff1"
},
"created_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"updated_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"timeline": {
"type": "array",
"description": "Timeline timestamped by the SERVER at each transition, rather than by your polling: AWAITING_DEPOSIT → DEPOSIT_DETECTED → DEPOSIT_CONFIRMED → (SELLING → SOLD → FORWARDING, exchange route only) → PAYING_OUT → COMPLETED. Use it in the customer's tracker.",
"items": {
"type": "object",
"properties": {
"state": {
"type": "string"
},
"at": {
"type": "string",
"format": "date-time"
}
}
}
},
"confirmations": {
"type": [
"integer",
"null"
],
"description": "Deposit confirmations observed live. Returned only while the order is confirming; not persisted and may change with each block. Display progress using this field and confirmations_required."
},
"confirmations_required": {
"type": [
"integer",
"null"
],
"description": "Number of confirmations the exchange requires before crediting a deposit on this network."
},
"failure_reason": {
"type": [
"string",
"null"
],
"description": "Failure reason when returned, including sandbox scenarios."
},
"sandbox": {
"type": "boolean",
"description": "True for fictitious sandbox operations."
},
"simulation": {
"type": "object",
"additionalProperties": true
}
}
}404 Order not found.
422 Quote expired or already accepted.
401 Missing, unknown or incorrect X-API-Key.
JSON schema · 401
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}POST /cash-outs/{cashout_id}/refund-address
Send the confirmed wallet for a pending refund
Use it when the order is in AWAITING_REFUND_ADDRESS (refund_address_required: true, webhook cashout.awaiting_refund_address): the sale needed a refund and the order had no return wallet. Send YOUR customer's wallet on the refund network (the order's refund_network and refund_asset). Lunium never refunds to the deposit's on-chain source (deposit_from), and a registered wallet is never replaced.
DePix sale (asset DEPIX, network liquid), since 1.44.0: send a Liquid address (lq1…) of your customer. Repeating the same address returns 200 with the order; a different address returns 409 refund_address_imutavel; an address that belongs to Lunium (the deposit address of this or another sale, or a house wallet) is rejected with 400 refund_address_invalida. If all of the DePix was with Lunium (or the provider's return has already been confirmed), the order moves to REFUNDING (webhook cashout.refunding) and the refund is sent automatically, for refund_amount: REFUNDED with refund_tx_hash (webhook cashout.refunded). If the DePix had already been forwarded to the provider and its return is not confirmed yet, the order moves to MANUAL_REVIEW (webhook cashout.under_review): the refund happens only after that confirmation, and it is at most what came back. The wallet is requested only when the sale fails: outside AWAITING_REFUND_ADDRESS, an order without a wallet returns 409 devolucao_indisponivel.
Parameters
| Field | In | Required | Description |
|---|---|---|---|
cashout_id | path | true |
JSON body
| Field | Type | Required | Description |
|---|---|---|---|
refund_address | string | true | Address confirmed by the customer on the refund network returned by the order. Never infer it from deposit_from. DePix sale: your customer's Liquid address (lq1…). |
Request schema
{
"type": "object",
"required": [
"refund_address"
],
"properties": {
"refund_address": {
"type": "string",
"description": "Address confirmed by the customer on the refund network returned by the order. Never infer it from deposit_from. DePix sale: your customer's Liquid address (lq1…)."
}
}
}Responses
200 Updated order; track it until REFUNDED and refund_tx_hash. DePix sale: state comes back as REFUNDING (DePix with Lunium) or MANUAL_REVIEW (DePix with the provider, awaiting its return).
JSON schema · 200
{
"type": "object",
"properties": {
"cashout_id": {
"type": "string",
"format": "uuid"
},
"state": {
"type": "string",
"enum": [
"QUOTE_CREATED",
"AWAITING_DEPOSIT",
"DEPOSIT_DETECTED",
"DEPOSIT_CONFIRMED",
"SELLING",
"SOLD",
"FORWARDING",
"PAYING_OUT",
"COMPLETED",
"MANUAL_REVIEW",
"REFUNDING_CRYPTO",
"REFUNDED",
"EXPIRED",
"FAILED",
"DELAYED",
"AWAITING_REFUND_ADDRESS",
"PROCESSING",
"REFUNDING"
],
"description": "Order state. COMPLETED confirms the PIX payment. Intermediate stages vary by settlement route. DELAYED belongs to a sandbox scenario. AWAITING_REFUND_ADDRESS: a refund is needed and the order has no return wallet; send it via POST /cash-outs/{cashout_id}/refund-address (crypto sales and, since 1.44.0, DePix sales). DePix sale: QUOTE_CREATED → AWAITING_DEPOSIT → DEPOSIT_DETECTED → PROCESSING → COMPLETED; if the Pix cannot be paid, REFUNDING → REFUNDED, or AWAITING_REFUND_ADDRESS when the wallet is missing. DePix already forwarded to the provider is refunded only after its return is confirmed: until then the order stays in MANUAL_REVIEW, and the refund is at most what came back."
},
"path": {
"type": [
"string",
"null"
],
"enum": [
"FAST",
"DEX",
"CONVERT",
null
],
"description": "FAST, DEX or CONVERT settlement route. Timing depends on the route, confirmations and processing."
},
"asset": {
"type": "string",
"examples": [
"USDT"
],
"description": "Asset to sell. Use the EXACT id from GET /catalog (for example, \"usdt\"). The (asset, network) pair must exist in that catalog."
},
"network": {
"type": "string",
"examples": [
"polygon"
],
"description": "Blockchain deposit network, as listed in the catalog (for example, \"polygon\"). The returned deposit address is valid only on this network."
},
"amount": {
"type": "string",
"description": "Crypto amount as a decimal string. Never use a floating-point number."
},
"brl_amount": {
"type": [
"string",
"null"
],
"description": "Amount in Brazilian reais (BRL) that the PIX recipient will receive."
},
"pix_key": {
"type": "string",
"description": "Destination PIX key: CPF, CNPJ, +55 phone number, email or random key. For 11 bare digits, also send pix_key_type (\"cpf\" or \"phone\"); otherwise the API returns erro=tipo_ambiguo instead of guessing."
},
"pix_key_type": {
"type": "string",
"enum": [
"cpf",
"cnpj",
"phone",
"email",
"random"
],
"description": "Usually omit it: the type is inferred from the key for e-mails, CNPJs, random keys and phones written with the +55 country code. Only required when the key is 11 bare digits, because a CPF and a phone number are the same length and guessing would pay the wrong person. An explicit type always wins over inference."
},
"deposit_address": {
"type": [
"string",
"null"
],
"description": "Address to which the customer sends crypto. Returned only after acceptance."
},
"deposit_tag": {
"type": [
"string",
"null"
],
"description": "Memo/tag that must accompany the deposit when returned by the accept operation. Use only networks listed in GET /catalog."
},
"external_id": {
"type": [
"string",
"null"
],
"description": "Idempotency identifier, up to 64 characters. Keep the identifier and every request parameter unchanged on retries. Conflict detection differs by route; do not use a replay to modify an operation. 409 external_id_divergente indicates a detected conflict.",
"maxLength": 64
},
"refund_address": {
"type": [
"string",
"null"
],
"description": "Return wallet supplied by the customer, at creation or via POST /cash-outs/{cashout_id}/refund-address: the destination of any refund. null means no wallet was supplied; Lunium never uses deposit_from in its place — if a refund is needed, the order waits in AWAITING_REFUND_ADDRESS. Also applies to DePix sales (Liquid lq1… address) since 1.44.0."
},
"refund_tx_hash": {
"type": [
"string",
"null"
],
"description": "Refund transaction hash when completed. Its presence does not imply a fixed refund amount or time for all cases."
},
"deposit_from": {
"type": [
"string",
"null"
],
"description": "Address that SENT the deposit, read on-chain; informational only. It may be an exchange's shared wallet, so it is never chosen automatically as a refund destination."
},
"br_code": {
"type": [
"string",
"null"
],
"description": "PIX copy-and-paste payment string supplied with the quote, if any. brl_amount is the QR payment amount."
},
"merchant_name": {
"type": [
"string",
"null"
],
"description": "Recipient name read from the PIX payment QR."
},
"copia_e_cola_buffer_usd": {
"type": [
"string",
"null"
],
"description": "Charges (br_code) only: BRL 1 reserve converted to USDT already included in amount. Guarantees the PIX at the exact QR amount; any unused part is kept by Lunium as a correction reserve and is not refunded.",
"examples": [
"1.00"
]
},
"expires_at": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "Quote expiration timestamp in ISO 8601 UTC (for example, 2026-09-02T14:03:00Z). Acceptance after this time fails with erro=cotacao_expirada. Request a new quote instead of retrying acceptance."
},
"pix_e2e": {
"type": [
"string",
"null"
],
"description": "The completed PIX payment's Central Bank end-to-end identifier. Anyone can verify it at GET /v1/verificar/{e2e} without an API key. Return it to your end customer as the payment reference.",
"examples": [
"E37293930202607312006361894c4a82"
]
},
"pix_paid_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"receipt_url": {
"type": [
"string",
"null"
],
"description": "Shareable receipt page that opens on the end customer's phone.",
"examples": [
"https://app.luniumpay.com/comprovante/uwscff6ASNS1oUcH2LHbvw"
]
},
"receipt_pdf_url": {
"type": [
"string",
"null"
],
"nullable": true,
"format": "uri",
"description": "Receipt as a PDF file for support tickets, customer messages or accounting. Contains recipient name, tax ID, institution, amount, date, E2E and verification link. Generated from the same data as the receipt page. null until the order reaches the state that supplies it.\n\nOfficial receipt — what it contains and where it arrives (API, webhook, partner dashboard, Telegram): https://docs.luniumpay.com/en/manual#comprovante",
"example": "https://app.luniumpay.com/comprovante/qigpnCTx3gM-Ge7hN27Mvw.pdf"
},
"verify_url": {
"type": [
"string",
"null"
],
"nullable": true,
"format": "uri",
"description": "Public verification link requiring no API key. Share it so the counterparty can check the payment independently. Does not expose the PIX key, full name or tax ID. null until the order reaches the state that supplies it.",
"example": "https://api.luniumpay.com/v1/verificar/E3729393020260731214021222ac6ff1"
},
"created_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"updated_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"timeline": {
"type": "array",
"description": "Timeline timestamped by the SERVER at each transition, rather than by your polling: AWAITING_DEPOSIT → DEPOSIT_DETECTED → DEPOSIT_CONFIRMED → (SELLING → SOLD → FORWARDING, exchange route only) → PAYING_OUT → COMPLETED. Use it in the customer's tracker.",
"items": {
"type": "object",
"properties": {
"state": {
"type": "string"
},
"at": {
"type": "string",
"format": "date-time"
}
}
}
},
"confirmations": {
"type": [
"integer",
"null"
],
"description": "Deposit confirmations observed live. Returned only while the order is confirming; not persisted and may change with each block. Display progress using this field and confirmations_required."
},
"confirmations_required": {
"type": [
"integer",
"null"
],
"description": "Number of confirmations the exchange requires before crediting a deposit on this network."
},
"failure_reason": {
"type": [
"string",
"null"
],
"description": "Failure reason when returned, including sandbox scenarios."
},
"sandbox": {
"type": "boolean",
"description": "True for fictitious sandbox operations."
},
"simulation": {
"type": "object",
"additionalProperties": true
},
"partner_fee_bps": {
"type": "integer",
"nullable": true,
"description": "Partner sub fee frozen on this sale (bps); null on orders predating the field or DePix sales."
},
"partner_fee_brl_cents": {
"type": "integer",
"nullable": true,
"description": "Partner share in cents, closed on PIX confirmation; the amount credited to the commission ledger."
},
"refund_address_required": {
"type": "boolean",
"description": "true in AWAITING_REFUND_ADDRESS: read the refund details and send a wallet confirmed by the customer via POST /cash-outs/{cashout_id}/refund-address."
},
"refund_amount": {
"type": [
"string",
"null"
],
"description": "Actual amount to refund, once determined; do not assume the original amount. DePix sale: when all of the DePix is with Lunium, refund_amount, refund_asset (DEPIX) and refund_network (liquid) are already filled in AWAITING_REFUND_ADDRESS. If the DePix had already been forwarded to the provider, these fields stay null in MANUAL_REVIEW until the return is confirmed; afterwards refund_amount is at most what came back (plus the part that was never forwarded, up to the order amount)."
},
"refund_asset": {
"type": [
"string",
"null"
],
"description": "Actual refund asset; it may differ from the deposited asset."
},
"refund_network": {
"type": [
"string",
"null"
],
"description": "Actual refund network; use a compatible wallet confirmed by the customer."
},
"provider_return_txid": {
"type": [
"string",
"null"
],
"description": "Reference of the settlement provider's return to Lunium; it is not proof of a refund to the customer."
}
}
}400 Missing address, invalid for the network, or belonging to Lunium (refund_address_invalida; on crypto sales, a rejection made while processing the refund may carry another code, with the reason in detail).
JSON schema · 400
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_invalido",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"carteira_indisponivel",
"carteira_nao_liberada",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"chave_obrigatoria",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_divergente",
"cotacao_expirada",
"cotacao_indisponivel",
"cotacao_recusada",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"devolucao_indisponivel",
"documento_invalido",
"em_processamento",
"email_invalido",
"email_obrigatorio",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"funding_source_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"muitos_pedidos_abertos",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"outcome_invalido",
"pagador_bloqueado",
"pagador_recusado_pelo_provedor",
"pagamentos_indisponiveis",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_imutavel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}401 Missing, unknown or incorrect X-API-Key.
JSON schema · 401
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_invalido",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"carteira_indisponivel",
"carteira_nao_liberada",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"chave_obrigatoria",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_divergente",
"cotacao_expirada",
"cotacao_indisponivel",
"cotacao_recusada",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"devolucao_indisponivel",
"documento_invalido",
"em_processamento",
"email_invalido",
"email_obrigatorio",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"funding_source_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"muitos_pedidos_abertos",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"outcome_invalido",
"pagador_bloqueado",
"pagador_recusado_pelo_provedor",
"pagamentos_indisponiveis",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_imutavel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}404 Order not found or owned by another key.
JSON schema · 404
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_invalido",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"carteira_indisponivel",
"carteira_nao_liberada",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"chave_obrigatoria",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_divergente",
"cotacao_expirada",
"cotacao_indisponivel",
"cotacao_recusada",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"devolucao_indisponivel",
"documento_invalido",
"em_processamento",
"email_invalido",
"email_obrigatorio",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"funding_source_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"muitos_pedidos_abertos",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"outcome_invalido",
"pagador_bloqueado",
"pagador_recusado_pelo_provedor",
"pagamentos_indisponiveis",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_imutavel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}409 Incompatible state or wallet already registered. DePix sale: refund_address_imutavel (acao parar) when the order already has a different wallet; devolucao_indisponivel (acao esperar) when the order is not waiting for a wallet — it is requested only when the sale fails. Crypto sale: the reason is in detail.
JSON schema · 409
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_invalido",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"carteira_indisponivel",
"carteira_nao_liberada",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"chave_obrigatoria",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_divergente",
"cotacao_expirada",
"cotacao_indisponivel",
"cotacao_recusada",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"devolucao_indisponivel",
"documento_invalido",
"em_processamento",
"email_invalido",
"email_obrigatorio",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"funding_source_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"muitos_pedidos_abertos",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"outcome_invalido",
"pagador_bloqueado",
"pagador_recusado_pelo_provedor",
"pagamentos_indisponiveis",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_imutavel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}GET /cashin/catalog
Cash-in delivery catalog for incoming PIX payments
Crypto delivery catalog for direct cash-in and custody withdrawals. Offer only items with entregavel=true from instant/convert; instant may be empty. Read memoRequired, withdrawFee, withdrawMin and estimates for each route. The BRL minimum depends on the quote from POST /cashin/preview. Exclude Liquid/DePix for custody withdrawals. stale=true indicates cached catalog data.
Responses
200 Crypto purchase catalog.
JSON schema · 200
{
"type": "object",
"description": "Cash-in catalog: assets we can deliver after receiving PIX.",
"properties": {
"updatedAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"instant": {
"type": "array",
"description": "House-funded delivery routes; may be empty depending on configuration. Do not assume availability or fixed timing.",
"items": {
"type": "object",
"properties": {
"asset": {
"type": "string"
},
"network": {
"type": "string"
},
"eta": {
"type": "string"
},
"entregavel": {
"type": "boolean"
}
}
}
},
"convert": {
"type": "array",
"description": "Exchange route: one entry per (asset, network) pair.",
"items": {
"type": "object",
"properties": {
"asset": {
"type": "string"
},
"network": {
"type": "string"
},
"etaSeconds": {
"type": "integer"
},
"eta": {
"type": "string"
},
"fastest": {
"type": "boolean"
},
"withdrawFee": {
"type": "string"
},
"withdrawMin": {
"type": "string"
},
"withdrawMax": {
"type": "string"
},
"minBuyAmount": {
"type": "string",
"description": "Minimum quantity TO BUY in asset units to cover withdrawMin + withdrawFee on the exchange route; not necessarily net delivery. Read min_brl_cents from POST /cashin/preview using your own key; fees and rates affect the BRL floor."
},
"precision": {
"type": "integer"
},
"memoRequired": {
"type": "boolean",
"description": "Shared-address network: payout_tag is required."
},
"entregavel": {
"type": "boolean"
}
}
}
},
"dropped": {
"type": "array",
"description": "Unavailable pairs and reasons, for example sem_par_usdt.",
"items": {
"type": "object",
"properties": {
"asset": {
"type": "string"
},
"network": {
"type": "string"
},
"motivo": {
"type": "string"
}
}
}
},
"totals": {
"type": "object",
"additionalProperties": true
},
"stale": {
"type": "boolean",
"description": "true if the catalog was served from a fallback cache."
}
}
}401 Missing, unknown or incorrect X-API-Key.
JSON schema · 401
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}POST /cashin/charge
Create a PIX charge for BRL custody or direct crypto delivery
Create a PIX charge for BRL custody (destino=saldo, no wallet required) or direct crypto delivery (destino=cripto, the default). Supply the payer's tax ID. Check GET /cashin/limits and key-specific conditions. Fees, limits and the provider determine the effective minimum; creation revalidates them. Holds may apply at the provider (held_hours/delay_until) or locally (hold_hours/liberar_em). A paid PIX does not prove completed delivery or credit: track settlement_status and the statement. Sandbox creates a non-payable QR; confirm it with POST /sandbox/cashin/{cashin_id}/pay. No bank transaction occurs.
JSON body
| Field | Type | Required | Description |
|---|---|---|---|
amount_cents | integer | true | Charge amount as integer BRL CENTS (for example, 15000 = R$150.00). Read GET /cashin/limits before creation for the payer's current no-hold and held-payment bands. |
chain | string | false | Delivery route network. Supply the catalog's network value in this chain field. Default: |
asset | string | false | Deliverable asset from GET /cashin/catalog; not limited to stablecoins. Default: |
payout_address | string | false | Per-charge wallet for destino=cripto. If omitted, the key's settlement_address may be used. Omit for destino=saldo. The address must match the selected network. |
payer_tax_number | string | true | Payer's CPF (11 digits) or CNPJ (14 digits), digits only. Identifies the payer for anti-fraud limits and holds published by GET /cashin/limits. |
external_id | string | false | Idempotency identifier, up to 64 characters. Keep the identifier and every request parameter unchanged on retries. Conflict detection differs by route; do not use a replay to modify an operation. 409 external_id_divergente indicates a detected conflict. |
destino | string | false | saldo credits BRL custody net of fees without requiring a wallet. cripto (default) delivers to the supplied or configured wallet. Read fees and waiting periods in GET /saldo, and holds in the charge/status response. Values: Default: |
customer_ref | string | false | Optional sub-account of the balance (your end customer id). With |
allow_hold | boolean | false | false rejects the charge when payer rules require a hold. It does not remove other key holds or freezes. true or omission allows the applicable hold. Read both held_hours AND hold_hours/liberar_em. Default: |
payout_tag | string | false | Destination memo/tag. REQUIRED on shared-address networks such as XRP, XLM, TON, ATOM, HBAR, ALGO, EOS, KAVA and LUNA, where it identifies the recipient. If missing or invalid, the API returns 400 |
payer_name | string | false | Payer's name, when supplied. |
sandbox_scenario | string | false | Only for a sandbox key. GET /sandbox provides the scenario matrix by flow. Omit in production. All prices, payments and withdrawals remain fictitious. Values: |
Request schema
{
"type": "object",
"required": [
"amount_cents",
"payer_tax_number"
],
"properties": {
"amount_cents": {
"type": "integer",
"description": "Charge amount as integer BRL CENTS (for example, 15000 = R$150.00). Read GET /cashin/limits before creation for the payer's current no-hold and held-payment bands.",
"examples": [
25000
]
},
"chain": {
"type": "string",
"default": "polygon",
"description": "Delivery route network. Supply the catalog's network value in this chain field."
},
"asset": {
"type": "string",
"default": "usdt",
"description": "Deliverable asset from GET /cashin/catalog; not limited to stablecoins."
},
"payout_address": {
"type": "string",
"description": "Per-charge wallet for destino=cripto. If omitted, the key's settlement_address may be used. Omit for destino=saldo. The address must match the selected network."
},
"payer_tax_number": {
"type": "string",
"description": "Payer's CPF (11 digits) or CNPJ (14 digits), digits only. Identifies the payer for anti-fraud limits and holds published by GET /cashin/limits."
},
"external_id": {
"type": "string",
"description": "Idempotency identifier, up to 64 characters. Keep the identifier and every request parameter unchanged on retries. Conflict detection differs by route; do not use a replay to modify an operation. 409 external_id_divergente indicates a detected conflict.",
"maxLength": 64
},
"destino": {
"type": "string",
"enum": [
"cripto",
"saldo"
],
"default": "cripto",
"description": "saldo credits BRL custody net of fees without requiring a wallet. cripto (default) delivers to the supplied or configured wallet. Read fees and waiting periods in GET /saldo, and holds in the charge/status response."
},
"customer_ref": {
"type": "string",
"maxLength": 80,
"description": "Optional sub-account of the balance (your end customer id). With `destino: \"saldo\"`, the credit lands on this sub-account; GET /saldo?customer_ref= reads it and POST /payouts with the same `customer_ref` spends it. Omit to use the key's main balance."
},
"allow_hold": {
"type": "boolean",
"default": true,
"description": "false rejects the charge when payer rules require a hold. It does not remove other key holds or freezes. true or omission allows the applicable hold. Read both held_hours AND hold_hours/liberar_em."
},
"payout_tag": {
"type": "string",
"maxLength": 120,
"description": "Destination memo/tag. REQUIRED on shared-address networks such as XRP, XLM, TON, ATOM, HBAR, ALGO, EOS, KAVA and LUNA, where it identifies the recipient. If missing or invalid, the API returns 400 `memo_obrigatorio` before creating a charge. For XRP, the destination tag is an integer from 0 to 4294967295. Accepted aliases: `memo`, `tag`, `destination_tag`. The catalog marks these routes with `memoRequired: true`."
},
"payer_name": {
"type": "string",
"description": "Payer's name, when supplied."
},
"sandbox_scenario": {
"type": "string",
"enum": [
"success",
"delayed",
"held",
"expired",
"refunded",
"failed",
"payer_mismatch",
"settlement_failed",
"settlement_uncertain",
"route_unavailable",
"provider_unavailable"
],
"description": "Only for a sandbox key. GET /sandbox provides the scenario matrix by flow. Omit in production. All prices, payments and withdrawals remain fictitious."
}
}
}Responses
200 Charge created. Display qr_copypaste as the PIX payment code.
JSON schema · 200
{
"type": "object",
"description": "Charge creation response, including the QR. See StatusCobranca for status, list and webhook representations.",
"properties": {
"cashin_id": {
"type": "string",
"description": "Charge identifier (ci_…)."
},
"status": {
"type": "string",
"description": "PIX state. paid alone does not prove credit or delivery; also read settlement_status.",
"enum": [
"pending",
"delayed",
"under_review",
"paid",
"expired",
"refunded",
"failed"
]
},
"amount_cents": {
"type": "integer",
"description": "PIX amount in BRL cents."
},
"destino": {
"type": "string",
"description": "cripto delivers on-chain; saldo credits the key's BRL custody balance for use with POST /payouts and POST /saldo/sacar-cripto.",
"enum": [
"cripto",
"saldo"
]
},
"fonte": {
"type": "string",
"enum": [
"pix",
"saldo"
],
"description": "Funding source at creation: PIX or balance withdrawal."
},
"customer_ref": {
"type": [
"string",
"null"
],
"description": "Your end-customer reference, identifying a balance subaccount.",
"maxLength": 80
},
"payout_address": {
"type": [
"string",
"null"
],
"description": "Wallet receiving crypto when destino=cripto."
},
"payout_tag": {
"type": [
"string",
"null"
],
"description": "Destination wallet memo/tag on networks with shared addresses, for destino=cripto."
},
"chain": {
"type": "string",
"description": "Delivery network identifier from GET /cashin/catalog."
},
"asset": {
"type": "string",
"description": "Asset delivered (usdt, usdc, btc, …)."
},
"lunium_fee_bps": {
"type": "integer",
"description": "Percentage fee locked into the charge, in basis points."
},
"lunium_fee_fixed_cents": {
"type": "integer",
"description": "Fixed fee locked into the charge, in BRL cents."
},
"partner_fee_bps": {
"type": "integer",
"description": "Partner fee locked into the charge."
},
"qr_copypaste": {
"type": [
"string",
"null"
],
"description": "PIX copy-and-paste string at creation; null for a custody withdrawal."
},
"qr_image_url": {
"type": [
"string",
"null"
],
"description": "QR image (PNG), returned only in the creation response."
},
"external_id": {
"type": [
"string",
"null"
],
"description": "Idempotency identifier, up to 64 characters. Keep the identifier and every request parameter unchanged on retries. Conflict detection differs by route; do not use a replay to modify an operation. 409 external_id_divergente indicates a detected conflict.",
"maxLength": 64
},
"created_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"expires_at": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "Charge expiration timestamp. Read this value, including when validity has been extended by the bot."
},
"delay_until": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "Provider hold release timestamp, when available."
},
"liberar_em": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "When the balance credit becomes available after its waiting period. null when immediately available, the default since 2026-09-16."
},
"hold_hours": {
"type": "integer",
"description": "Local charge hold in hours. Not an alias of held_hours or the general balance waiting period."
},
"held_hours": {
"type": "integer",
"description": "Hold requested from the provider. May be zero even when a local hold exists (hold_hours/liberar_em)."
},
"held": {
"type": "boolean",
"description": "true when held_hours > 0. Does not indicate whether a local hold exists."
},
"sandbox": {
"type": "boolean",
"description": "True for fictitious sandbox operations."
},
"simulation": {
"type": "object",
"additionalProperties": true
},
"sandbox_payment": {
"type": "object",
"properties": {
"method": {
"const": "POST"
},
"path": {
"type": "string"
}
}
},
"timeline": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true
}
}
}
}403 Payer limit exceeded.
JSON schema · 403
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}400 Invalid parameters, amount outside the limits or cash-in disabled for this key. `valor_abaixo_do_minimo`: selected asset/network has a route-specific minimum; minimo_estimado_cents indicates an estimated starting amount, checked before funds are moved. `memo_obrigatorio`: required memo/tag missing or invalid.
JSON schema · 400
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}401 Missing, unknown or incorrect X-API-Key.
JSON schema · 401
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}502 No charge was created. Inspect the error code and action: `provedor_indisponivel` with `repetir` or `esperar` indicates a transient settlement-provider failure; retry the SAME request with the same external_id after waiting. `config_provedor` with `falar_com_suporte` indicates invalid provider configuration on our side, such as a PIX key, credential or account. Waiting or retrying does not resolve that error; contact support.
JSON schema · 502
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}503 catalogo_indisponivel / cotacao_indisponivel: an exchange quote is temporarily unavailable; retry.
JSON schema · 503
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}409 Conflicting external_id parameters.
GET /cashin/charges
List or recover cash-in charges for this key
Parameters
| Field | In | Required | Description |
|---|---|---|---|
external_id | query | false | Idempotent recovery: returns the operation with this external_id, if any (0 or 1). Unique per key and product, case-sensitive and retained permanently. |
status | query | false | |
start | query | false | |
end | query | false | |
limit | query | false |
Responses
200 List, newest first.
JSON schema · 200
{
"type": "object",
"properties": {
"charges": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Cobranca"
}
}
}
}401 Missing or invalid X-API-Key.
JSON schema · 401
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}403 Listing requires X-API-Key; it is not public.
JSON schema · 403
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}GET /cashin/events
Operational event feed for this key
Recent key events, newest first: charges, crypto sales, withdrawals and webhook deliveries. Same feed as the monitoring page; useful for an operational screen. Accepts X-API-Key or the key's monitor token.
Parameters
| Field | In | Required | Description |
|---|---|---|---|
limit | query | false | Number of events to return; default 60. |
Responses
200 Recent events.
JSON schema · 200
{
"type": "object",
"properties": {
"projeto": {
"type": "string",
"description": "Key name."
},
"agora": {
"type": "string",
"format": "date-time",
"description": "Server time, so the display clock does not depend on the client's clock."
},
"eventos": {
"type": "array",
"items": {
"type": "object",
"properties": {
"ts": {
"type": "string",
"format": "date-time"
},
"fluxo": {
"type": "string",
"description": "cashin · cashout · payout · webhook"
},
"provedor": {
"type": "string"
},
"ref": {
"type": "string",
"description": "Operation identifier."
},
"valor": {
"type": "string"
},
"estado": {
"type": "string"
},
"detalhe": {
"type": [
"string",
"null"
]
},
"tx": {
"type": [
"string",
"null"
]
}
}
}
}
}
}401 Missing, unknown or incorrect X-API-Key.
JSON schema · 401
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}GET /cashin/limits
How much this taxpayer can pay right now
Advisory CPF/CNPJ limits, usage and no-hold/held-payment bands. Creation revalidates key conditions, including custody without a waiting period. max_amount_cents does not replace fee minimums, route/provider constraints or contractual gates. Provider or local holds may apply; read held_hours, hold_hours and liberar_em in the charge response. Do not hardcode the ladder in your client.
Parameters
| Field | In | Required | Description |
|---|---|---|---|
payer_tax | query | true | CPF (11 digits) or CNPJ (14 digits), digits only. |
Responses
200 Current ladder state
JSON schema · 200
{
"type": "object",
"properties": {
"payer_tax": {
"type": "string",
"description": "Masked back to you, never in full."
},
"stage": {
"enum": [
"first_transaction",
"first_24h",
"mature",
"disabled",
"desconhecido"
]
},
"max_amount_cents": {
"type": "integer",
"description": "Advisory maximum for this tax ID, including possible holds. Creation revalidates the key, minimums and availability."
},
"used_cents": {
"type": "integer"
},
"available_cents": {
"type": [
"integer",
"null"
],
"description": "Amount still eligible for clearing without a hold at the current stage. Alias: instant_available_cents. null when the limit rule is disabled (stage=disabled)."
},
"limit_cents": {
"type": [
"integer",
"null"
],
"description": "null when the limit rule is disabled (stage=disabled)."
},
"next_stage": {
"type": [
"object",
"null"
],
"description": "When the ceiling rises and to what."
},
"instant_available_cents": {
"type": "integer",
"description": "Same as available_cents — what clears without a hold, spelled out."
},
"held_qr": {
"type": [
"object",
"null"
],
"description": "Held-payment band conditions, when applicable. Funds may be held by the provider or through a local charge hold. Read the creation/status response.",
"properties": {
"stage": {
"type": "string",
"enum": [
"held_qr"
]
},
"max_amount_cents": {
"type": "integer"
},
"used_cents": {
"type": "integer",
"description": "Paid + in-flight in the last 24h."
},
"available_cents": {
"type": "integer"
},
"hold_hours": {
"type": "integer"
},
"explicacao": {
"type": "string"
}
}
}
}
}400 Malformed document
JSON schema · 400
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}401 Missing, unknown or incorrect X-API-Key.
JSON schema · 401
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}POST /cashin/preview
Preview a cash-in conversion without creating a charge
Estimate PIX/BRL conversion for a delivery route. Does not create a QR or lock the exchange rate until payment. Read min_brl_cents and route-specific fields. This is not a complete custody withdrawal preview: the house withdrawal fee is additional.
JSON body
| Field | Type | Required | Description |
|---|---|---|---|
amount_cents | integer | true | BRL amount in integer cents. The effective minimum depends on the key, fees and route. Read GET /keys/me and returned min_brl_cents/limits; do not hardcode the example minimum. |
asset | string | false | Deliverable asset from GET /cashin/catalog; not limited to stablecoins. Default: |
chain | string | false | Delivery route network. Supply the catalog's network value in this chain field. Default: |
Request schema
{
"type": "object",
"required": [
"amount_cents"
],
"properties": {
"amount_cents": {
"type": "integer",
"minimum": 1,
"description": "BRL amount in integer cents. The effective minimum depends on the key, fees and route. Read GET /keys/me and returned min_brl_cents/limits; do not hardcode the example minimum."
},
"asset": {
"type": "string",
"default": "usdt",
"description": "Deliverable asset from GET /cashin/catalog; not limited to stablecoins."
},
"chain": {
"type": "string",
"default": "polygon",
"description": "Delivery route network. Supply the catalog's network value in this chain field."
}
}
}Responses
200 Quote with the key's fee applied.
JSON schema · 200
{
"oneOf": [
{
"type": "object",
"properties": {
"asset": {
"type": "string",
"description": "Settlement stablecoin, echoed from the request."
},
"amount_cents": {
"type": "integer",
"description": "Charge amount in cents, echoed from the request."
},
"admin_fee_bps": {
"type": "integer"
},
"admin_fee_fixed_cents": {
"type": "integer"
},
"fee_total_cents": {
"type": "integer",
"description": "ALL deductions from the gross amount: fixed fee + Lunium percentage fee + partner fee. Invariant: fee_total_cents + net_cents == amount_cents. Read lunium_fee_cents and partner_fee_cents for the allocation."
},
"net_cents": {
"type": "integer",
"description": "Net amount converted to crypto for the end customer, after any partner fee."
},
"brl_per_usdt": {
"type": "string",
"description": "Exchange rate rounded for display. Delivery uses the full-precision rate."
},
"usdt_amount": {
"type": "string",
"description": "Net delivered quantity, the source of truth."
},
"partner_fee_bps": {
"type": "integer",
"description": "Partner fee applied to this quote, in basis points. 0 means disabled."
},
"lunium_fee_cents": {
"type": "integer",
"description": "Lunium's share: fixed plus percentage fee. Equals fee_total_cents when there is no partner fee."
},
"partner_fee_cents": {
"type": "integer",
"description": "Partner's share, credited as commission when crypto is delivered. Calculated as the remainder after a single floor operation; adding the partner fee does not change Lunium's share."
},
"sandbox": {
"const": false
}
}
},
{
"type": "object",
"description": "Isolated sandbox quote using synthetic rates and route withdrawal fees without calling a provider. fee_bps and fee_fixed_cents are simulation fees, not a production quote.",
"required": [
"sandbox",
"synthetic",
"amount_cents",
"min_brl_cents",
"fee_bps",
"fee_fixed_cents",
"partner_fee_bps",
"asset",
"chain",
"usdt_amount",
"asset_amount",
"withdraw_fee",
"withdraw_min",
"brl_per_usdt",
"brl_per_asset"
],
"properties": {
"sandbox": {
"const": true
},
"synthetic": {
"const": true
},
"amount_cents": {
"type": "integer"
},
"min_brl_cents": {
"type": "integer"
},
"fee_bps": {
"type": "integer"
},
"fee_fixed_cents": {
"type": "integer"
},
"partner_fee_bps": {
"type": "integer"
},
"asset": {
"type": "string"
},
"chain": {
"type": "string"
},
"usdt_amount": {
"type": "string"
},
"asset_amount": {
"type": "string"
},
"withdraw_fee": {
"type": "string"
},
"withdraw_min": {
"type": "string"
},
"brl_per_usdt": {
"type": "number"
},
"brl_per_asset": {
"type": "number"
}
}
}
]
}400 Amount outside the key's limits or invalid parameters.
JSON schema · 400
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}401 Missing, unknown or incorrect X-API-Key.
JSON schema · 401
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}GET /cashin/{cashin_id}/status
State of a PIX charge
Track PIX payment and credit/delivery separately. paid alone does not prove crypto delivery or available balance. settlement_status=sent completes credit/delivery; for custody also check available and blocked balance. delayed represents a provider hold; paid with liberar_em may indicate a local hold. Do not request another payment because delivery is still pending. Prefer webhooks; polling must respect the key's rate limit.
Parameters
| Field | In | Required | Description |
|---|---|---|---|
cashin_id | path | true |
Responses
200 Current state with a server-timestamped timeline.
JSON schema · 200
{
"type": "object",
"description": "Charge status. GET may add trilho, timeline and tempos_tipicos; list and webhook responses use the base object.",
"properties": {
"cashin_id": {
"type": "string",
"description": "Charge identifier (ci_…)."
},
"status": {
"type": "string",
"description": "PIX state. paid alone does not prove credit or delivery; also read settlement_status.",
"enum": [
"pending",
"delayed",
"under_review",
"paid",
"expired",
"refunded",
"failed"
]
},
"settlement_status": {
"type": [
"string",
"null"
],
"description": "Credit/delivery state: sent means completed; incerto requires reconciliation. PIX payment and delivery are separate states.",
"enum": [
"pending",
"sending",
"entregando",
"sent",
"incerto",
"failed",
null
]
},
"amount_cents": {
"type": "integer",
"description": "PIX amount in BRL cents."
},
"depix_received_cents": {
"type": [
"integer",
"null"
],
"description": "Amount received from the settlement provider before deducting the key's deposit fees. This is not the net custody credit."
},
"usdt_amount": {
"type": [
"string",
"null"
],
"description": "Legacy amount field returned by settlement. Interpret it alongside asset and the route-specific fields."
},
"settlement_tx_hash": {
"type": [
"string",
"null"
],
"description": "On-chain delivery hash, or internal identifier when delivery uses an exchange."
},
"settlement_tx_url": {
"type": [
"string",
"null"
],
"description": "Block explorer link for that hash, when available."
},
"payout_address": {
"type": [
"string",
"null"
],
"description": "Wallet receiving crypto when destino=cripto."
},
"payout_tag": {
"type": [
"string",
"null"
],
"description": "Destination wallet memo/tag on networks with shared addresses, for destino=cripto."
},
"chain": {
"type": "string",
"description": "Delivery network identifier from GET /cashin/catalog."
},
"asset": {
"type": "string",
"description": "Asset delivered (usdt, usdc, btc, …)."
},
"payer_tax_number": {
"type": "string",
"description": "Payer's CPF/CNPJ: the person or business that must pay the QR. Payment from a different tax ID is refunded with refund_reason PAYER_MISMATCH."
},
"external_id": {
"type": [
"string",
"null"
],
"description": "Idempotency identifier, up to 64 characters. Keep the identifier and every request parameter unchanged on retries. Conflict detection differs by route; do not use a replay to modify an operation. 409 external_id_divergente indicates a detected conflict.",
"maxLength": 64
},
"expires_at": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "Charge expiration timestamp. Read this value, including when validity has been extended by the bot."
},
"paid_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"settled_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"destino": {
"type": "string",
"description": "cripto delivers on-chain; saldo credits the key's BRL custody balance for use with POST /payouts and POST /saldo/sacar-cripto.",
"enum": [
"cripto",
"saldo"
]
},
"held_hours": {
"type": "integer",
"description": "Hold requested from the provider. May be zero even when a local hold exists (hold_hours/liberar_em)."
},
"held": {
"type": "boolean",
"description": "true when held_hours > 0. Does not indicate whether a local hold exists."
},
"delay_until": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "Provider hold release timestamp, when available."
},
"liberar_em": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "When the balance credit becomes available after its waiting period. null when immediately available, the default since 2026-09-16."
},
"e2e": {
"type": [
"string",
"null"
],
"description": "Central Bank EndToEndId of the incoming PIX payment."
},
"payer_name": {
"type": [
"string",
"null"
],
"description": "Payer's name, when supplied or identified by the bank."
},
"customer_ref": {
"type": [
"string",
"null"
],
"description": "Your end-customer reference, identifying a balance subaccount.",
"maxLength": 80
},
"refund_reason": {
"type": [
"string",
"null"
],
"description": "Refund reason when status=refunded, for example PAYER_MISMATCH (different payer tax ID), TEST_AMOUNT (test amount) or PROVIDER_REJECTED."
},
"refund_reason_detail": {
"type": [
"string",
"null"
],
"description": "Human-readable refund explanation."
},
"created_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"trilho": {
"type": "string",
"description": "Operation route: casa, corretora, saldo or liquid. Not a timing guarantee."
},
"timeline": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true
}
},
"tempos_tipicos": {
"type": "object",
"description": "Measured median duration in seconds for each stage, grouped by route. Use it to display typical processing times.",
"additionalProperties": true
},
"sandbox": {
"type": "boolean",
"description": "True for fictitious sandbox operations."
},
"simulation": {
"type": "object",
"additionalProperties": true
}
}
}404 Not found
JSON schema · 404
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}401 Missing, unknown or incorrect X-API-Key.
JSON schema · 401
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}GET /catalog
Currently supported assets, networks and settlement limits
Incoming crypto catalog for cash-out. Use the currently returned pairs, minimums, maximums and estimates instead of hardcoding networks. fast, convert and dex represent different settlement routes. Availability differs from the delivery catalog at /cashin/catalog. If acceptance returns deposit_tag, include it with the deposit. stale=true indicates fallback data.
Responses
200 Current catalog.
JSON schema · 200
{
"type": "object",
"description": "Cash-out catalog for selling crypto.",
"properties": {
"updatedAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"fast": {
"type": "array",
"description": "Pairs available on the FAST route. Deposit and PIX timing depend on the operation; this is not a fixed SLA.",
"items": {
"type": "object",
"properties": {
"asset": {
"type": "string"
},
"network": {
"type": "string"
}
}
}
},
"dex": {
"type": "object",
"description": "Long-tail tokens via DEX: chains and notes.",
"additionalProperties": true
},
"convert": {
"type": "array",
"description": "Exchange route: one entry per asset with supported networks. Includes solana and tron (since 2026-09-06) and shared-address networks (XRP, XLM, ATOM, HBAR, KAVA, HIVE, STEEM, IOST), where acceptance returns deposit_tag.",
"items": {
"type": "object",
"properties": {
"asset": {
"type": "string"
},
"networks": {
"type": "array",
"items": {
"type": "string"
}
},
"min": {
"type": "string",
"description": "Minimum in units of THIS asset, for the networks listed in this item. Do not apply the 6 USDT/USDC floor to BTC, ETH or other assets. The operation BRL floor also applies."
},
"max": {
"type": "string"
},
"precision": {
"type": "integer"
},
"deposit_eta": {
"type": "array",
"description": "Expected wait AFTER sending crypto, by network. Display this on the crypto-selling screen. Derived from exchange deposit confirmation requirements, not our withdrawal time for crypto purchases. Sorted from fastest to slowest network.",
"items": {
"type": "object",
"properties": {
"network": {
"type": "string"
},
"confirmations": {
"type": "integer",
"description": "Confirmations required by the exchange, for example 1,000 on Base, 5,000 on Arbitrum and 61 on BSC."
},
"eta_seconds": {
"type": "integer",
"description": "Estimated seconds: required confirmations × network block time, rounded up."
},
"eta": {
"type": "string",
"description": "The same estimate as short text, for example \"about 34 min\"."
}
},
"required": [
"network",
"confirmations",
"eta_seconds",
"eta"
]
}
}
}
}
}
}
}401 Missing, unknown or incorrect X-API-Key.
JSON schema · 401
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}GET /catalog/dex
Long-tail tokens available through DEX
List relay-allowlisted tokens for a DEX chain. Use address as token_address in POST /cash-outs. Symbols may be shared by different tokens; contract addresses distinguish them. An unsupported settlement network returns 400.
Parameters
| Field | In | Required | Description |
|---|---|---|---|
chain | query | true | DEX chain. Currently only polygon. |
q | query | false | Filter by symbol or partial address. |
Responses
200 Allowlisted tokens.
JSON schema · 200
{
"type": "array",
"items": {
"type": "object",
"properties": {
"symbol": {
"type": "string",
"description": "Token symbol. NOT unique; use address."
},
"address": {
"type": "string",
"description": "Token contract address, used as token_address in the quote."
},
"decimals": {
"type": "integer"
}
},
"required": [
"symbol",
"address",
"decimals"
]
}
}400 Error.
JSON schema · 400
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}401 Missing, unknown or incorrect X-API-Key.
JSON schema · 401
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}GET /comissao
Partner commission balance
Accrued partner fees. Credited when a PIX-to-crypto purchase or balance deposit is settled, never before, to avoid paying commission on funds that may be reversed. Crypto-to-PIX commission is a later phase. Calculation base: amount received minus Lunium's fixed fee. min_saque_cents is US$ 10 converted at the current rate.
Responses
200 Balance, policy and withdrawal minimum
JSON schema · 200
{
"type": "object",
"properties": {
"disponivel_cents": {
"type": "integer"
},
"creditado_cents": {
"type": "integer"
},
"estornado_cents": {
"type": "integer"
},
"sacado_cents": {
"type": "integer"
},
"operacoes": {
"type": "integer"
},
"ultimo_credito_em": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"moeda": {
"type": "string"
},
"sandbox": {
"type": "boolean"
},
"min_saque_cents": {
"type": [
"integer",
"null"
],
"description": "US$ 10 converted at the CURRENT rate. null means no quote is available and withdrawal is refused."
},
"pode_sacar_agora": {
"type": "boolean"
},
"ultimo_saque_em": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"proximo_saque_em": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"politica": {
"type": "object"
}
},
"required": [
"disponivel_cents",
"creditado_cents",
"sacado_cents",
"operacoes",
"moeda",
"sandbox",
"pode_sacar_agora",
"politica"
]
}401 Missing API key
JSON schema · 401
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}GET /comissao/extrato
Commission statement
Parameters
| Field | In | Required | Description |
|---|---|---|---|
limit | query | false | |
before | query | false | id of the last item on the previous page |
Responses
200 Ledger entries, newest first
JSON schema · 200
{
"type": "object",
"properties": {
"itens": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ComissaoEvento"
}
},
"has_more": {
"type": "boolean"
},
"next_before": {
"type": [
"string",
"null"
]
}
}
}401 Missing API key
JSON schema · 401
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}POST /comissao/sacar
Withdraw commission as crypto
Manually withdraw commission as crypto using a currently available route from GET /cashin/catalog. No additional commission-withdrawal fee: the end customer paid the partner fee in the original operation. Minimum US$ 10 at the current rate; read min_saque_cents in GET /comissao. Once per rolling 24-hour window. Track delivery using saque.cashin_id in GET /cashin/{cashin_id}/status or the cashin.settled webhook.
JSON body
| Field | Type | Required | Description |
|---|---|---|---|
amount_cents | integer | true | BRL cents to convert, at least min_saque_cents. |
asset | string | false | usdt or usdc on Polygon, or an asset from GET /cashin/catalog. Default: |
chain | string | false | Default: |
payout_address | string | true | Your wallet on the selected network. |
payout_tag | string | false | Memo/tag when required by the network. |
external_id | string | false | Idempotency identifier, up to 64 characters. Keep the identifier and every request parameter unchanged on retries. Conflict detection differs by route; do not use a replay to modify an operation. 409 external_id_divergente indicates a detected conflict. |
Request schema
{
"type": "object",
"required": [
"amount_cents",
"payout_address"
],
"properties": {
"amount_cents": {
"type": "integer",
"minimum": 1,
"description": "BRL cents to convert, at least min_saque_cents."
},
"asset": {
"type": "string",
"default": "usdt",
"description": "usdt or usdc on Polygon, or an asset from GET /cashin/catalog."
},
"chain": {
"type": "string",
"default": "polygon"
},
"payout_address": {
"type": "string",
"description": "Your wallet on the selected network."
},
"payout_tag": {
"type": "string",
"description": "Memo/tag when required by the network."
},
"external_id": {
"type": "string",
"maxLength": 64,
"description": "Idempotency identifier, up to 64 characters. Keep the identifier and every request parameter unchanged on retries. Conflict detection differs by route; do not use a replay to modify an operation. 409 external_id_divergente indicates a detected conflict."
}
}
}Responses
200 Withdrawal created and queued for delivery
JSON schema · 200
{
"type": "object",
"properties": {
"saque": {
"$ref": "#/components/schemas/Cobranca"
},
"comissao": {
"$ref": "#/components/schemas/Comissao"
}
}
}400 valor_invalido | valor_abaixo_do_minimo (includes min_saque_cents) | rede_indisponivel | asset_invalido | payout_address_invalido | sandbox_sem_saque
JSON schema · 400
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}402 saldo_insuficiente: available commission is lower than the requested amount
JSON schema · 402
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}409 external_id_divergente
JSON schema · 409
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}429 saque_comissao_diario: includes proximo_saque_em, the next allowed withdrawal time
JSON schema · 429
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}503 provedor_indisponivel: no quote available to calculate the minimum
JSON schema · 503
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}POST /keys
Create an API key (self-service)
The full key is returned only ONCE at creation; save it immediately. Only its hash is stored. The response also includes links to groups where API contract changes are announced.
JSON body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | true | Business name, displayed in the dashboard and notifications. |
email | string | false | Recommended. The newly created key is emailed to this address as well as returned in the response. |
settlement_address | string | false | EVM settlement wallet on Polygon. Optional; may be configured later. |
webhook_url | string | false | HTTPS webhook URL. Optional. |
lead_token | string | false | Opaque |
Request schema
{
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"minLength": 2,
"maxLength": 80,
"description": "Business name, displayed in the dashboard and notifications."
},
"email": {
"type": "string",
"format": "email",
"description": "Recommended. The newly created key is emailed to this address as well as returned in the response."
},
"settlement_address": {
"type": "string",
"description": "EVM settlement wallet on Polygon. Optional; may be configured later."
},
"webhook_url": {
"type": "string",
"format": "uri",
"description": "HTTPS webhook URL. Optional."
},
"lead_token": {
"type": "string",
"pattern": "^ldt_[A-Za-z0-9_-]{43}$",
"minLength": 47,
"maxLength": 47,
"description": "Opaque `ldt_…` token returned by POST /leads when the person consented to technical contact. Links this key to the lead. Request body only, never the URL. Optional; a missing or invalid token does not prevent key creation."
}
}
}Responses
201 API key created.
JSON schema · 201
{
"type": "object",
"properties": {
"api_key": {
"type": "string",
"description": "Plaintext API key, returned ONLY in this creation response. Only its hash is stored."
},
"email_sent": {
"type": "boolean",
"description": "true when a copy of the key was sent to the supplied `email`; false when no email was provided or sending failed."
},
"webhook_secret": {
"type": "string",
"description": "Present when webhook_url was supplied."
},
"key": {
"type": "object",
"description": "Public key metadata: prefix, name and feature flags."
},
"limits": {
"type": "object",
"description": "Current limits."
},
"monitor_url": {
"type": "string",
"format": "uri",
"description": "Private read-only live monitor for this key's operations."
},
"lead_attribution": {
"type": "object",
"description": "Attribution result when a consented lead_token is supplied. Attribution never blocks key creation.",
"required": [
"requested",
"linked",
"status"
],
"properties": {
"requested": {
"type": "boolean",
"description": "true if lead_token was supplied in the request body."
},
"linked": {
"type": "boolean",
"description": "true if the key was linked to a contact with consent."
},
"status": {
"type": "string",
"enum": [
"nao_solicitado",
"vinculado",
"token_invalido",
"indisponivel"
],
"description": "Attribution link status."
}
}
}
}
}400 Invalid fields: name is required and webhook_url must be a public HTTPS URL.
JSON schema · 400
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}429 API-key creation limit for this IP address reached.
JSON schema · 429
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}GET /keys/me
Current limits and daily usage
Read current limits here instead of hardcoding them.
Cash-out (selling crypto): R$6.00–R$250,000.00 per transaction, plus a R$100,000.00 daily cap for the recipient's CPF/CNPJ (per PIX key when the key is not a tax ID), resetting at midnight in Brasilia time. The effective maximum is the LOWER of the two and appears in limits.max_brl_cents; the per-transaction cap is limits.max_brl_cents_por_transacao. There is no general daily API-key cap on crypto sales.
Cash-in and payouts: since 2026-09-10 there is no general daily API-key cap: limits.daily_limit_cents, limits.available_today_cents and limits.next_tier are null, limits.tier is "Sem teto" (no daily cap), and limits.daily_limit_applies_to is []. Each charge ranges from R$1.00 to R$6,000.00, subject to the effective minimum in limits.per_operation.cashin.min_brl_cents and the payer ladder in GET /cashin/limits. A key may impose its own daily cap through mandate.max_diario_cents.
Responses
200 Your key and limits.
JSON schema · 200
{
"type": "object",
"description": "Your key, current limits and enabled capabilities.",
"properties": {
"key": {
"type": "object",
"properties": {
"sandbox": {
"type": "boolean"
},
"key_id": {
"type": "integer"
},
"prefix": {
"type": "string"
},
"name": {
"type": "string"
},
"email": {
"type": [
"string",
"null"
],
"description": "null for a sandbox key or a key created without an email."
},
"cashin_enabled": {
"type": "boolean"
},
"cashout_enabled": {
"type": "boolean"
},
"payout_enabled": {
"type": "boolean"
},
"settlement_address": {
"type": [
"string",
"null"
],
"description": "Default settlement wallet on Polygon; null until configured."
},
"chain": {
"type": [
"string",
"null"
]
},
"fee_bps": {
"type": "integer"
},
"rate_limit_per_minute": {
"type": "integer"
},
"webhook_url": {
"type": [
"string",
"null"
],
"description": "null until configured using PATCH /keys/me. Without a webhook URL, cashin.paid/settled/delayed callbacks cannot be delivered."
},
"webhook_configured": {
"type": "boolean"
},
"telegram_linked": {
"type": "boolean"
},
"created_at": {
"type": [
"string",
"null"
]
},
"partner_fee_bps": {
"type": "integer",
"minimum": 0,
"maximum": 1000,
"description": "Partner fee in basis points, ADDED to `fee_bps` (Lunium's fee). 100 = 1%. Paid by the end customer; Lunium's share is unchanged. 0 disables it. Configure using PATCH /keys/me."
}
}
},
"limits": {
"type": "object",
"description": "Current key limits and usage, by operation and payer. A null daily cap means that particular cap is absent, not that all restrictions are removed. Mandates and per-person limits may still apply.",
"additionalProperties": true
},
"payout": {
"type": "object",
"description": "enabled, via, unlocks_at_settled_volume_cents, settled_volume_cents, remaining_cents.",
"additionalProperties": true
},
"monitor_url": {
"type": "string",
"description": "Monitoring page for this key."
},
"telegram": {
"type": "object",
"additionalProperties": true
},
"grupos_obrigatorios": {
"type": "object",
"description": "Links to operational notice, partner and community groups.",
"additionalProperties": true
},
"comissao": {
"type": "object",
"description": "Accrued partner commission. See GET /comissao for details.",
"properties": {
"partner_fee_bps": {
"type": "integer"
},
"max_partner_fee_bps": {
"type": "integer"
},
"disponivel_cents": {
"type": [
"integer",
"null"
]
},
"creditado_cents": {
"type": "integer"
},
"estornado_cents": {
"type": "integer"
},
"sacado_cents": {
"type": "integer"
},
"operacoes": {
"type": "integer"
},
"ultimo_credito_em": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"moeda": {
"type": "string"
},
"nota": {
"type": "string"
}
}
}
}
}401 Missing, unknown or incorrect X-API-Key.
JSON schema · 401
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}PATCH /keys/me
Update key settings, settlement wallet, webhook or tokens
JSON body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | false | |
settlement_address | ['string', 'null'] | false | Polygon address beginning with 0x; null clears it. |
webhook_url | ['string', 'null'] | false | Public HTTPS URL; null clears it. Setting it generates webhook_secret if the key does not yet have one. |
rotate_webhook_secret | boolean | false | true rotates the webhook secret. The new secret is returned ONCE in the response. |
rotate_monitor_token | boolean | false | true rotates the monitor token. The old URL immediately stops exposing data; the replacement is returned in monitor_url. |
partner_fee_bps | integer | false | Partner fee in basis points, added to Lunium's fee and paid by the end customer (100 = 1%; maximum 1000 = 10%). Applies to NEW charges only; existing charges retain their locked fee. 0 disables it. |
Request schema
{
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 2,
"maxLength": 80
},
"settlement_address": {
"type": [
"string",
"null"
],
"description": "Polygon address beginning with 0x; null clears it."
},
"webhook_url": {
"type": [
"string",
"null"
],
"description": "Public HTTPS URL; null clears it. Setting it generates webhook_secret if the key does not yet have one."
},
"rotate_webhook_secret": {
"type": "boolean",
"description": "true rotates the webhook secret. The new secret is returned ONCE in the response."
},
"rotate_monitor_token": {
"type": "boolean",
"description": "true rotates the monitor token. The old URL immediately stops exposing data; the replacement is returned in monitor_url."
},
"partner_fee_bps": {
"type": "integer",
"minimum": 0,
"maximum": 1000,
"description": "Partner fee in basis points, added to Lunium's fee and paid by the end customer (100 = 1%; maximum 1000 = 10%). Applies to NEW charges only; existing charges retain their locked fee. 0 disables it."
}
}
}Responses
200 Key updated. May include a webhook_secret returned once and a replacement monitor_url.
400 Invalid fields or nothing to update.
JSON schema · 400
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}401 Missing, unknown or incorrect X-API-Key.
JSON schema · 401
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}POST /keys/painel-link
Request a dashboard link by email without an API key
Request the monitoring link using the email registered on the key. The response is always generic and does not reveal whether the email exists. Limited to three emails per address and ten per IP each hour. For the current partner dashboard, use https://parceiros.luniumpay.com/entrar and its activation or recovery flow; monitor tokens and dashboard login credentials are distinct.
JSON body
| Field | Type | Required | Description |
|---|---|---|---|
email | string | true |
Request schema
{
"type": "object",
"required": [
"email"
],
"properties": {
"email": {
"type": "string",
"format": "email"
}
}
}Responses
200 Request accepted; generic response.
400 Invalid email.
429 Hourly limit reached.
POST /keys/sandbox
Get a sandbox API key — one call, no API key needed
Returns a lun_test_ key in one call: no approval, no API key and no wallet. email is required: the e-mail of the person who will test. About a minute later, LuniumPay support sends that address one message with what LuniumPay is, the 3-step integration, the manual and PDF, the flowchart and VendaCripto (a ready-made app to buy or sell crypto with PIX, no integration). One message per address, with an unsubscribe link. Missing or invalid email: 400 email_obrigatorio (acao=corrigir, campo=email). All six financial journeys are simulated with fictitious funds using the normal endpoints. GET /sandbox returns the supported flows, scenario matrix and simulation controls. POST /sandbox/cashin/{cashin_id}/pay confirms a non-payable test charge. Cash-in, custody and payouts are durable; cash-out retention is two hours. Signed webhooks use the normal delivery pipeline with sandbox:true. No financial provider is called. Catalogs and prices are synthetic snapshots, not live quotes. See https://docs.luniumpay.com/en/sandbox .
JSON body
| Field | Type | Required | Description |
|---|---|---|---|
email | string | true | Required. E-mail of the person who will test, e.g. you@company.com. LuniumPay support sends this address one message with the integration guide (what LuniumPay is, the 3 steps, manual and PDF, flowchart, VendaCripto). One message per address, with an unsubscribe link. |
name | string | false | Optional label to recognise the key later. |
webhook_url | string | false | Optional HTTPS webhook. |
lead_token | string | false | Optional opaque token returned by consented POST /leads. Links this TEST key to the contact. Invalid or unavailable attribution never blocks key creation. Never put this token in a URL or log. |
Request schema
{
"type": "object",
"required": [
"email"
],
"properties": {
"email": {
"type": "string",
"format": "email",
"maxLength": 160,
"description": "Required. E-mail of the person who will test, e.g. you@company.com. LuniumPay support sends this address one message with the integration guide (what LuniumPay is, the 3 steps, manual and PDF, flowchart, VendaCripto). One message per address, with an unsubscribe link."
},
"name": {
"type": "string",
"description": "Optional label to recognise the key later."
},
"webhook_url": {
"type": "string",
"format": "uri",
"description": "Optional HTTPS webhook."
},
"lead_token": {
"type": "string",
"pattern": "^ldt_[A-Za-z0-9_-]{43}$",
"description": "Optional opaque token returned by consented POST /leads. Links this TEST key to the contact. Invalid or unavailable attribution never blocks key creation. Never put this token in a URL or log."
}
}
}Responses
201 Sandbox key created
JSON schema · 201
{
"type": "object",
"properties": {
"api_key": {
"type": "string",
"example": "lun_test_1df82296e3459819702c6a6087aab1c7"
},
"sandbox": {
"type": "boolean",
"const": true
},
"gatilhos": {
"type": "object",
"description": "The deterministic triggers, described above."
},
"diferencas_para_producao": {
"type": "array",
"items": {
"type": "string"
}
},
"lead_link": {
"type": "object",
"properties": {
"requested": {
"type": "boolean"
},
"linked": {
"type": "boolean"
},
"status": {
"type": "string"
}
}
}
}
}400 email_obrigatorio: email missing or invalid. Send the e-mail of the person who will test, e.g. {"email": "you@company.com"}.
JSON schema · 400
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"email_obrigatorio",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}429 Too many keys from this IP today
JSON schema · 429
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}POST /leads
Request human assistance for a commercial or technical question
Public route requiring no API key. Use for volume pricing, contracts, partnerships or a question not resolved by the documentation. The person must have provided the contact address for this request; do not discover, scrape or reuse email addresses collected for another purpose. To start without contacting anyone, use POST /keys/sandbox.
JSON body
| Field | Type | Required | Description |
|---|---|---|---|
email | string | true | |
nome | string | false | |
empresa | string | false | |
whatsapp | string | false | |
mensagem | string | false | |
fluxo | string | false | Values: |
volume_mensal | string | false | |
prazo | string | false | |
estagio_produto | string | false | |
como_encontrou | string | false | Source reported by the person, separate from UTM attribution. Examples: chatgpt, google, indicacao. |
consentimento | boolean | true | Confirms that the person supplied their contact details to receive a response to this request. |
origem | string | false | Page or context where the request began. |
utm_source | string | false | |
utm_medium | string | false | |
utm_campaign | string | false | |
utm_content | string | false | |
utm_term | string | false | |
ref_agent | string | false | |
website | string | false | Honeypot. Legitimate clients must omit this field or send an empty value. |
Request schema
{
"type": "object",
"required": [
"email",
"consentimento"
],
"properties": {
"email": {
"type": "string",
"format": "email",
"maxLength": 200
},
"nome": {
"type": "string",
"maxLength": 120
},
"empresa": {
"type": "string",
"maxLength": 120
},
"whatsapp": {
"type": "string",
"maxLength": 40
},
"mensagem": {
"type": "string",
"maxLength": 1000
},
"fluxo": {
"type": "string",
"enum": [
"cashin",
"cashout",
"cashin_cashout",
"payout",
"outro",
"custody"
]
},
"volume_mensal": {
"type": "string",
"maxLength": 60
},
"prazo": {
"type": "string",
"maxLength": 60
},
"estagio_produto": {
"type": "string",
"maxLength": 60
},
"como_encontrou": {
"type": "string",
"description": "Source reported by the person, separate from UTM attribution. Examples: chatgpt, google, indicacao."
},
"consentimento": {
"type": "boolean",
"const": true,
"description": "Confirms that the person supplied their contact details to receive a response to this request."
},
"origem": {
"type": "string",
"description": "Page or context where the request began."
},
"utm_source": {
"type": "string"
},
"utm_medium": {
"type": "string"
},
"utm_campaign": {
"type": "string"
},
"utm_content": {
"type": "string"
},
"utm_term": {
"type": "string"
},
"ref_agent": {
"type": "string"
},
"website": {
"type": "string",
"description": "Honeypot. Legitimate clients must omit this field or send an empty value."
}
}
}Responses
200 Existing contact updated within the deduplication window. With explicit consent, returns a new lead_token and invalidates the previous token.
JSON schema · 200
{
"type": "object",
"required": [
"ok"
],
"properties": {
"ok": {
"type": "boolean",
"const": true
},
"lead_id": {
"type": "integer",
"format": "int64"
},
"lead_token": {
"type": "string",
"pattern": "^ldt_[A-Za-z0-9_-]{43}$",
"minLength": 47,
"maxLength": 47,
"description": "Opaque attribution token returned with explicit consent. Send only in POST /keys, POST /keys/sandbox or lunium_start_sandbox_demo. Never place it in URLs or logs."
},
"detail": {
"type": "string"
},
"integration_url": {
"type": "string",
"format": "uri",
"description": "Start the self-service integration immediately; human contact is optional."
}
}
}201 Contact request received. With explicit consent, lead_token links this contact to a subsequently created key.
JSON schema · 201
{
"type": "object",
"required": [
"ok",
"lead_id"
],
"properties": {
"ok": {
"type": "boolean",
"const": true
},
"lead_id": {
"type": "integer",
"format": "int64"
},
"lead_token": {
"type": "string",
"pattern": "^ldt_[A-Za-z0-9_-]{43}$",
"minLength": 47,
"maxLength": 47,
"description": "Opaque attribution token returned with explicit consent. Send only in POST /keys, POST /keys/sandbox or lunium_start_sandbox_demo. Never place it in URLs or logs."
},
"detail": {
"type": "string"
},
"integration_url": {
"type": "string",
"format": "uri",
"description": "Start the self-service integration immediately; human contact is optional."
}
}
}400 Invalid email or request body.
JSON schema · 400
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}429 Too many attempts from the same address.
503 Could not save the contact request. Try again or use the published contact email.
GET /mesh
Everything an agent needs before integrating
One public GET describes Lunium, settlement capabilities, assets, networks, endpoints, key creation, production activation, limits and schemas. No credential required.
Responses
200 Discovery document.
JSON schema · 200
{
"type": "object",
"description": "Single discovery document answering the questions an agent needs before integrating. Generated from the live configuration to reflect API behavior.",
"properties": {
"quem_somos": {
"type": "object"
},
"como_falar_comigo": {
"type": "object",
"description": "REST, OpenAPI, MCP, A2A and Mesh."
},
"capacidades": {
"type": "object",
"additionalProperties": {
"$ref": "#/components/schemas/Capability"
}
},
"como_escolher_capacidade": {
"type": "object",
"description": "Intent-to-capability index and instructions for filtering by attribute.",
"properties": {
"por_intencao": {
"type": "object",
"additionalProperties": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
},
"execucao": {
"type": "object",
"description": "Endpoint, required fields and ready-to-use example for each capability."
},
"ativos_e_redes": {
"type": "object"
},
"limites": {
"type": "object"
},
"como_comecar": {
"type": "object"
},
"regra_de_seguranca": {
"type": "object"
},
"atribuicao": {
"type": "object"
}
}
}GET /mesh/agents
List agents in the network
Public directory. Never returns keys, hashes or tokens.
Responses
200 Agents.
JSON schema · 200
{
"type": "object",
"properties": {
"agents": {
"type": "array",
"items": {
"$ref": "#/components/schemas/AgentIdentity"
}
}
}
}POST /mesh/agents
Register an agent and receive a sandbox credential
Register and issue a key in one call. referral_token establishes verified lineage; without it, the agent is registered as a root.
JSON body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | true | |
description | string | false | |
contact | string | false | |
agent_card_url | string | false | |
capabilities | array | false | |
referral_token | string | false | Attestation signed by the referrer. This is the ONLY way to establish referral lineage. Client-supplied |
Request schema
{
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"minLength": 2,
"maxLength": 80
},
"description": {
"type": "string"
},
"contact": {
"type": "string"
},
"agent_card_url": {
"type": "string"
},
"capabilities": {
"type": "array",
"items": {
"type": "string"
}
},
"referral_token": {
"type": "string",
"description": "Attestation signed by the referrer. This is the ONLY way to establish referral lineage. Client-supplied `referred_by` is rejected because lineage determines financial rewards."
}
}
}Responses
201 Agent created, with credential and next step.
JSON schema · 201
{
"type": "object",
"properties": {
"agent": {
"$ref": "#/components/schemas/AgentIdentity"
},
"api_key": {
"type": "string"
},
"sandbox": {
"type": "boolean"
},
"lineage": {
"type": "object"
},
"proximo_passo": {
"type": "object"
}
}
}400 Invalid request or rejected referral_token.
JSON schema · 400
{
"type": "object",
"description": "Error the agent can handle itself. `acao` is a stable enum: corrigir (fix request), esperar (wait for quota), parar (stop retrying), repetir (retry a transient failure).",
"properties": {
"erro": {
"type": "string",
"example": "mandate_valor_acima_do_teto"
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"esperar",
"parar",
"repetir"
]
},
"detail": {
"type": "string"
},
"missing": {
"type": "array",
"items": {
"type": "string"
}
},
"next_actions": {
"type": "array",
"items": {
"$ref": "#/components/schemas/NextAction"
}
}
},
"required": [
"erro",
"acao"
]
}GET /mesh/agents/{agent_id}
Read an agent's state, mandate, metrics and lineage
Parameters
| Field | In | Required | Description |
|---|---|---|---|
agent_id | path | true |
Responses
200 Agent details.
JSON schema · 200
{
"type": "object",
"description": "PERMANENT agent identity. Credentials can be replaced; lineage, volume, rewards, mandate and reputation belong to agent_id.",
"properties": {
"agent_id": {
"type": "string",
"example": "agt_2319c9da313e84af3b"
},
"name": {
"type": "string"
},
"description": {
"type": [
"string",
"null"
]
},
"contact": {
"type": [
"string",
"null"
]
},
"status": {
"$ref": "#/components/schemas/AgentLifecycle"
},
"environment": {
"type": "string",
"enum": [
"sandbox",
"production"
]
},
"capabilities": {
"type": "array",
"items": {
"type": "string"
}
},
"settlement_address": {
"type": [
"string",
"null"
]
},
"referred_by": {
"type": [
"string",
"null"
],
"description": "Immutable after registration, enforced by a database trigger."
},
"created_at": {
"type": "string",
"format": "date-time"
}
}
}404 Not found.
JSON schema · 404
{
"type": "object",
"description": "Error the agent can handle itself. `acao` is a stable enum: corrigir (fix request), esperar (wait for quota), parar (stop retrying), repetir (retry a transient failure).",
"properties": {
"erro": {
"type": "string",
"example": "mandate_valor_acima_do_teto"
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"esperar",
"parar",
"repetir"
]
},
"detail": {
"type": "string"
},
"missing": {
"type": "array",
"items": {
"type": "string"
}
},
"next_actions": {
"type": "array",
"items": {
"$ref": "#/components/schemas/NextAction"
}
}
},
"required": [
"erro",
"acao"
]
}POST /mesh/agents/{agent_id}/mandate
Set the agent's own limits policy
Can only tighten key limits, never expand them. Required before production activation.
Parameters
| Field | In | Required | Description |
|---|---|---|---|
agent_id | path | true |
JSON body
| Field | Type | Required | Description |
|---|---|---|---|
max_por_operacao_cents | integer | false | |
max_diario_cents | integer | false | |
contrapartes | array | false | Allowed PIX destination keys. Empty means no restriction. |
Request schema
{
"type": "object",
"description": "Policy imposed by the key itself. It can only tighten limits, never expand them, so an agent can set it independently. Required before production activation.",
"properties": {
"max_por_operacao_cents": {
"type": "integer",
"example": 30000
},
"max_diario_cents": {
"type": "integer",
"example": 200000
},
"contrapartes": {
"type": "array",
"items": {
"type": "string"
},
"description": "Allowed PIX destination keys. Empty means no restriction."
}
}
}Responses
200 Completed.
JSON schema · 200
{
"type": "object"
}401 Missing API key.
JSON schema · 401
{
"type": "object",
"description": "Error the agent can handle itself. `acao` is a stable enum: corrigir (fix request), esperar (wait for quota), parar (stop retrying), repetir (retry a transient failure).",
"properties": {
"erro": {
"type": "string",
"example": "mandate_valor_acima_do_teto"
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"esperar",
"parar",
"repetir"
]
},
"detail": {
"type": "string"
},
"missing": {
"type": "array",
"items": {
"type": "string"
}
},
"next_actions": {
"type": "array",
"items": {
"$ref": "#/components/schemas/NextAction"
}
}
},
"required": [
"erro",
"acao"
]
}403 Key does not belong to this agent.
JSON schema · 403
{
"type": "object",
"description": "Error the agent can handle itself. `acao` is a stable enum: corrigir (fix request), esperar (wait for quota), parar (stop retrying), repetir (retry a transient failure).",
"properties": {
"erro": {
"type": "string",
"example": "mandate_valor_acima_do_teto"
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"esperar",
"parar",
"repetir"
]
},
"detail": {
"type": "string"
},
"missing": {
"type": "array",
"items": {
"type": "string"
}
},
"next_actions": {
"type": "array",
"items": {
"$ref": "#/components/schemas/NextAction"
}
}
},
"required": [
"erro",
"acao"
]
}409 Missing prerequisite.
JSON schema · 409
{
"type": "object",
"description": "Error the agent can handle itself. `acao` is a stable enum: corrigir (fix request), esperar (wait for quota), parar (stop retrying), repetir (retry a transient failure).",
"properties": {
"erro": {
"type": "string",
"example": "mandate_valor_acima_do_teto"
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"esperar",
"parar",
"repetir"
]
},
"detail": {
"type": "string"
},
"missing": {
"type": "array",
"items": {
"type": "string"
}
},
"next_actions": {
"type": "array",
"items": {
"$ref": "#/components/schemas/NextAction"
}
}
},
"required": [
"erro",
"acao"
]
}GET /mesh/agents/{agent_id}/network
Referral lineage, tree and network volume
Recursive network query. network_volume counts the entire tree; reward_eligible_volume counts only eligible direct-referral volume (level 1).
Parameters
| Field | In | Required | Description |
|---|---|---|---|
agent_id | path | true |
Responses
200 Network details.
JSON schema · 200
{
"type": "object",
"description": "An agent's referral tree. `network_volume` counts the entire tree for reputation; `reward_eligible_volume` counts only reward-eligible volume.",
"properties": {
"agent_id": {
"type": "string"
},
"referred_by": {
"type": [
"string",
"null"
]
},
"depth": {
"type": "integer"
},
"direct_children": {
"type": "integer"
},
"total_descendants": {
"type": "integer"
},
"own_volume_cents": {
"type": "integer"
},
"own_transactions": {
"type": "integer"
},
"network_volume_cents": {
"type": "integer"
},
"network_transactions": {
"type": "integer"
},
"reward_eligible_volume_cents": {
"type": "integer"
},
"lifetime_rewards_cents": {
"type": "integer"
},
"first_operation": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"production_since": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"children": {
"type": "array",
"items": {
"type": "object"
}
}
}
}404 Not found.
JSON schema · 404
{
"type": "object",
"description": "Error the agent can handle itself. `acao` is a stable enum: corrigir (fix request), esperar (wait for quota), parar (stop retrying), repetir (retry a transient failure).",
"properties": {
"erro": {
"type": "string",
"example": "mandate_valor_acima_do_teto"
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"esperar",
"parar",
"repetir"
]
},
"detail": {
"type": "string"
},
"missing": {
"type": "array",
"items": {
"type": "string"
}
},
"next_actions": {
"type": "array",
"items": {
"$ref": "#/components/schemas/NextAction"
}
}
},
"required": [
"erro",
"acao"
]
}POST /mesh/agents/{agent_id}/production-request
Activate production automatically
Automatically checks validated sandbox usage, a settlement address on a supported network, a policy-compliant mandate and an active credential. If satisfied, production is activated in the same response. Otherwise returns 422 with missing and next_actions so the agent can correct the configuration and retry.
Parameters
| Field | In | Required | Description |
|---|---|---|---|
agent_id | path | true |
Responses
200 Completed.
JSON schema · 200
{
"type": "object",
"description": "AUTOMATIC activation. `activated_by` is always `policy`, never `operator`.",
"properties": {
"status": {
"type": "string",
"example": "production_active"
},
"agent_id": {
"type": "string"
},
"environment": {
"type": "string",
"example": "production"
},
"activated_at": {
"type": "string",
"format": "date-time"
},
"activated_by": {
"type": "string",
"example": "policy"
},
"api_key": {
"type": "string",
"description": "Production credential (`lun_live_*`), returned only once."
},
"settlement": {
"type": "object"
},
"mandate": {
"$ref": "#/components/schemas/Mandate"
},
"capabilities": {
"type": "array",
"items": {
"type": "string"
}
}
}
}401 Missing API key.
JSON schema · 401
{
"type": "object",
"description": "Error the agent can handle itself. `acao` is a stable enum: corrigir (fix request), esperar (wait for quota), parar (stop retrying), repetir (retry a transient failure).",
"properties": {
"erro": {
"type": "string",
"example": "mandate_valor_acima_do_teto"
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"esperar",
"parar",
"repetir"
]
},
"detail": {
"type": "string"
},
"missing": {
"type": "array",
"items": {
"type": "string"
}
},
"next_actions": {
"type": "array",
"items": {
"$ref": "#/components/schemas/NextAction"
}
}
},
"required": [
"erro",
"acao"
]
}403 Key does not belong to this agent.
JSON schema · 403
{
"type": "object",
"description": "Error the agent can handle itself. `acao` is a stable enum: corrigir (fix request), esperar (wait for quota), parar (stop retrying), repetir (retry a transient failure).",
"properties": {
"erro": {
"type": "string",
"example": "mandate_valor_acima_do_teto"
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"esperar",
"parar",
"repetir"
]
},
"detail": {
"type": "string"
},
"missing": {
"type": "array",
"items": {
"type": "string"
}
},
"next_actions": {
"type": "array",
"items": {
"$ref": "#/components/schemas/NextAction"
}
}
},
"required": [
"erro",
"acao"
]
}409 Missing prerequisite.
JSON schema · 409
{
"type": "object",
"description": "Error the agent can handle itself. `acao` is a stable enum: corrigir (fix request), esperar (wait for quota), parar (stop retrying), repetir (retry a transient failure).",
"properties": {
"erro": {
"type": "string",
"example": "mandate_valor_acima_do_teto"
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"esperar",
"parar",
"repetir"
]
},
"detail": {
"type": "string"
},
"missing": {
"type": "array",
"items": {
"type": "string"
}
},
"next_actions": {
"type": "array",
"items": {
"$ref": "#/components/schemas/NextAction"
}
}
},
"required": [
"erro",
"acao"
]
}422 Incomplete prerequisites, in machine-readable form.
JSON schema · 422
{
"type": "object",
"description": "Error the agent can handle itself. `acao` is a stable enum: corrigir (fix request), esperar (wait for quota), parar (stop retrying), repetir (retry a transient failure).",
"properties": {
"erro": {
"type": "string",
"example": "mandate_valor_acima_do_teto"
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"esperar",
"parar",
"repetir"
]
},
"detail": {
"type": "string"
},
"missing": {
"type": "array",
"items": {
"type": "string"
}
},
"next_actions": {
"type": "array",
"items": {
"$ref": "#/components/schemas/NextAction"
}
}
},
"required": [
"erro",
"acao"
]
}GET /mesh/agents/{agent_id}/rewards
Reward balance and ledger
Parameters
| Field | In | Required | Description |
|---|---|---|---|
agent_id | path | true |
Responses
200 Balance and ledger.
JSON schema · 200
{
"type": "object",
"description": "Balance belongs to agent_id, never to a credential. Rotating a key does not lose the balance.",
"properties": {
"agent_id": {
"type": "string"
},
"own_volume_cents": {
"type": "integer"
},
"direct_referral_volume_cents": {
"type": "integer"
},
"network_volume_cents": {
"type": "integer"
},
"pending_rewards_cents": {
"type": "integer"
},
"available_rewards_cents": {
"type": "integer"
},
"paid_rewards_cents": {
"type": "integer"
},
"lifetime_rewards_cents": {
"type": "integer"
},
"reward_events": {
"type": "integer"
},
"reversals": {
"type": "integer"
},
"policy": {
"$ref": "#/components/schemas/MeshEconomyPolicy"
},
"ledger": {
"type": "array",
"items": {
"$ref": "#/components/schemas/RewardEvent"
}
}
}
}404 Not found.
JSON schema · 404
{
"type": "object",
"description": "Error the agent can handle itself. `acao` is a stable enum: corrigir (fix request), esperar (wait for quota), parar (stop retrying), repetir (retry a transient failure).",
"properties": {
"erro": {
"type": "string",
"example": "mandate_valor_acima_do_teto"
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"esperar",
"parar",
"repetir"
]
},
"detail": {
"type": "string"
},
"missing": {
"type": "array",
"items": {
"type": "string"
}
},
"next_actions": {
"type": "array",
"items": {
"$ref": "#/components/schemas/NextAction"
}
}
},
"required": [
"erro",
"acao"
]
}POST /mesh/agents/{agent_id}/settlement
Set the settlement destination
Address on a supported settlement network.
Parameters
| Field | In | Required | Description |
|---|---|---|---|
agent_id | path | true |
JSON body
| Field | Type | Required | Description |
|---|---|---|---|
settlement_address | string | true | Wallet on a supported settlement network. |
Request schema
{
"type": "object",
"required": [
"settlement_address"
],
"properties": {
"settlement_address": {
"type": "string",
"example": "0x51e3…75e0",
"description": "Wallet on a supported settlement network."
}
}
}Responses
200 Completed.
JSON schema · 200
{
"type": "object"
}401 Missing API key.
JSON schema · 401
{
"type": "object",
"description": "Error the agent can handle itself. `acao` is a stable enum: corrigir (fix request), esperar (wait for quota), parar (stop retrying), repetir (retry a transient failure).",
"properties": {
"erro": {
"type": "string",
"example": "mandate_valor_acima_do_teto"
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"esperar",
"parar",
"repetir"
]
},
"detail": {
"type": "string"
},
"missing": {
"type": "array",
"items": {
"type": "string"
}
},
"next_actions": {
"type": "array",
"items": {
"$ref": "#/components/schemas/NextAction"
}
}
},
"required": [
"erro",
"acao"
]
}403 Key does not belong to this agent.
JSON schema · 403
{
"type": "object",
"description": "Error the agent can handle itself. `acao` is a stable enum: corrigir (fix request), esperar (wait for quota), parar (stop retrying), repetir (retry a transient failure).",
"properties": {
"erro": {
"type": "string",
"example": "mandate_valor_acima_do_teto"
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"esperar",
"parar",
"repetir"
]
},
"detail": {
"type": "string"
},
"missing": {
"type": "array",
"items": {
"type": "string"
}
},
"next_actions": {
"type": "array",
"items": {
"$ref": "#/components/schemas/NextAction"
}
}
},
"required": [
"erro",
"acao"
]
}409 Missing prerequisite.
JSON schema · 409
{
"type": "object",
"description": "Error the agent can handle itself. `acao` is a stable enum: corrigir (fix request), esperar (wait for quota), parar (stop retrying), repetir (retry a transient failure).",
"properties": {
"erro": {
"type": "string",
"example": "mandate_valor_acima_do_teto"
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"esperar",
"parar",
"repetir"
]
},
"detail": {
"type": "string"
},
"missing": {
"type": "array",
"items": {
"type": "string"
}
},
"next_actions": {
"type": "array",
"items": {
"$ref": "#/components/schemas/NextAction"
}
}
},
"required": [
"erro",
"acao"
]
}POST /mesh/agents/{agent_id}/validate
Validate sandbox usage
Creating a key alone is insufficient: the agent must create AND accept a sandbox order. This is the required usage check before real funds are involved. Independently verify your application's error handling, polling and webhook processing.
Parameters
| Field | In | Required | Description |
|---|---|---|---|
agent_id | path | true |
Responses
200 Completed.
JSON schema · 200
{
"type": "object"
}401 Missing API key.
JSON schema · 401
{
"type": "object",
"description": "Error the agent can handle itself. `acao` is a stable enum: corrigir (fix request), esperar (wait for quota), parar (stop retrying), repetir (retry a transient failure).",
"properties": {
"erro": {
"type": "string",
"example": "mandate_valor_acima_do_teto"
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"esperar",
"parar",
"repetir"
]
},
"detail": {
"type": "string"
},
"missing": {
"type": "array",
"items": {
"type": "string"
}
},
"next_actions": {
"type": "array",
"items": {
"$ref": "#/components/schemas/NextAction"
}
}
},
"required": [
"erro",
"acao"
]
}403 Key does not belong to this agent.
JSON schema · 403
{
"type": "object",
"description": "Error the agent can handle itself. `acao` is a stable enum: corrigir (fix request), esperar (wait for quota), parar (stop retrying), repetir (retry a transient failure).",
"properties": {
"erro": {
"type": "string",
"example": "mandate_valor_acima_do_teto"
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"esperar",
"parar",
"repetir"
]
},
"detail": {
"type": "string"
},
"missing": {
"type": "array",
"items": {
"type": "string"
}
},
"next_actions": {
"type": "array",
"items": {
"$ref": "#/components/schemas/NextAction"
}
}
},
"required": [
"erro",
"acao"
]
}409 Missing prerequisite.
JSON schema · 409
{
"type": "object",
"description": "Error the agent can handle itself. `acao` is a stable enum: corrigir (fix request), esperar (wait for quota), parar (stop retrying), repetir (retry a transient failure).",
"properties": {
"erro": {
"type": "string",
"example": "mandate_valor_acima_do_teto"
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"esperar",
"parar",
"repetir"
]
},
"detail": {
"type": "string"
},
"missing": {
"type": "array",
"items": {
"type": "string"
}
},
"next_actions": {
"type": "array",
"items": {
"$ref": "#/components/schemas/NextAction"
}
}
},
"required": [
"erro",
"acao"
]
}GET /mesh/economy
Public network economy rules
0.10% of SETTLED volume from direct referrals, level 1 only. Registration, referrals, quotes and sandbox activity generate no payment.
Responses
200 Current policy.
JSON schema · 200
{
"type": "object",
"description": "Public network economy rules. NO SETTLEMENT → NO REWARD.",
"properties": {
"model": {
"type": "string",
"example": "transaction_attribution"
},
"direct_rate": {
"type": "string",
"example": "0.10%"
},
"direct_rate_bps": {
"type": "integer",
"example": 10
},
"max_paid_levels": {
"type": "integer",
"example": 1
},
"recruitment_reward": {
"type": "boolean",
"example": false
},
"requires_settled_transaction": {
"type": "boolean",
"example": true
},
"revenue_share_cap": {
"type": "string"
}
}
}GET /mesh/graph
Mesh agent graph
Public agents, referral relationships and aggregated network totals. No credentials required; no secrets returned.
Responses
200 Statistics and public agents.
JSON schema · 200
{
"type": "object",
"required": [
"stats",
"agents"
],
"properties": {
"stats": {
"type": "object",
"additionalProperties": true
},
"agents": {
"type": "array",
"items": {
"type": "object",
"required": [
"agent_id",
"name",
"status",
"capabilities"
],
"properties": {
"agent_id": {
"type": "string"
},
"name": {
"type": "string"
},
"status": {
"type": "string"
},
"referred_by": {
"type": [
"string",
"null"
]
},
"capabilities": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
}
}POST /mesh/referrals
Issue a referral attestation
Requires the referring agent's X-API-Key. Returns a signed, single-use, expiring token. This is the only way to establish referral lineage and the corresponding 0.10% reward eligibility.
JSON body
| Field | Type | Required | Description |
|---|---|---|---|
capability | string | false | |
expires_in_minutes | integer | false | Default: |
Request schema
{
"type": "object",
"properties": {
"capability": {
"type": "string"
},
"expires_in_minutes": {
"type": "integer",
"default": 60,
"maximum": 10080
}
}
}Responses
201 Attestation issued.
JSON schema · 201
{
"type": "object",
"description": "Signed, single-use, expiring token (JWS HS256) proving the referrer. Without it, the agent becomes a root agent and generates no referral reward for another agent.",
"properties": {
"type": {
"type": "string",
"example": "mesh_referral"
},
"referrer_agent_id": {
"type": "string"
},
"referral_token": {
"type": "string"
},
"capability": {
"type": [
"string",
"null"
]
},
"nonce": {
"type": "string"
},
"expires_at": {
"type": "string",
"format": "date-time"
},
"one_time_use": {
"type": "boolean",
"example": true
}
}
}401 Missing API key.
JSON schema · 401
{
"type": "object",
"description": "Error the agent can handle itself. `acao` is a stable enum: corrigir (fix request), esperar (wait for quota), parar (stop retrying), repetir (retry a transient failure).",
"properties": {
"erro": {
"type": "string",
"example": "mandate_valor_acima_do_teto"
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"esperar",
"parar",
"repetir"
]
},
"detail": {
"type": "string"
},
"missing": {
"type": "array",
"items": {
"type": "string"
}
},
"next_actions": {
"type": "array",
"items": {
"$ref": "#/components/schemas/NextAction"
}
}
},
"required": [
"erro",
"acao"
]
}404 Key is not associated with an agent.
JSON schema · 404
{
"type": "object",
"description": "Error the agent can handle itself. `acao` is a stable enum: corrigir (fix request), esperar (wait for quota), parar (stop retrying), repetir (retry a transient failure).",
"properties": {
"erro": {
"type": "string",
"example": "mandate_valor_acima_do_teto"
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"esperar",
"parar",
"repetir"
]
},
"detail": {
"type": "string"
},
"missing": {
"type": "array",
"items": {
"type": "string"
}
},
"next_actions": {
"type": "array",
"items": {
"$ref": "#/components/schemas/NextAction"
}
}
},
"required": [
"erro",
"acao"
]
}GET /payouts
List payouts for this key
Parameters
| Field | In | Required | Description |
|---|---|---|---|
status | query | false | |
limit | query | false | |
external_id | query | false | Idempotent recovery: returns the operation with this external_id, if any (0 or 1). Unique per key and product, case-sensitive and retained permanently. |
Responses
200 List, newest first. An empty list returns 200, never 403.
JSON schema · 200
{
"type": "object",
"properties": {
"payouts": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Payout"
}
}
}
}401 Missing, unknown or incorrect X-API-Key.
JSON schema · 401
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}403 Payouts are not enabled for this key.
JSON schema · 403
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}POST /payouts
Send a PIX directly (no crypto leg)
Send PIX using only available BRL house or customer_ref subaccount balance received through PIX. Check payout.enabled in GET /keys/me, and custodia_ativa, pix_rules and fees in GET /saldo. Maximum R$6,000.00 per PIX, subject to lower account limits. A valid recipient CPF/CNPJ is required; the API may derive it from a CPF/CNPJ PIX key. Amount plus fees are reserved before calling the provider; insufficient balance returns 402. Read the current fee from the API and reconcile the operation fee_cents. Limits and the key mandate still apply. Keep external_id stable and query the original order after a timeout. Sandbox uses fictitious balance and calculates the fee published by the API; no real payment occurs. The USDT wallet is separate from BRL balance: it requires project enablement, receives external USDT deposits and does not use /payouts. When enabled it uses funding_source=crypto_usdt; a recipient document is not required in that flow. Its limits come from the quote and API conditions, not the R$6,000 BRL-balance cap. It is unavailable in sandbox.
JSON body
| Field | Type | Required | Description |
|---|---|---|---|
amount_cents | integer | true | PIX amount as integer BRL CENTS (5000 = R$50.00). Maximum 600000 (R$6,000.00), subject to a lower account limit. Fees are debited in addition to this amount. |
pix_key | string | true | Destination PIX key: CPF, CNPJ, +55 phone number, email or random key. For 11 bare digits, also send pix_key_type ("cpf" or "phone"); otherwise the API returns erro=tipo_ambiguo instead of guessing. |
pix_key_type | — | false | Optional: inferred from email, CNPJ, UUID or a +55 phone number. Required for 11 bare digits, where CPF and phone numbers cannot be distinguished. In that case the API returns tipo_ambiguo instead of guessing. Values: |
tax_number | string | false | Valid recipient CPF or CNPJ, with verified check digits. Required for email, phone or random PIX keys. For a valid CPF/CNPJ key, it may be omitted: the API derives the document from that key; if supplied, it must match. This does not prove key ownership. |
beneficiary_name | string | false | Optional. Beneficiary's full name, forwarded to the PIX provider as the end user's name. Not required — payouts to third-party PIX keys are allowed. |
external_id | string | false | Idempotent identifier of up to 64 characters. Retries must preserve amount, PIX key, type, recipient document, customer_ref and funding_source from the original request. A 409 external_id_divergente or external_id_nao_verificavel returns payout_id/recovery_endpoint for the original order; do not generate another ID merely to bypass the conflict. |
customer_ref | string | false | Sub-account to debit (custody keys). Debited BEFORE the PIX is sent: amount + house fee ( |
sandbox_scenario | string | false | Only for a sandbox key. GET /sandbox provides the scenario matrix by flow. Omit in production. All prices, payments and withdrawals remain fictitious. Values: |
funding_source | string | false | Optional. The only accepted value is pix_brl. This endpoint debits BRL balance received through PIX; it never debits the USDT wallet. Values: |
Request schema
{
"type": "object",
"properties": {
"amount_cents": {
"type": "integer",
"minimum": 1,
"description": "PIX amount as integer BRL CENTS (5000 = R$50.00). Maximum 600000 (R$6,000.00), subject to a lower account limit. Fees are debited in addition to this amount.",
"maximum": 600000
},
"pix_key": {
"type": "string",
"description": "Destination PIX key: CPF, CNPJ, +55 phone number, email or random key. For 11 bare digits, also send pix_key_type (\"cpf\" or \"phone\"); otherwise the API returns erro=tipo_ambiguo instead of guessing."
},
"pix_key_type": {
"enum": [
"cpf",
"cnpj",
"phone",
"email",
"random"
],
"description": "Optional: inferred from email, CNPJ, UUID or a +55 phone number. Required for 11 bare digits, where CPF and phone numbers cannot be distinguished. In that case the API returns tipo_ambiguo instead of guessing."
},
"tax_number": {
"type": "string",
"description": "Valid recipient CPF or CNPJ, with verified check digits. Required for email, phone or random PIX keys. For a valid CPF/CNPJ key, it may be omitted: the API derives the document from that key; if supplied, it must match. This does not prove key ownership."
},
"beneficiary_name": {
"type": "string",
"maxLength": 120,
"description": "Optional. Beneficiary's full name, forwarded to the PIX provider as the end user's name. Not required — payouts to third-party PIX keys are allowed."
},
"external_id": {
"type": "string",
"description": "Idempotent identifier of up to 64 characters. Retries must preserve amount, PIX key, type, recipient document, customer_ref and funding_source from the original request. A 409 external_id_divergente or external_id_nao_verificavel returns payout_id/recovery_endpoint for the original order; do not generate another ID merely to bypass the conflict.",
"maxLength": 64
},
"customer_ref": {
"type": "string",
"maxLength": 80,
"description": "Sub-account to debit (custody keys). Debited BEFORE the PIX is sent: amount + house fee (`saque_fee_bps`) + provider fee; on explicit provider refusal the debits are reversed. 402 `saldo_insuficiente` when available balance < amount + fees (`saque_fee_bps`, `saque_taxa_estimada_cents` in GET /saldo). Sub-account (e.g. the merchant) whose balance is debited. Same value used on the deposit."
},
"sandbox_scenario": {
"type": "string",
"enum": [
"success",
"delayed",
"held",
"expired",
"refunded",
"failed",
"payer_mismatch",
"settlement_failed",
"settlement_uncertain",
"route_unavailable",
"provider_unavailable"
],
"description": "Only for a sandbox key. GET /sandbox provides the scenario matrix by flow. Omit in production. All prices, payments and withdrawals remain fictitious."
},
"funding_source": {
"type": "string",
"enum": [
"pix_brl"
],
"description": "Optional. The only accepted value is pix_brl. This endpoint debits BRL balance received through PIX; it never debits the USDT wallet."
}
},
"required": [
"amount_cents",
"pix_key"
]
}Responses
403 Administrative kill switch or `custodia_desligada`. Production keys are enabled by default; if this response appears, stop and contact support instead of retrying. No PIX was sent.
JSON schema · 403
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}409 external_id_divergente or external_id_nao_verificavel: query the original operation using payout_id/recovery_endpoint. Do not change parameters or generate a new ID for the same payment intent. em_processamento: query the in-flight order without submitting a new payment.
JSON schema · 409
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
},
"payout_id": {
"type": "string",
"description": "Original payout identifier."
},
"recovery_endpoint": {
"type": "string",
"description": "Relative API path of the original payout."
}
}
}401 Missing, unknown or incorrect X-API-Key.
JSON schema · 401
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}423 carencia_primeiro_deposito — first-deposit hold (only keys with a contractual holding period; none by default since 2026-09-16): no withdrawal for this sub-account until `libera_em`.
JSON schema · 423
{
"type": "object",
"properties": {
"erro": {
"type": "string",
"enum": [
"carencia_primeiro_deposito"
]
},
"acao": {
"type": "string",
"enum": [
"esperar"
]
},
"detail": {
"type": "string"
},
"libera_em": {
"type": "string",
"format": "date-time"
}
}
}503 saque_indisponivel: funding/provider unavailable; this attempt makes no new reservation or debit. idempotencia_indisponivel: the previous order could not be checked; no new order is created, but an earlier one may exist. Wait and query the same external_id; do not generate a new ID.
200 Payout created, or idempotent replay of the original operation.
JSON schema · 200
{
"type": "object",
"description": "PIX payout funded by the key's custody balance (PIX→PIX).",
"properties": {
"payout_id": {
"type": "string"
},
"customer_ref": {
"type": [
"string",
"null"
],
"maxLength": 80
},
"status": {
"type": "string",
"description": "processing, sent, failed or refunded. Reconcile balance using the statement and tolerate new states."
},
"amount_cents": {
"type": "integer",
"description": "Amount the recipient receives."
},
"fee_cents": {
"type": [
"integer",
"null"
],
"description": "Additional amount debited beyond the payout amount: fee_service_cents + fee_provider_cents."
},
"fee_service_cents": {
"type": [
"integer",
"null"
],
"description": "Key-specific service fee, from saque_fee_bps in GET /saldo."
},
"fee_provider_cents": {
"type": [
"integer",
"null"
],
"description": "Effective provider fee, fixed or percentage-based. Read the saque_taxa_provedor_* fields in GET /saldo."
},
"pix_key": {
"type": "string"
},
"pix_key_type": {
"type": "string",
"enum": [
"cpf",
"cnpj",
"phone",
"email",
"random"
]
},
"tax_number": {
"type": [
"string",
"null"
],
"description": "Masked recipient tax ID, when supplied; optional in the request."
},
"external_id": {
"type": [
"string",
"null"
],
"description": "Idempotent identifier of up to 64 characters. Retries must preserve amount, PIX key, type, recipient document, customer_ref and funding_source from the original request. A 409 external_id_divergente or external_id_nao_verificavel returns payout_id/recovery_endpoint for the original order; do not generate another ID merely to bypass the conflict.",
"maxLength": 64
},
"error": {
"type": [
"string",
"null"
],
"description": "Reason when the operation is failed or refunded."
},
"e2e": {
"type": [
"string",
"null"
],
"description": "EndToEndId of the outgoing PIX payment."
},
"receiver_name": {
"type": [
"string",
"null"
],
"description": "Recipient name obtained after payment, when available; otherwise null."
},
"receiver_tax_number": {
"type": [
"string",
"null"
]
},
"paid_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"sent_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"verify_url": {
"type": [
"string",
"null"
],
"description": "Public PIX verification (GET /v1/verificar/{e2e})."
},
"created_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"updated_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"sandbox": {
"type": "boolean",
"description": "True for fictitious sandbox operations."
},
"simulation": {
"type": "object",
"additionalProperties": true
}
}
}400 Refusal or failure. Read erro, acao and detail when present.
JSON schema · 400
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}402 Refusal or failure. Read erro, acao and detail when present.
JSON schema · 402
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}500 Refusal or failure. Read erro, acao and detail when present.
JSON schema · 500
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}GET /payouts/{payout_id}
State of a payout
Parameters
| Field | In | Required | Description |
|---|---|---|---|
payout_id | path | true |
Responses
200 Withdrawal state.
JSON schema · 200
{
"type": "object",
"description": "PIX payout funded by the key's custody balance (PIX→PIX).",
"properties": {
"payout_id": {
"type": "string"
},
"customer_ref": {
"type": [
"string",
"null"
],
"maxLength": 80
},
"status": {
"type": "string",
"description": "processing, sent, failed or refunded. Reconcile balance using the statement and tolerate new states."
},
"amount_cents": {
"type": "integer",
"description": "Amount the recipient receives."
},
"fee_cents": {
"type": [
"integer",
"null"
],
"description": "Additional amount debited beyond the payout amount: fee_service_cents + fee_provider_cents."
},
"fee_service_cents": {
"type": [
"integer",
"null"
],
"description": "Key-specific service fee, from saque_fee_bps in GET /saldo."
},
"fee_provider_cents": {
"type": [
"integer",
"null"
],
"description": "Effective provider fee, fixed or percentage-based. Read the saque_taxa_provedor_* fields in GET /saldo."
},
"pix_key": {
"type": "string"
},
"pix_key_type": {
"type": "string",
"enum": [
"cpf",
"cnpj",
"phone",
"email",
"random"
]
},
"tax_number": {
"type": [
"string",
"null"
],
"description": "Masked recipient tax ID, when supplied; optional in the request."
},
"external_id": {
"type": [
"string",
"null"
],
"description": "Idempotency identifier, up to 64 characters. Keep the identifier and every request parameter unchanged on retries. Conflict detection differs by route; do not use a replay to modify an operation. 409 external_id_divergente indicates a detected conflict.",
"maxLength": 64
},
"error": {
"type": [
"string",
"null"
],
"description": "Reason when the operation is failed or refunded."
},
"e2e": {
"type": [
"string",
"null"
],
"description": "EndToEndId of the outgoing PIX payment."
},
"receiver_name": {
"type": [
"string",
"null"
],
"description": "Recipient name obtained after payment, when available; otherwise null."
},
"receiver_tax_number": {
"type": [
"string",
"null"
]
},
"paid_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"sent_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"verify_url": {
"type": [
"string",
"null"
],
"description": "Public PIX verification (GET /v1/verificar/{e2e})."
},
"created_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"updated_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"sandbox": {
"type": "boolean",
"description": "True for fictitious sandbox operations."
},
"simulation": {
"type": "object",
"additionalProperties": true
}
}
}404 Not found
JSON schema · 404
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}401 Missing, unknown or incorrect X-API-Key.
JSON schema · 401
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}GET /ping
API health check
Responses
200 pong
GET /pix/keys/lookup
Look up the PIX account holder when verification is available
Auxiliary holder lookup. When disabled, returns HTTP 200 with verified=false, available=false, verification_status=not_performed, source=disabled and null holder details. Payments remain available. When enabled, returns DICT data subject to caching and rate limits. Sandbox returns a fictitious holder with source=sandbox. HTTP 200 alone does not prove holder verification. Supply an explicit type when known.
Parameters
| Field | In | Required | Description |
|---|---|---|---|
key | query | true | PIX key: CPF, CNPJ, email, phone with or without +55, or random key. |
type | query | false | Optional. Inferred from the format when omitted. |
Responses
200 Account holder found.
JSON schema · 200
{
"type": "object",
"required": [
"pix_key",
"pix_key_type",
"owner_name",
"verified",
"source",
"checked_at"
],
"properties": {
"pix_key": {
"type": "string",
"description": "Normalized PIX key; phone numbers use the +55 format."
},
"pix_key_type": {
"type": "string",
"enum": [
"cpf",
"cnpj",
"phone",
"email",
"random"
],
"description": "Type of the queried PIX key: \"cpf\", \"cnpj\", \"phone\", \"email\" or \"random\"."
},
"owner_name": {
"type": [
"string",
"null"
],
"description": "Account holder's name as recorded in DICT, the PIX key directory.",
"examples": [
"João Silva"
]
},
"owner_tax_number": {
"type": [
"string",
"null"
],
"description": "MASKED CPF/CNPJ. Never returned in full.",
"examples": [
"***.202.745-**"
]
},
"institution_name": {
"type": [
"string",
"null"
],
"description": "Institution where the PIX key is registered.",
"examples": [
"NU PAGAMENTOS - IP"
]
},
"ispb": {
"type": [
"string",
"null"
],
"description": "Institution's eight-digit ISPB identifier.",
"examples": [
"18236120"
]
},
"verified": {
"type": "boolean",
"description": "true when holder details were retrieved or simulated (source=sandbox); false when not verified."
},
"source": {
"type": "string",
"enum": [
"dict",
"sandbox",
"disabled"
]
},
"checked_at": {
"type": "string",
"format": "date-time"
},
"cached": {
"type": "boolean",
"description": "true when the response was served from the 24-hour cache."
},
"sandbox": {
"type": "boolean",
"description": "Sandbox keys only: fictitious account holder."
},
"available": {
"type": "boolean",
"description": "false when lookup is unavailable; may accompany HTTP 200."
},
"optional": {
"type": "boolean",
"description": "Holder lookup is auxiliary and is not a payment requirement."
},
"verification_status": {
"type": "string",
"description": "not_performed when verification was not performed."
},
"detail": {
"type": "string"
}
}
}400 Invalid PIX key format (`pix_key_invalida`) or missing key (`pix_key_obrigatoria`).
JSON schema · 400
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}401 Missing, unknown or incorrect X-API-Key.
JSON schema · 401
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}404 PIX key does not exist in DICT (`chave_nao_encontrada`).
JSON schema · 404
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}429 Account limit of five lookups per minute (`limite_consultas`). Read Retry-After.
JSON schema · 429
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}503 DICT provider unavailable (`provedor_indisponivel`, retry) or lookup disabled (`consulta_indisponivel`, wait).
JSON schema · 503
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}GET /saldo
BRL balance (custody) — available, on hold, next releases
BRL balance for the house or a customer_ref subaccount. Returns available and blocked amounts, upcoming releases and effective custody conditions. Fees and waiting periods depend on the key. Local charge holds, provider holds and balance waiting periods are separate rules. Only disponivel_cents can fund withdrawals; GET /saldo/consolidado combines house and customer balances. Sandbox returns persistent fictitious balances and supports simulated deposits, withdrawals and transfers.
Parameters
| Field | In | Required | Description |
|---|---|---|---|
customer_ref | query | false | Sub-account (your end customer id). Omit for the key's main balance. |
Responses
200 OK
JSON schema · 200
{
"type": "object",
"required": [
"disponivel_cents",
"bloqueado_cents",
"total_cents"
],
"properties": {
"customer_ref": {
"type": [
"string",
"null"
],
"maxLength": 80
},
"disponivel_cents": {
"type": "integer"
},
"bloqueado_cents": {
"type": "integer"
},
"total_cents": {
"type": "integer"
},
"movimentos": {
"type": "integer"
},
"proximas_liberacoes": {
"type": "array",
"description": "Upcoming releases for the requested scope (house or customer_ref). May contain up to 200 items (before 1.44.2, at most 20); do not assume a smaller limit.",
"items": {
"type": "object",
"properties": {
"disponivel_em": {
"type": "string",
"format": "date-time"
},
"valor_cents": {
"type": "integer"
}
}
}
},
"custodia_ativa": {
"type": "boolean",
"description": "false = this key cannot hold BRL (destino \"saldo\" is refused)."
},
"carencia_horas": {
"type": "integer",
"description": "Waiting period configured for this key; zero when credits reach the balance without a waiting period. Charge holds and blocked credits remain independent."
},
"deposito_fee_bps": {
"type": "integer",
"description": "Effective deposit fee in basis points, deducted when crediting the balance."
},
"saque_taxa_estimada_cents": {
"type": "integer",
"description": "Fixed provider fee or estimated fee floor. For percentage-based fees, apply saque_taxa_provedor_formula. This is not the total fee for every withdrawal."
},
"saque_fee_bps": {
"type": "integer",
"description": "House withdrawal fee in basis points. Read this key's conditions; 100 bps = 1%."
},
"saque_cripto_fee_bps": {
"type": "integer",
"description": "House withdrawal fee in basis points. Read this key's conditions; 100 bps = 1%."
},
"primeiro_deposito_em": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "When the first deposit of this sub-account was credited (null = never deposited)."
},
"carencia_ate": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "End of the first-deposit waiting period when active; otherwise null. Also read bloqueado_cents and proximas_liberacoes."
},
"retencao_acima_cents": {
"type": "integer",
"description": "Policy threshold for the first eligible custody payment. Does not imply a hold on every deposit above this amount; payer rules and key settings also apply."
},
"deposito_fee_fixed_cents": {
"type": [
"integer",
"null"
],
"description": "Effective fixed portion of the deposit fee, in BRL cents."
},
"saque_taxa_provedor_formula": {
"type": [
"string",
"null"
],
"description": "Current formula: fixed (piso_cents) or percentage with a floor. Do not assume one provider is always active."
},
"saque_taxa_provedor_tipo": {
"type": "string",
"enum": [
"fixo",
"percentual"
],
"description": "Current payout-provider fee type."
},
"saque_taxa_provedor_piso_cents": {
"type": "integer",
"description": "Fixed fee or floor of a percentage-based fee, in BRL cents."
},
"sandbox": {
"type": "boolean",
"description": "true in the reduced test response."
}
}
}401 Missing or invalid key
GET /saldo/clientes
List customer subaccounts and balances with pagination
List each customer_ref with available, blocked and total balances. Sorted by customer_ref; continue with cursor=next_cursor. com_saldo=1 hides zero-balance subaccounts.
Parameters
| Field | In | Required | Description |
|---|---|---|---|
limit | query | false | |
cursor | query | false | next_cursor from the previous page, containing a customer_ref. |
com_saldo | query | false | 1 lists only subaccounts with a nonzero balance. |
Responses
200 Page of subaccounts.
JSON schema · 200
{
"type": "object",
"properties": {
"clientes": {
"type": "array",
"items": {
"type": "object",
"properties": {
"customer_ref": {
"type": "string",
"maxLength": 80
},
"disponivel_cents": {
"type": "integer"
},
"bloqueado_cents": {
"type": "integer"
},
"total_cents": {
"type": "integer"
},
"movimentos": {
"type": "integer"
},
"primeiro_movimento_em": {
"type": "string",
"format": "date-time"
},
"ultimo_movimento_em": {
"type": "string",
"format": "date-time"
}
}
}
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": [
"string",
"null"
]
}
}
}GET /saldo/consolidado
Consolidated custody: house plus customer balances
Sum of all custody balances controlled by this key. casa contains movements without customer_ref: partner margin, adjustments and the key's own funds. clientes sums subaccounts with customer_ref. total_custodiado_cents = casa + clientes. Use this total for financial reconciliation.
Responses
200 Consolidated balances.
JSON schema · 200
{
"type": "object",
"properties": {
"casa": {
"type": "object",
"properties": {
"disponivel_cents": {
"type": "integer"
},
"bloqueado_cents": {
"type": "integer"
},
"total_cents": {
"type": "integer"
}
}
},
"clientes": {
"type": "object",
"properties": {
"qtd": {
"type": "integer"
},
"disponivel_cents": {
"type": "integer"
},
"bloqueado_cents": {
"type": "integer"
},
"total_cents": {
"type": "integer"
}
}
},
"total_custodiado_cents": {
"type": "integer"
},
"movimentos": {
"type": "integer"
},
"ultimo_movimento_em": {
"type": [
"string",
"null"
],
"format": "date-time"
}
}
}GET /saldo/extrato
Balance statement (movements, newest first)
Parameters
| Field | In | Required | Description |
|---|---|---|---|
customer_ref | query | false | |
limit | query | false |
Responses
200 OK
JSON schema · 200
{
"type": "object",
"properties": {
"movimentos": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"valor_cents": {
"type": "integer"
},
"sentido": {
"type": "string",
"enum": [
"credito",
"debito"
]
},
"tipo": {
"type": "string",
"enum": [
"cashin",
"payout",
"cashout",
"estorno",
"ajuste"
]
},
"origem_tipo": {
"type": [
"string",
"null"
]
},
"origem_id": {
"type": [
"string",
"null"
]
},
"disponivel_em": {
"type": "string",
"format": "date-time"
},
"disponivel": {
"type": "boolean"
},
"descricao": {
"type": [
"string",
"null"
]
},
"criado_em": {
"type": "string",
"format": "date-time"
}
}
}
},
"proxima_pagina": {
"type": [
"string",
"null"
]
}
}
}401 Missing or invalid key
POST /saldo/sacar-cripto
Withdraw BRL balance as crypto to a self-custodial wallet
Convert available BRL balance to crypto. Select a route with entregavel=true from GET /cashin/catalog and supply a wallet and memo per withdrawal; no fixed wallet is needed. Liquid/DePix are not supported. Debits amount_cents plus the house fee before delivery; conversion and route costs affect the final crypto quantity. Track cashin_id at GET /cashin/{cashin_id}/status. Shares the external_id namespace with charges. There is no public withdrawal-preview endpoint.
JSON body
| Field | Type | Required | Description |
|---|---|---|---|
amount_cents | integer | true | BRL amount in integer cents. The effective minimum depends on the key, fees and route. Read GET /keys/me and returned min_brl_cents/limits; do not hardcode the example minimum. |
chain | string | false | Network (aliases accepted: sol, trc20, erc20, bep20, arbitrum, base…). Default: |
asset | string | false | Asset code in lowercase (usdt, usdc, btc, eth, sol…), as listed by GET /cashin/catalog. Default: |
payout_address | string | true | Destination wallet, validated for the network. |
tax_number | string | true | CPF (11 digits) or CNPJ (14) of the customer who owns the balance. |
customer_ref | string | false | Sub-account to debit. Omit for the key's main balance. |
external_id | string | false | Idempotency identifier, up to 64 characters. Keep the identifier and every request parameter unchanged on retries. Conflict detection differs by route; do not use a replay to modify an operation. 409 external_id_divergente indicates a detected conflict. |
payout_tag | string | false | Destination memo/tag. REQUIRED on shared-address networks such as XRP, XLM, TON, ATOM, HBAR, ALGO, EOS, KAVA and LUNA, where it identifies the recipient. Missing or invalid values return 400 |
max_debited_cents | integer | false | Optional cap on the BRL debit: amount plus house fee. Exceeding it returns 409 taxa_alterada. Does not lock the exchange rate or token quantity. |
sandbox_scenario | string | false | Only for a sandbox key. GET /sandbox provides the scenario matrix by flow. Omit in production. All prices, payments and withdrawals remain fictitious. Values: |
Request schema
{
"type": "object",
"required": [
"amount_cents",
"payout_address",
"tax_number"
],
"properties": {
"amount_cents": {
"type": "integer",
"minimum": 100,
"description": "BRL amount in integer cents. The effective minimum depends on the key, fees and route. Read GET /keys/me and returned min_brl_cents/limits; do not hardcode the example minimum."
},
"chain": {
"type": "string",
"default": "polygon",
"description": "Network (aliases accepted: sol, trc20, erc20, bep20, arbitrum, base…)."
},
"asset": {
"type": "string",
"default": "usdt",
"description": "Asset code in lowercase (usdt, usdc, btc, eth, sol…), as listed by GET /cashin/catalog."
},
"payout_address": {
"type": "string",
"description": "Destination wallet, validated for the network."
},
"tax_number": {
"type": "string",
"description": "CPF (11 digits) or CNPJ (14) of the customer who owns the balance."
},
"customer_ref": {
"type": "string",
"maxLength": 80,
"description": "Sub-account to debit. Omit for the key's main balance."
},
"external_id": {
"type": "string",
"maxLength": 64,
"description": "Idempotency identifier, up to 64 characters. Keep the identifier and every request parameter unchanged on retries. Conflict detection differs by route; do not use a replay to modify an operation. 409 external_id_divergente indicates a detected conflict."
},
"payout_tag": {
"type": "string",
"maxLength": 120,
"description": "Destination memo/tag. REQUIRED on shared-address networks such as XRP, XLM, TON, ATOM, HBAR, ALGO, EOS, KAVA and LUNA, where it identifies the recipient. Missing or invalid values return 400 `memo_obrigatorio` before creation. For XRP, the destination tag is an integer from 0 to 4294967295. Accepted aliases: `memo`, `tag`, `destination_tag`. Catalog routes requiring it have `memoRequired: true`."
},
"max_debited_cents": {
"type": "integer",
"minimum": 0,
"description": "Optional cap on the BRL debit: amount plus house fee. Exceeding it returns 409 taxa_alterada. Does not lock the exchange rate or token quantity."
},
"sandbox_scenario": {
"type": "string",
"enum": [
"success",
"delayed",
"held",
"expired",
"refunded",
"failed",
"payer_mismatch",
"settlement_failed",
"settlement_uncertain",
"route_unavailable",
"provider_unavailable"
],
"description": "Only for a sandbox key. GET /sandbox provides the scenario matrix by flow. Omit in production. All prices, payments and withdrawals remain fictitious."
}
}
}Responses
200 Debited and queued for delivery. Same view as POST /cashin/charge (cashin_id, status = `paid` — the balance is the payment —, chain, asset, payout_address, amount_cents, settlement_status, settlement_tx_hash) plus `fee_cents` (house fee debited), `debited_cents` (amount + fee), `fonte: "saldo"`, `destino: "cripto"`, `customer_ref`. Follow `settlement_status` on GET /cashin/{cashin_id}/status until `sent`.
JSON schema · 200
{
"allOf": [
{
"$ref": "#/components/schemas/Cobranca"
},
{
"type": "object",
"properties": {
"settlement_status": {
"type": [
"string",
"null"
],
"description": "Credit/delivery state: sent means completed; incerto requires reconciliation. PIX payment and delivery are separate states.",
"enum": [
"pending",
"sending",
"entregando",
"sent",
"incerto",
"failed",
null
]
},
"settlement_tx_hash": {
"type": [
"string",
"null"
],
"description": "On-chain delivery hash, or internal identifier when delivery uses an exchange."
},
"fee_cents": {
"type": "integer",
"description": "House withdrawal fee debited in addition to amount_cents."
},
"debited_cents": {
"type": "integer",
"description": "amount_cents plus the house withdrawal fee."
}
}
}
]
}400 rede_indisponivel | asset_invalido | payout_address_invalido | documento_invalido | valor_abaixo_do_minimo. `memo_obrigatorio` means the required memo/tag is missing or invalid.
402 saldo_insuficiente — available < amount + fee. Body carries `saldo` and `fee_cents`.
409 external_id_divergente
423 carencia_primeiro_deposito — first-deposit hold (only keys with a contractual holding period); `libera_em` says when.
503 entrega_indisponivel — no stock/route to deliver right now; nothing was debited.
POST /saldo/transferir
Transfer balance internally between subaccounts and the house
Move AVAILABLE balance between an end customer's customer_ref and the house ("casa", the key's own balance), or between two customers, without PIX. Common uses include collecting a fee, crediting a bonus or returning funds. Frozen funds (24-hour holds or MED holds) cannot move. A source subaccount in its contractual first-deposit waiting period returns 423. Idempotent by external_id. Emits saldo.transferido.
JSON body
| Field | Type | Required | Description |
|---|---|---|---|
from_customer_ref | string | true | Source customer_ref, or |
to_customer_ref | string | true | Destination customer_ref, or |
amount_cents | integer | true | |
descricao | string | false | Description shown on both sides' statements. |
external_id | string | false | Idempotency identifier, up to 64 characters. Keep the identifier and every request parameter unchanged on retries. Conflict detection differs by route; do not use a replay to modify an operation. 409 external_id_divergente indicates a detected conflict. |
Request schema
{
"type": "object",
"required": [
"from_customer_ref",
"to_customer_ref",
"amount_cents"
],
"properties": {
"from_customer_ref": {
"type": "string",
"description": "Source customer_ref, or `\"casa\"`."
},
"to_customer_ref": {
"type": "string",
"description": "Destination customer_ref, or `\"casa\"`."
},
"amount_cents": {
"type": "integer",
"minimum": 1
},
"descricao": {
"type": "string",
"maxLength": 140,
"description": "Description shown on both sides' statements."
},
"external_id": {
"type": "string",
"maxLength": 64,
"description": "Idempotency identifier, up to 64 characters. Keep the identifier and every request parameter unchanged on retries. Conflict detection differs by route; do not use a replay to modify an operation. 409 external_id_divergente indicates a detected conflict."
}
}
}Responses
201 Transfer completed.
JSON schema · 201
{
"type": "object",
"properties": {
"transfer_id": {
"type": "string"
},
"from_customer_ref": {
"type": [
"string",
"null"
]
},
"to_customer_ref": {
"type": [
"string",
"null"
]
},
"amount_cents": {
"type": "integer"
},
"descricao": {
"type": [
"string",
"null"
]
},
"created_at": {
"type": "string",
"format": "date-time"
},
"movimentos": {
"type": "object"
},
"saldos": {
"type": "object",
"description": "Both balances after the transfer."
}
}
}200 Idempotent replay (`idempotente: true`).
400 valor_invalido (invalid amount), origem_igual_destino (same source and destination), or custodia_desligada (custody disabled).
409 saldo_insuficiente (insufficient funds, with disponivel_cents/bloqueado_cents), or external_id_divergente (idempotency conflict).
423 carencia_primeiro_deposito: source subaccount is in its first-deposit waiting period.
GET /sandbox
Discover sandbox capabilities
Supported journeys, scenarios by flow, QR semantics, limits and simulation control routes.
Responses
200 Sandbox result; sandbox=true; no real funds move.
JSON schema · 200
{
"type": "object",
"additionalProperties": true
}401 Missing or invalid key.
403 Requires a sandbox key.
404 Operation not found for this key.
409 State conflict or divergent idempotency parameters.
503 Simulator unavailable; never falls through to a real provider.
POST /sandbox/cashin/{cashin_id}/pay
Simulate payment of a test PIX charge
Only the owning sandbox key can confirm. Replays never duplicate credits. This endpoint cannot confirm a production payment.
Parameters
| Field | In | Required | Description |
|---|---|---|---|
cashin_id | path | true |
JSON body
| Field | Type | Required | Description |
|---|---|---|---|
payer_tax_number | string | false | Optional synthetic payer document; a mismatch simulates a refund. |
Request schema
{
"type": "object",
"properties": {
"payer_tax_number": {
"type": "string",
"description": "Optional synthetic payer document; a mismatch simulates a refund."
}
},
"required": []
}Responses
200 Sandbox result; sandbox=true; no real funds move.
JSON schema · 200
{
"type": "object",
"additionalProperties": true
}401 Missing or invalid key.
403 Requires a sandbox key.
404 Operation not found for this key.
409 State conflict or divergent idempotency parameters.
503 Simulator unavailable; never falls through to a real provider.
GET /sandbox/events
Inspect generated sandbox events
Returns generated events even if no webhook was configured. Use /webhooks/deliveries for actual callback attempts.
Parameters
| Field | In | Required | Description |
|---|---|---|---|
limit | query | false |
Responses
200 Sandbox result; sandbox=true; no real funds move.
JSON schema · 200
{
"type": "object",
"additionalProperties": true
}401 Missing or invalid key.
403 Requires a sandbox key.
404 Operation not found for this key.
409 State conflict or divergent idempotency parameters.
503 Simulator unavailable; never falls through to a real provider.
POST /sandbox/operations/{operation_id}/resolve
Resolve an uncertain sandbox operation
Only a test operation already in an uncertain state can be resolved. Same outcome can be replayed safely.
Parameters
| Field | In | Required | Description |
|---|---|---|---|
operation_id | path | true |
JSON body
| Field | Type | Required | Description |
|---|---|---|---|
outcome | string | true | Values: |
Request schema
{
"type": "object",
"properties": {
"outcome": {
"type": "string",
"enum": [
"sent",
"failed"
]
}
},
"required": [
"outcome"
]
}Responses
200 Sandbox result; sandbox=true; no real funds move.
JSON schema · 200
{
"type": "object",
"additionalProperties": true
}400 Missing outcome, or a value other than sent and failed: erro outcome_invalido, acao corrigir, sandbox=true. Checked before the operation is looked up, and nothing changes in the simulator (since 1.44.2; before, a body without outcome could return 200 without resolving anything).
401 Missing or invalid key.
403 Requires a sandbox key.
404 Operation not found for this key.
409 State conflict or divergent idempotency parameters.
503 Simulator unavailable; never falls through to a real provider.
GET /sandbox/qr/{cashin_id}.svg
Non-payable sandbox QR image
Encodes SANDBOX:NAO_PAGAVEL:<id>; not a bank PIX code. No payment action or customer data.
Parameters
| Field | In | Required | Description |
|---|---|---|---|
cashin_id | path | true |
Responses
200 Synthetic SVG QR.
POST /sandbox/reset
Reset this key’s fictitious state
Deletes only the owning key’s simulated state. Previously queued webhook deliveries retain their history. Production keys are refused.
JSON body
| Field | Type | Required | Description |
|---|---|---|---|
confirm | boolean | true |
Request schema
{
"type": "object",
"properties": {
"confirm": {
"type": "boolean",
"const": true
}
},
"required": [
"confirm"
]
}Responses
200 Sandbox result; sandbox=true; no real funds move.
JSON schema · 200
{
"type": "object",
"additionalProperties": true
}401 Missing or invalid key.
403 Requires a sandbox key.
404 Operation not found for this key.
409 State conflict or divergent idempotency parameters.
503 Simulator unavailable; never falls through to a real provider.
GET /v1/verificar/{e2e}
Verify a PIX payment publicly, without an API key
Check a payment independently of the sender's claim. No account or API key required.
Does not return the PIX key, full name or tax ID, avoiding disclosure of the parties' identity.
A not-found response explicitly states that another institution may have processed the PIX. Absence here is not evidence that no payment occurred.
Parameters
| Field | In | Required | Description |
|---|---|---|---|
e2e | path | true | Central Bank identifier: E followed by 32 characters. |
Responses
200 Payment settled through Lunium.
JSON schema · 200
{
"type": "object",
"properties": {
"verificado": {
"type": "boolean"
},
"pago": {
"type": "boolean"
},
"e2e": {
"type": "string",
"description": "Central Bank end-to-end identifier, echoed from the request: E followed by the receipt code. Any third party can verify it using this endpoint."
},
"valor_brl": {
"type": "string"
},
"pago_em": {
"type": "string",
"format": "date-time",
"example": "2026-08-01T22:35:49-03:00",
"description": "ISO 8601 timestamp with an explicit time-zone offset (Brasilia time). Do not assume UTC or the client's local time; read the supplied offset."
},
"recebedor_iniciais": {
"type": [
"string",
"null"
]
},
"instituicao": {
"type": [
"string",
"null"
]
},
"liquidado_por": {
"type": "string"
},
"comprovante_url": {
"type": [
"string",
"null"
]
}
}
}404 Not settled through Lunium; another institution may have processed it.
400 Invalid format.
GET /webhooks/deliveries
Webhook delivery history for this key
Diagnose what was sent, what failed and why. Does not return the event body; use retry to resend the original body.
Parameters
| Field | In | Required | Description |
|---|---|---|---|
status | query | false | |
event | query | false | |
limit | query | false |
Responses
200 Deliveries, newest first.
JSON schema · 200
{
"type": "object",
"properties": {
"deliveries": {
"type": "array",
"items": {
"$ref": "#/components/schemas/EntregaWebhook"
}
},
"failed_count": {
"type": "integer",
"description": "Number of deliveries in this response that exhausted their attempts."
}
}
}400 Invalid filter.
JSON schema · 400
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}401 Missing, unknown or incorrect X-API-Key.
JSON schema · 401
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}POST /webhooks/deliveries/{event_id}/retry
Retry an event delivery
Attempt delivery immediately and return the result. If unsuccessful, return the delivery to the queue with 12 new attempts. Refuses to resend a delivery already acknowledged with 2xx.
Parameters
| Field | In | Required | Description |
|---|---|---|---|
event_id | path | true |
Responses
200 Delivered immediately.
JSON schema · 200
{
"type": "object",
"properties": {
"event_id": {
"type": "string"
},
"delivered": {
"type": "boolean",
"const": true
},
"status_code": {
"type": "integer"
},
"ms": {
"type": "integer"
},
"delivery_id": {
"type": "string"
}
}
}202 Not delivered immediately; returned to the retry queue.
404 Not found for this key.
JSON schema · 404
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}409 Already delivered; replaying would duplicate delivery.
JSON schema · 409
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}401 Missing, unknown or incorrect X-API-Key.
JSON schema · 401
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}POST /webhooks/test
Send a webhook test event now
Send webhook.test to your webhook_url using the SAME transport as production and return your endpoint's HTTP status and latency. No funds move and nothing is queued. Use before the first real charge. Limited to six tests per minute.
Responses
200 Your endpoint returned 2xx.
JSON schema · 200
{
"type": "object",
"properties": {
"ok": {
"type": "boolean"
},
"event_id": {
"type": "string"
},
"delivery_id": {
"type": "string"
},
"url": {
"type": "string"
},
"status_code": {
"type": "integer"
},
"ms": {
"type": "integer"
}
}
}400 webhook_url is not configured.
JSON schema · 400
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}429 More than six tests per minute.
JSON schema · 429
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}502 Your endpoint did not return 2xx. The response body describes what happened.
JSON schema · 502
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}401 Missing, unknown or incorrect X-API-Key.
JSON schema · 401
{
"type": "object",
"description": "API error. Fields may vary by route, including infrastructure responses. Interpret the HTTP status together with erro and acao when present; detail is for display, not control flow. Accept unknown error codes.",
"properties": {
"erro": {
"type": "string",
"description": "Stable error code. Branch on this field, never on the detail text. This list is generated from codes actually emitted by the API.",
"x-known-values": [
"amount_invalido",
"asset_invalido",
"br_code_indisponivel",
"br_code_sem_valor",
"brl_amount_invalido",
"campos_conflitantes",
"campos_obrigatorios",
"carencia_primeiro_deposito",
"cashin_indisponivel",
"cashout_indisponivel",
"catalogo_indisponivel",
"chave_ausente",
"chave_desconhecida",
"chave_incorreta",
"chave_nao_encontrada",
"conflito",
"consulta_indisponivel",
"corpo_grande_demais",
"cotacao_expirada",
"cotacao_indisponivel",
"custodia_desligada",
"deposit_obrigatorio",
"destino_invalido",
"documento_invalido",
"em_processamento",
"email_invalido",
"endpoint_nao_respondeu",
"erro_interno",
"external_id_divergente",
"formato_invalido",
"ja_entregue",
"limite_consultas",
"limite_de_chaves_teste",
"limite_diario",
"limite_diario_recebedor",
"limite_do_pagador",
"limite_indisponivel",
"liquidante_indisponivel",
"mandate_contraparte_nao_autorizada",
"mandate_valor_acima_do_teto",
"memo_obrigatorio",
"metodo_nao_permitido",
"muitas_tentativas",
"nao_autenticado",
"nao_encontrado",
"nao_permitido",
"nao_processavel",
"origem_igual_destino",
"pagador_recusado_pelo_provedor",
"payer_tax_invalido",
"payer_tax_number_invalido",
"payout_address_invalido",
"payout_address_obrigatorio",
"payout_nao_liberado",
"payout_recusado",
"pix_key_invalida",
"pix_key_obrigatoria",
"provedor_indisponivel",
"provedor_sem_resposta",
"rate_limit",
"rede_indisponivel",
"refund_address_invalida",
"requisicao_invalida",
"saldo_insuficiente",
"sandbox_sem_cashin",
"sandbox_sem_saldo",
"sandbox_sem_saque",
"saque_comissao_diario",
"saque_indisponivel",
"status_invalido",
"taxa_alterada",
"tempo_esgotado",
"temporariamente_indisponivel",
"tipo_ambiguo",
"valor_abaixo_do_minimo",
"valor_acima_do_maximo",
"valor_invalido",
"webhook_nao_configurado",
"webhook_url_invalida"
]
},
"acao": {
"type": "string",
"enum": [
"corrigir",
"repetir",
"esperar",
"parar",
"falar_com_suporte"
],
"description": "corrigir = fix the request; an identical retry will fail. repetir = transient failure; retry. esperar = wait for the quota to renew. parar = stop retrying and contact us. falar_com_suporte = do not retry in a loop; preserve request_id and external_id and contact Lunium (for example, config_provedor)."
},
"detail": {
"type": "string",
"description": "Human-readable explanation. Never branch on this text."
},
"limits": {
"type": "object",
"description": "Included in limit errors, already expressed in the order's currency."
},
"docs": {
"type": "string",
"format": "uri"
},
"request_id": {
"type": "string",
"description": "Request identifier, also returned in the X-Request-ID header. Include it when contacting support. A supplied X-Request-ID matching [A-Za-z0-9._:-]{8,64} is preserved end to end.",
"examples": [
"req_62f05f21b3794830a241"
]
},
"code": {
"type": "string",
"deprecated": true,
"description": "LEGACY alias of `erro`. SUNSET: no longer returned from 2026-11-09. Use the canonical `erro` field for control flow. This alias is never returned without `erro`."
}
}
}Human support and live tracking
Human support group strongly recommended: Lunium or the partner can create the project group and add @luniumb2b and @luniumb2c, alongside @LuniumNotifyBot. Read the group setup guide. Use the private monitor from /keys/me and implement webhooks, live tracking and reconciliation. Never expose credentials, secrets or the monitor to unauthorized users.
Create your production key in 60 seconds
One call, no human approval, no waiting: the lun_live_ key is created in the same response, same as the sandbox one. Just testing? POST /keys/sandbox with your email returns a sandbox key in the same call. See the step by step.
Lunium Partners
Official integrator community for operational notices, maintenance, API changes and partner discussions. Participation is strongly recommended from the beginning of integration.
Join Lunium PartnersParticipation guideOperations and reconciliation
Configure commission, understand fees, recover monitor access and handle incidents using the current contract.
Fees and commissionRecover accessIncident runbook