Rotas e campos reservados¶
Para: Dev — Conferido em 2026-10-18.
O contrato 1.1.0 define câmbio, recebimentos bancários, recall de saque e transferência bancária (wire e SWIFT). O Dracma publica essas rotas no documento OpenAPI, mas nenhuma operação tem câmbio nem trilho bancário habilitado. Esta página mostra o que cada rota responde hoje, o que cada campo reservado vale e o que o seu código deve fazer para continuar correto.
O que é¶
Não disponível
O Dracma não oferece hoje câmbio, cotação de moeda, recebimento de transferência bancária (wire ou SWIFT) nem recall de saque. As rotas existem para manter o
contrato 1.1.0 inteiro, mas respondem sempre com um erro do catálogo ou com uma lista vazia, sem criar nem alterar nada. O único método de depósito e de saque é pix, em BRL.
| Rota | Escopo | operationId |
Resposta hoje |
|---|---|---|---|
POST /v1/withdrawals/{id}/recall |
withdrawals:write |
pedirRecallDeSaque |
saque da operação: 409 invalid_state_transition; saque inexistente ou de outra operação: 404; corpo inválido: 400 |
POST /v1/fx/quotes |
deposits:write ou withdrawals:write |
criarCotacao |
corpo válido: 422 fx_not_enabled; corpo inválido: 400 |
GET /v1/fx/quotes/{id} |
read |
obterCotacao |
sempre 404 not_found |
GET /v1/receipts |
read |
listarRecebimentos |
200 com {"data": [], "next_cursor": null}; parâmetro inválido: 400 |
GET /v1/receipts/{id} |
read |
obterRecebimento |
sempre 404 not_found |
POST /v1/sandbox/bank-transfers/incoming |
deposits:write |
sandboxTransferenciaRecebida |
corpo válido: 400 rail_not_enabled; corpo inválido: 400 validation_failed; em operação Real: 404 |
Essas rotas existem desde o ajuste de 2026-10-02: antes disso respondiam 404 de rota inexistente. Veja OpenAPI.
Quando usar¶
Na prática, não use. O que importa para o seu conector:
- Não monte telas nem fluxos que dependam de câmbio, recibo bancário ou recall: o Dracma não os atende.
- Um cliente gerado a partir do OpenAPI vai ter métodos para essas rotas. Elas existem para o contrato fechar, não para uso.
- O seu código deve tolerar os estados, campos e eventos reservados (seção "Campos, estados e eventos reservados"). Assim, nada quebra se um dia forem preenchidos.
Como funciona¶
Recall de saque: POST /v1/withdrawals/{id}/recall¶
Recall só vale para saque wire ou SWIFT já enviado. Todo saque do Dracma é PIX, então não há caminho de sucesso. A API confere, nesta ordem:
idfora do formatowdr_mais letras e números:404 not_found.- Corpo:
reason_codeé obrigatório e deve ser um destes:duplicate,wrong_beneficiary,wrong_amount,fraud_suspected,other.justificationé opcional, até 1000 caracteres. Corpo fora disso:400 validation_failed(enumpara o motivo,max_lengthpara a justificativa, e as demais razões do corpo estrito). - Saque inexistente, ou de outra operação:
404 not_found. - Saque existente da operação:
409 invalid_state_transition. Nada muda no saque, qualquer que seja o estado dele.
Para desfazer um saque que ainda não foi enviado, use o cancelamento descrito em Saques.
Cotação de câmbio: POST /v1/fx/quotes e GET /v1/fx/quotes/{id}¶
POST /v1/fx/quotes valida o corpo, confere o escopo e responde 422 fx_not_enabled. A ordem:
- Corpo que não é JSON válido ou tem campo desconhecido:
400 validation_failed,field: body,reason: invalid_json. -
Campos fora do schema, com
reason: invalid:errors[0].fieldRegra purposeobrigatório: depositouwithdrawalsell_currencysell_currencyebuy_currencyobrigatórias e diferentessell_amountexatamente um entre sell_amountebuy_amount, nunca os dois nem nenhumsell_amount,buy_amounttexto de inteiro na menor unidade, sem zero à esquerda, até 38 dígitos -
Escopo conforme o
purpose:deposits:writeparadeposit,withdrawals:writeparawithdrawal. Sem ele:403 insufficient_scope. - Corpo válido:
422 fx_not_enabled. Nenhuma cotação é criada, de nenhuma operação.
GET /v1/fx/quotes/{id} responde sempre 404 not_found, com id bem ou mal formado: não há como saber se uma cotação existe.
Os campos fx_quote_id e payout_currency não têm efeito. No depósito, fx_quote_id é recusado (unknown_field); no saque, fx_quote_id, payout_currency e purpose
são aceitos pela forma e ignorados. Veja Divergências conhecidas.
Recebimentos bancários: GET /v1/receipts e GET /v1/receipts/{id}¶
Um recebimento seria um crédito bancário (wire ou SWIFT) que não casou com um depósito. Como nenhuma operação tem trilho bancário, nenhum recebimento existe.
GET /v1/receiptsvalida os parâmetros do contrato e devolve{"data": [], "next_cursor": null}. É uma rota de listagem e usa o balde de listagem do rate limit.- Os parâmetros são validados:
statusprecisa estar emunmatched,matched,returned,frozen(reason: enum);limitde 1 a 200 (range);updated_sinceem RFC 3339 (format). - Qualquer
cursoré inválido:400comreason: format, porque a API nunca emitiu um cursor de recebimento. Não é uma página vazia. GET /v1/receipts/{id}responde sempre404 not_found, sem distinguir id bem ou mal formado.
Transferência bancária simulada: POST /v1/sandbox/bank-transfers/incoming¶
Rota de sandbox que simularia um crédito bancário entrante. Em operação Teste ela exige deposits:write e Idempotency-Key, valida o corpo e responde
400 rail_not_enabled: nada é casado nem criado. Em operação Real ela não existe (404).
Corpo (amount e rail são obrigatórios):
| Campo | Regra |
|---|---|
amount |
Money: amount é texto de inteiro sem zero à esquerda, até 38 dígitos; currency é o código da moeda em maiúsculas |
rail |
^[a-z][a-z0-9_]{1,31}$ |
reference |
até 140 caracteres |
payer_name |
até 140 caracteres |
payer_document |
type em CPF, CNPJ, PASSPORT, NATIONAL_ID, TAX_ID; number de 1 a 32 caracteres; country ISO alfa-2 |
payer_country |
ISO alfa-2 |
screening |
clear ou hit |
Corpo fora disso: 400 validation_failed com reason: invalid e o campo em errors[0].field. Corpo válido: 400 com code: rail_not_enabled e errors[0] = {field: "rail", reason: "rail_not_enabled"}.
Nenhuma operação tem trilho habilitado, então não existe corpo que resulte em sucesso. Nem uma reference de um depósito seu faz diferença: a rota não lê depósito algum.
Campos, estados e eventos reservados¶
Reservado no contrato
Tudo o que está nesta seção existe no contrato 1.1.0 (e, para Saque, também no documento OpenAPI servido), mas o Dracma não preenche, não emite ou não alcança hoje. Trate como informativo e aplique o leitor tolerante.
| Onde | O que | Valor hoje |
|---|---|---|
Deposito |
rail, received_amount, receipts, fee, fees, fx, compliance, expected_settlement_date, return |
não são devolvidos |
Saque |
rail, fees, charge_bearer, fx, purpose, compliance, expected_settlement_date, sent_at, tracking, recall |
null, e fees é [] |
Saque |
fee |
null. Sem tarifa descontada do saque |
Saque |
return |
preenchido em returned. Não é reservado. Veja Saques |
Moeda |
rails |
não é devolvido |
Metodo |
card, crypto, boleto, bank_transfer, wire, swift |
400 method_not_enabled |
StatusDeposito |
pending_compliance, frozen, paid_partial |
nenhum depósito chega a esses estados |
StatusSaque |
pending_compliance, sent, in_transit, recall_requested, recalled |
nenhum saque chega a esses estados; só valem como filtro de status |
| Eventos | deposit.pending_compliance, deposit.frozen, deposit.paid_partial, withdrawal.pending_compliance, withdrawal.sent, withdrawal.in_transit, withdrawal.recall_requested, withdrawal.recall_rejected, withdrawal.recalled, receipt.unmatched, receipt.matched, receipt.returned, receipt.frozen |
não são emitidos. Veja Catálogo de eventos |
Reconciliacao |
kind fee, recall, receipt; fee do item; totals.fees |
sem itens desses kind; fee é null; totals.fees é "0". Veja Reconciliação |
Cambio, Compliance, RastreioBancario, Recall, Recebimento, Tarifa, TrilhoDisponivel |
schemas inteiros | nunca devolvidos hoje |
Exemplos¶
Cotação com corpo válido, resposta 422:
POST /v1/fx/quotes HTTP/1.1
Host: api.example.test
Content-Type: application/json; charset=utf-8
Idempotency-Key: fxq-0192a3b4-5c6d-7e8f-9a0b-1c2d3e4f5a6b
Dracma-Key-Id: key_test_01J9EXEMPLO
Dracma-Timestamp: 1790000000
Dracma-Nonce: 0123456789abcdef0123456789abcdef
Dracma-Signature: v1=<assinatura>
{
"purpose": "deposit",
"sell_currency": "USD",
"buy_currency": "BRL",
"sell_amount": "10000"
}
{
"type": "https://docs.dracma.test/errors/fx_not_enabled",
"title": "fx_not_enabled",
"status": 422,
"code": "fx_not_enabled",
"trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
"retryable": false
}
Recall de um saque PIX da sua operação. Corpo do pedido:
{
"reason_code": "duplicate",
"justification": "Pedido duplicado por falha do meu conector."
}
Resposta 409:
{
"type": "https://docs.dracma.test/errors/invalid_state_transition",
"title": "invalid_state_transition",
"status": 409,
"code": "invalid_state_transition",
"trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
"retryable": false
}
Listagem de recebimentos, resposta 200:
{
"data": [],
"next_cursor": null
}
Transferência simulada com corpo válido, resposta 400:
{
"type": "https://docs.dracma.test/errors/rail_not_enabled",
"title": "rail_not_enabled",
"status": 400,
"code": "rail_not_enabled",
"trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
"retryable": false,
"errors": [
{
"field": "rail",
"message": "trilho não habilitado na operação",
"reason": "rail_not_enabled"
}
]
}
Erros e casos de borda¶
| Situação | Resposta |
|---|---|
| Qualquer das rotas sem o escopo exigido | 403 insufficient_scope |
POST sem Idempotency-Key |
400 validation_failed |
| Rota de sandbox em operação Real | 404 not_found (nunca 403) |
422 fx_not_enabled e 400 rail_not_enabled |
recusas definitivas: não repita |
409 invalid_state_transition no recall |
definitiva: o recall não se aplica a saque PIX |
- Uma recusa
4xxguardada pela idempotência volta igual por 30 dias. Veja Idempotência e repetição. GET /v1/receiptsconta no balde de listagem: não faça polling nela.
Veja também¶
- Saques e Depósitos: o que é de fato oferecido.
- Objetos e campos: a coluna "devolvido hoje?".
- Catálogo de eventos
- Divergências conhecidas