Problemas de integração¶
Para: Dev — Conferido em 2026-10-18.
Roteiro de diagnóstico para os problemas mais comuns ao chamar a API: 401 por relógio ou corpo, 403, 404, 409,
429 e 503 em laço, e ambiente errado. Parta do sintoma, confirme a causa e aplique a correção.
O que é¶
Cada seção começa pelo que você vê (o status e o code) e termina no que fazer. A API confere as coisas numa ordem
fixa (Autenticação HMAC), e o primeiro problema é o que volta: use isso para eliminar causas.
Problemas de webhook estão em Problemas comuns de webhook; problemas de dinheiro (saldo, estado parado), em Runbook de dinheiro.
Quando usar¶
Quando uma chamada falha e você não sabe por quê, e antes de abrir um chamado. Guarde o Dracma-Trace-Id de toda
resposta que não seja 2xx: com ele o suporte acha a requisição.
Como funciona¶
Passo zero: reproduza os vetores¶
Antes de qualquer outra hipótese, faça o seu código produzir os três vetores de
vetores-assinatura.json (mesma assinatura, byte a byte). Se não produz, o
problema é local e não de rede nem do Dracma. Imprima o pedido canônico com cat -A ou equivalente: um $ no fim da
última linha é um \n que não pode existir.
401: autenticação¶
timestamp_out_of_window
| Causa provável | Como confirmar | Correção |
|---|---|---|
| Relógio do servidor fora de ±300 s | Compare o cabeçalho Date da resposta (vem também no erro) com date -u no seu servidor |
Ative o NTP (chronyc tracking); alerte desvio acima de 5 s |
| Timestamp em milissegundos | O valor tem 13 dígitos | floor(agora_ms / 1000) |
| Formato fora do canônico | Tem +, espaço, zero à esquerda, casa decimal ou notação científica |
Inteiro simples, sem formatação |
| Assinou com um timestamp e enviou outro | O cabeçalho difere do usado no canônico | Calcule uma vez e reuse na assinatura e no cabeçalho |
| Relógio do contêiner diferente do host (VM pausada, snapshot restaurado) | O desvio aparece só em uma máquina | Sincronize ao restaurar |
invalid_signature: é o código mais genérico, de propósito (o Dracma não revela se a chave existe).
| Causa provável | Como confirmar | Correção |
|---|---|---|
Segredo errado, de outra chave, ou com \n ou espaço no fim |
Reproduza o vetor com o segredo lido do seu cofre | Leia o segredo sem a quebra de linha; confira o key_id |
Dracma-Key-Id digitado errado |
Chave "inexistente" e assinatura errada voltam o mesmo 401 |
Copie o key_id do painel |
| Corpo diferente do assinado | Só POST falha; reserializou o JSON, mudou a ordem das chaves ou o espaçamento |
Serialize uma vez; assine e envie os mesmos bytes |
Biblioteca HTTP recodifica o corpo (compressão, charset) |
Compare o sha256 do corpo no seu log com o do pedido de rede (proxy de depuração) |
Envie o corpo cru, sem compressão |
Caminho sem /v1, ou com host na frente |
O canônico tem /deposits em vez de /v1/deposits |
Assine o caminho completo |
| Query reordenada ou decodificada | Só GET com parâmetros falha |
Assine a URL exatamente como enviada (curl --path-as-is) |
| Método em minúsculas | O canônico tem post |
Maiúsculas |
| Nonce com maiúscula ou com menos de 32 caracteres | O nonce não casa ^[0-9a-f]{32}$ |
openssl rand -hex 16 ou equivalente |
| Segredo usado decodificado (hexadecimal ou base64) | O vetor só passa decodificando | Use os bytes da própria string |
| Um proxy ou balanceador seu muda o caminho ou o corpo | A assinatura passa em chamada direta e falha atrás do proxy | Assine o que sai do proxy ou desligue a reescrita |
Sobre 429 no lugar de 401: depois de 20 falhas de assinatura por minuto do mesmo IP, o Dracma passa a responder
429 rate_limited. Pare o laço, corrija a causa e espere o Retry-After.
replayed_nonce
| Causa provável | Correção |
|---|---|
| O retry reutiliza o nonce da primeira tentativa | Gere o nonce dentro da função que monta cada tentativa |
| Dois processos usam um gerador com a mesma semente | Use o gerador do sistema (crypto/rand, random_bytes) |
| O mesmo pedido é enviado duas vezes por um proxy de repetição | Desligue o retry automático do proxy e deixe a repetição para o conector |
unknown_key
| Causa provável | Como confirmar | Correção |
|---|---|---|
Tipo da chave não bate com o host (key_test_ na API Real, ou o contrário) |
O prefixo da chave e o host da sua base | Use o par chave-host certo (Ambientes, tipos de operação e hosts) |
| Chave revogada | O painel mostra a chave como Revogada | Crie outra |
Dracma-Key-Id ausente ou mal formado |
O cabeçalho some em algum proxy | Verifique os cabeçalhos que chegam |
403: autorização¶
Um 403 quer dizer que a autenticação passou: a assinatura está certa.
code |
Causa | Correção |
|---|---|---|
insufficient_scope |
A chave não tem o escopo da rota; ou você usou um método que a API não tem (PUT, DELETE, OPTIONS); ou fez POST em rota que não existe |
Compare a rota com a tabela de escopos; use a chave do componente certo |
operation_suspended |
Operação suspensa pelo Dracma | FAQ: operação suspensa |
ip_not_allowed |
Chave válida usada de origem fora da lista de IPs da operação | Use o IP público de saída do conector. Se o IP mudou ou é dinâmico, peça a inclusão do novo IP (aprovação e espera de 24 h) ou remova a lista; veja IPs do conector |
400, 404, 409 e 422¶
| Sintoma | Causa | Correção |
|---|---|---|
400 validation_failed com unknown_field |
Campo que o schema não tem (inclusive status, version, paid_amount) |
Remova o campo; a API não aceita campo "extra" |
400 com field: Idempotency-Key |
POST sem Idempotency-Key, ou com menos de 16 caracteres |
16 a 128 caracteres [A-Za-z0-9_.:-] |
400 com field: amount |
Valor como número, decimal ou com zeros à esquerda | Money (Convenções HTTP) |
400 com reason: required_by_operation |
A operação exige um campo que o contrato deixa opcional | Mande o campo; consulte GET /currencies |
400 com reason: reserved_domain_required |
E-mail de jogador real em operação Teste | Use .test, .invalid ou .example |
404 not_found em objeto que existe |
O objeto é de outra operação, ou o id tem outro formato |
Confira a chave e o id |
404 em rota que existe |
GET em rota só POST, ou caminho sem /v1 |
Método e caminho |
404 sem corpo |
Caminho fora de /v1/*, ou /v1/sandbox/* em operação Real |
Corrija a base; sandbox só em Teste |
409 idempotency_key_reused |
Mesma chave com outro corpo, rota ou query | Reenvie os bytes originais, ou use chave nova e external_id novo (operação nova) |
409 duplicate_external_id |
O external_id já existe |
Leia existing; concilie em vez de criar outro |
409 invalid_state_transition |
O estado atual não permite a ação (cancelar saque já enviado, por exemplo) | GET do objeto e decida |
422 |
Recusa de negócio (limite, lista, documento, caixa) | Erros; não repita igual |
429 e 503 em laço¶
Um laço de repetição sem espera é a causa mais comum de 429 e piora o 503.
- Leia o
Retry-Aftere espere esse tempo, no mínimo. Sem o cabeçalho, use backoff exponencial com jitter (1 s, 2 s, 4 s, até 60 s). - Descubra qual balde estourou. Escrita (50/s, rajada 100), leitura (100/s por chave), listagem (5/s) ou jogador
(10 depósitos e 3 saques por hora) — Limites e quotas.
Retry-Afterde minutos é balde de jogador. - Ponha uma fila e um teto de concorrência no conector: dispare a uma taxa abaixo do teto, nunca em rajada de lote.
- Use um disjuntor. Depois de N falhas seguidas, pare por um intervalo e teste com
GET /v1/pingantes de voltar. - Mantenha a mesma
Idempotency-Keyem toda repetição de umPOST.429e5xxliberam a chave; a repetição nunca duplica. 503repetido por minutos é problema do Dracma ou de uma dependência dele: junte oDracma-Trace-Idde duas ou três respostas e abra chamado (Suporte). Não crie objetos novos para "driblar": consulte porexternal_id(Idempotência e repetição).503comRetry-After: 5em operação Teste pode ser a queda simulada ligada porPOST /sandbox/outage: desligue com{"down": false}.
Ambiente errado¶
Sintomas típicos: 401 unknown_key com a chave certa; 404 em /v1/sandbox/...; depósito que "não aparece" no painel; ou
dinheiro movendo quando você achava que era teste.
- Chame
GET /v1/pinge leiaenvironment:sandboxé operação Teste;productioné operação Real. - Compare com o prefixo da chave (
key_test_oukey_live_) e com o host da sua base (Ambientes, tipos de operação e hosts). - Confira se o painel que você olha é o do mesmo ambiente (hml e produção são painéis distintos).
- Guarde uma configuração por ambiente (base,
key_id, segredo, segredo de webhook) e nunca misture.
Dinheiro real
Operação Real cobra e paga de verdade, inclusive no hml. Se você não tem certeza do tipo da chave, rode GET /v1/ping
antes de qualquer POST.
Timeouts e conexão¶
- Timeout de cliente: 10 s. O depósito pode levar cerca de 7 s e voltar
202; o saque é sempre201. - Timeout não é falha. Repita com a mesma
Idempotency-Key. Se desistir, consulte porexternal_idantes de decidir. - Resposta que não é JSON (página de erro de proxy,
413sem corpo) vem da entrada pública ou da rede: trate como erro de transporte. - TLS: use TLS 1.2 ou superior e valide o certificado do host; não desligue a verificação para "fazer funcionar".
Exemplos¶
Checagem rápida de relógio, antes de mexer em qualquer outra coisa (a resposta de erro também traz Date):
curl -sS -o /dev/null -D - "$DRACMA_BASE_URL/ping" | grep -i '^date:'
date -u
Se as duas horas diferirem em mais de alguns segundos, o relógio é o problema.
Diagnóstico de assinatura com o shell, usando as funções de exemplos/shell/lib.sh:
source exemplos/shell/lib.sh
dracma_canonico 1790000000 0123456789abcdef0123456789abcdef POST /v1/deposits corpo.json | cat -A
dracma_assinar "$(cat segredo.txt)" 1790000000 0123456789abcdef0123456789abcdef POST /v1/deposits corpo.json
Compare as saídas com o vetor 1. Qualquer $ no fim da última linha do canônico, ou uma assinatura diferente, mostra onde
está a diferença.
Erros e casos de borda¶
- Funciona direto e falha atrás de um proxy ou API gateway seu: o proxy reescreve caminho, query ou corpo depois de você assinar. Assine no último salto.
- Funciona em
GETe falha emPOST: quase sempre o corpo assinado não é o enviado, ou faltaIdempotency-Key. - Funciona uma vez e depois dá
replayed_nonce: nonce fixo ou semente repetida. - Intermitente, com
timestamp_out_of_window: relógio com deriva ou VM pausada. - Só
401na primeira chamada do dia: chave rotacionada e segredo antigo no cofre. - Depois de 20 falhas, tudo vira
429: o IP está bloqueado por falhas de assinatura; corrija a causa e espere. - Nada disso: abra um chamado com
Dracma-Trace-Id, horário em UTC,operation_id, rota ecode. Não envie o segredo da chave.