OpenAPI publicada

openapi.yaml é o documento que a API serve em GET /openapi.yaml (público, sem autenticação, fora do grupo /v1). É cópia byte a byte do arquivo embutido no binário do dracma_api (internal/interface/http/openapi/openapi.yaml). Não é editado aqui.

O contrato de forma do briefing (Contrato de integração v1 1.1.0) fica ao lado, sem alteração, em contrato-1.1.0.openapi.yaml, só para leitura do diff. Em conflito de semântica, vale o contrato (texto normativo). Para a forma que o código aceita e devolve hoje, vale o documento servido.

Como a cópia é provada

  • python3 scripts/verificar_openapi.py compara as duas cópias com as fontes do dracma_api e falha em qualquer byte diferente. Também falha quando a fonte não é encontrada, porque sem a fonte não há prova. Antes de comparar, adultera um byte e exige que a comparação acuse.
  • O scripts/verificar_docs.py chama essa checagem, e o CI do dracma_docs roda as duas com o checkout do dracma_api em DRACMA_API_DIR.
  • Para atualizar depois de mudar a API, rode python3 scripts/verificar_openapi.py --sync, revise o diff e rode python3 scripts/gerar_llms_full.py.
  • Do lado da API, TestOpenAPIRoutesMatchRouter exige que toda rota do roteador v1 esteja no documento e vice-versa. TestOpenAPIResponsesMatchSchemas e TestP056PIXSliceOfV110Surface validam as respostas reais contra o documento.

Documento servido x contrato 1.1.0

Regra aplicada: o contrato vence (decisão D9). Quando a API divergia do contrato sem decisão registrada, a API foi corrigida. Quando a diferença é um acréscimo aditivo (Contrato §6.0) ou já tinha decisão registrada, ela fica e está listada abaixo. O diff gerado pela máquina está em dracma_api/docs/openapi-divergencias.md, conferido pelo teste TestBriefingDiffRegistered.

Resolvidas na API (P056, 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 (wire/SWIFT) habilitado.

Rota Antes Agora
GET /fx/quotes/{id} 404 (rota inexistente) 404 not_found: nenhuma cotação é emitida, porque POST /fx/quotes responde 422 fx_not_enabled
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, porque recall só vale para wire/SWIFT e todo saque é PIX; saque 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 (nada é casado nem criado); corpo inválido → 400 validation_failed; em produção → 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 (§6.0), registrado em D-R1 de divergencias.md.
Descrição de Problema.errors[].reason (motivos novos) A lista de motivos é aberta e só a descrição muda (D-R1).
404 declarado em POST /deposits/{id}/cancel e POST /withdrawals/{id}/cancel O catálogo do §7 já manda 404 not_found, inclusive para objeto de outra operação. O documento só passou a declarar esse status.
Idempotency-Key declarado nos POST /sandbox/* (inclusive bank-transfers/incoming) A API exige a chave em todo POST. O contrato não declarava o header nessas rotas (D-S1, que fica resolvida no documento publicado).
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 do §7 (validation_failed, rail_not_enabled).
Rotas POST /sandbox/deposits/{id}/refund e /chargeback Gatilho de sandbox para paid → refunded e paid → chargeback. O §9 manda o sandbox exercitar todo caminho. Ação nova de sandbox é aditiva e responde 404 em produção (D-D3, C238).
Servidor http://127.0.0.1:3016/v1 removido É o "Dracma FALSO" do lado da bet, não um servidor do Dracma (D-S3).

As divergências de comportamento, que o schema não mostra, continuam em divergencias.md. Exemplos: D-D4 (method_options/fx_quote_id → 400) e D-W9.