OpenAPI

Para: Dev — Conferido em 2026-10-19.

O documento OpenAPI 3.1 da API v1 é openapi.yaml. Ele é uma cópia byte a byte do documento que a própria API serve, e você o baixa em https://developers.dracma.cfd/openapi.yaml. Esta página diz como baixá-lo, como ele se relaciona com o contrato 1.1.0 e o que ainda difere do contrato, para você não gerar um cliente sobre uma informação desatualizada.

O que é

Item Valor
Versão do contrato 1.1.0
Formato OpenAPI 3.1, application/yaml
Onde baixar https://developers.dracma.cfd/openapi.yaml
Quem o gera a própria API: o arquivo é embutido no serviço e é o que ela serve em GET /openapi.yaml

A API implementa a rota GET /openapi.yaml, pública e sem autenticação, fora do grupo /v1. Mas o ponto de entrada público do Dracma só expõe /v1/*: qualquer outro caminho dos hosts da API responde 404. Por isso, não tente baixar o documento do host da API. Use sempre o endereço do site de documentação acima.

O documento não é editado por quem escreve este guia. Quando o texto da API muda, a cópia é atualizada junto.

O contrato de forma do briefing (Contrato de integração v1, versão 1.1.0) fica ao lado, sem alteração, em contrato-1.1.0.openapi.yaml, só para você ler o diff. Em conflito de semântica, vale o texto normativo do contrato. Para a forma que a API aceita e devolve hoje, vale o documento servido, com as correções desta página.

Quando usar

  • Para gerar um cliente ou validar respostas: baixe o openapi.yaml.
  • Para saber o que a API de fato devolve: leia as páginas desta seção. O documento tem mais campos e rotas do que o Dracma preenche (veja Rotas e campos reservados e Objetos e campos).
  • Para achar o texto de uma operação a partir do operationId: veja o Índice de endpoints.
  • Para conferir o seu cliente contra o servido: compare o info.version e o conteúdo com a cópia do site, que é a que o guia usa.

Como funciona

Cache e ETag

A rota da API, quando alcançável (por exemplo, em um ambiente de desenvolvimento do próprio Dracma), responde com:

Cabeçalho Valor
Content-Type application/yaml; charset=utf-8
ETag um ETag forte, derivado do hash do conteúdo
Cache-Control public, max-age=300
X-Content-Type-Options nosniff

Um pedido com If-None-Match igual ao ETag atual recebe 304, sem corpo. HEAD também funciona. No site de documentação, o arquivo é um arquivo estático: baixe-o no seu CI e compare o conteúdo (por hash) em vez de depender de cabeçalhos.

Como a cópia é provada

  • Uma checagem automática compara as duas cópias do documento com a fonte embutida na API e falha em qualquer byte diferente. Ela também falha quando a fonte não é encontrada, porque sem fonte não há prova. Antes de comparar, adultera um byte e exige que a comparação acuse.
  • Do lado da API, um teste exige que toda rota do roteador /v1 esteja no documento e vice-versa, e outros testes validam as respostas reais contra os schemas.
  • Os exemplos JSON deste guia que representam objetos da API são validados contra o openapi.yaml.

O documento servido e o contrato 1.1.0

Regra aplicada: o contrato vence. Quando a API divergia do contrato sem decisão registrada, a API foi corrigida. Quando a diferença é um acréscimo aditivo ou já tinha decisão registrada, ela fica e está listada abaixo.

Resolvidas na API (2026-10-02). Estas rotas estavam no contrato, mas fora do documento servido: a API respondia 404 de rota inexistente. Agora estão declaradas e implementadas no recorte PIX. Nenhuma operação tem câmbio nem trilho bancário habilitado.

Rota Antes Agora
GET /fx/quotes/{id} 404 (rota inexistente) 404 not_found: nenhuma cotação é emitida
GET /receipts 404 (rota inexistente) 200 {data: [], next_cursor: null}; parâmetro fora do schema: 400 validation_failed
GET /receipts/{id} 404 (rota inexistente) 404 not_found: sem trilho bancário não existe recebimento
POST /withdrawals/{id}/recall 404 (rota inexistente) saque da operação: 409 invalid_state_transition; inexistente ou de outra operação: 404; corpo inválido: 400
POST /sandbox/bank-transfers/incoming 404 (rota inexistente) corpo válido: 400 rail_not_enabled; corpo inválido: 400 validation_failed; em operação Real: 404

Aceitas (aditivas ou com decisão registrada).

Diferença no documento servido Motivo
Moeda.method_details e o schema DetalheMetodo Exigências de depósito por operação. Campo aditivo
Descrição de Problema.errors[].reason com motivos novos A lista de motivos é aberta
404 declarado em POST /deposits/{id}/cancel e POST /withdrawals/{id}/cancel O catálogo de erros já manda 404 not_found, inclusive para objeto de outra operação. O documento só passou a declarar o status
Idempotency-Key declarado nos POST /sandbox/* A API exige a chave em todo POST. O contrato não declarava o cabeçalho nessas rotas
400 declarado em POST /withdrawals/{id}/recall, GET /receipts e POST /sandbox/bank-transfers/incoming Validação de corpo e parâmetros com o catálogo de erros
Rotas POST /sandbox/deposits/{id}/refund e /chargeback Gatilho de sandbox para paid → refunded e paid → chargeback. Ação nova de sandbox é aditiva e responde 404 em operação Real
Servidor de teste local removido da lista servers Ele não era um servidor do Dracma, e sim um servidor de teste do lado do integrador

As divergências de comportamento, que o schema não mostra, estão em Divergências conhecidas.

O que ainda difere do contrato

Nada de relevante. A lista de 15 itens que esta página trazia (operador de exemplo citado pelo nome, e-mail de exemplo de domínio real, servers com host sandbox.* e mTLS obrigatório, rules.updated, method_options e fx_quote_id no depósito, schema vazio em GET /sandbox/webhooks, texto da janela da reconciliação e outros) foi corrigida na fonte, na API, e a cópia do site foi atualizada junto. O histórico está em Divergências conhecidas.

O que continua diferente do documento servido é a diferença contra o contrato 1.1.0 (por exemplo, o return de reconciliação, os campos de saque PIX reservados e a lista de IPs liberados, que é opcional (vazia = sem restrição)). Isso fica em Divergências conhecidas.

Exemplos

Baixar o documento e guardar o hash do conteúdo, para detectar mudança:

curl -fsS -o openapi.yaml https://developers.dracma.cfd/openapi.yaml
sha256sum openapi.yaml

Um pedido condicional à rota da API, onde ela for alcançável (o ETag abaixo é ilustrativo):

GET /openapi.yaml HTTP/1.1
Host: api.example.test
If-None-Match: "3f8a2c1d9b7e4a5c6d0e1f2a3b4c5d6e"
HTTP/1.1 304 Not Modified
ETag: "3f8a2c1d9b7e4a5c6d0e1f2a3b4c5d6e"
Cache-Control: public, max-age=300

Erros e casos de borda

  • GET /openapi.yaml no host da API pelo ponto de entrada público responde 404: o ponto de entrada só repassa /v1/*.
  • A rota não usa assinatura nem Idempotency-Key: ela fica fora do grupo /v1.
  • Mudança no documento (campos novos, rotas novas) é aditiva dentro de /v1. Veja Política de versionamento.
  • Um cliente gerado com um enum fechado quebra ao receber valor novo. Gere com enum aberto, ou trate o valor desconhecido como o leitor tolerante manda.
  • Se o info.version do documento subir, leia o Changelog.

Veja também