API v1, contrato 1.6.0. Contrato completo, legível por máquina (OpenAPI 3): baixar o openapi.json. Para criar a chave de API, cadastre a sua empresa ou fale com o suporte.
Para quem integra um sistema (o app de voz, um ERP) com o provedor. O sistema nunca lida com XML, certificado ou Sefin: manda JSON e recebe a nota, o PDF e o XML prontos.
Versão da API:
v1, congelada desde 01/10/2026 (contrato1.6.0; o1.0.0de 01/10/2026 ganhou as listagens no1.1.0, a substituição de NFS-e no1.2.0,GET /v1/contano1.3.0, no1.3.1a conferência local dos códigos nas tabelas oficiais e só dígitos de 0 a 9 nos campos numéricos, os serviços salvos no1.4.0, os clientes salvos no1.5.0e, no1.6.0, o resumo do pedido no detalhe da nota). A primeira nota real na Produção Restrita já passou pelo mesmo caminho descrito aqui. Esta página também é publicada no portal, em/integracao(os trechos marcados como internos ficam só no repositório). O contrato completo, legível por máquina (OpenAPI 3), é público em/integracao/openapi.json(no repositório:app/api/contrato-v1.openapi.json). Política de versão: ver a seção 11.
1. Acesso
- Chave de API no cabeçalho
X-API-Key: nfp_.... Cada chave só enxerga as empresas da própria conta; empresa ou nota de outra conta responde 404. - A chave é criada pelo admin (página da conta) ou pelo cliente no portal ("Chaves de API"). Ela aparece uma única vez: guarde no cofre de segredos do seu sistema, nunca no app do celular.
- Ambiente atual: homologação. As notas não têm validade jurídica e o PDF sai com "NFS-e SEM VALIDADE JURÍDICA".
2. Fluxo
1. POST /v1/empresas cadastra o CNPJ (uma vez por empresa)
2. POST /v1/empresas/{id}/certificado envia o A1 (.pfx + senha; a senha não é guardada)
3. GET /v1/empresas/{id}/diagnostico testa a conexão com a Sefin (não emite nada)
4. POST /v1/notas/previa opcional: XML que seria enviado (não emite, não gasta número)
POST /v1/notas/previa/danfse opcional: PDF de conferência "sem validade" (mesmo pedido)
5. POST /v1/notas emite (síncrono; volta autorizada, rejeitada ou erro_comunicacao)
6. GET /v1/notas/{id}/danfse PDF para mandar ao cliente
GET /v1/notas/{id}/xml XML oficial da NFS-e
7. POST /v1/notas/{id}/cancelamento cancela (só depois de confirmação do usuário!)
8. GET /v1/empresas/{id}/acervo?de=&ate= ZIP com os XML do período (para o contador)
9. GET /v1/empresas e GET /v1/notas listagens com filtro e paginação por cursor
Nos passos 1 a 3, uma conta "cliente" pode usar o portal em vez da API. Para emitir sem programar, a página da empresa tem o botão "Emitir nota": preenche tomador, serviço e valor, vê a prévia em PDF (não envia nada) e só emite ao marcar a confirmação. Vale para o cliente e para o operador da plataforma, com as mesmas regras da API (conta ativa, cota, idempotência, auditoria).
Acervo fiscal em lote (passo 8)
GET /v1/empresas/{id}/acervo?de=2026-09-01&ate=2026-09-30 devolve um ZIP (application/zip) com:
NFS-e-{serie}-{numero}.xml: o XML da NFS-e como a Sefin devolveu, de cada nota autorizada ou cancelada emitida no período;NFS-e-{serie}-{numero}-cancelamento.xml: o XML do evento, quando a nota foi cancelada;indice.csv(UTF-8 com BOM): série, número, chave de acesso, data de emissão, situação, nomes dos arquivos e "guardar até". Não leva dado do tomador.
Regras: as datas são dias do fuso do município da empresa (uma nota de 30/09 às 23:30 em Cuiabá é de setembro); de e ate são incluídos; o período vai até 366 dias e 2000 notas. Sem nota no período: 404. Período invertido, grande demais, acima de 2000 notas ou data mal escrita: 422. Rejeitadas e pendentes não entram. Cada download fica na auditoria (acervo_baixado, só datas e quantidade). A conta cliente também baixa pela tela da empresa no portal.
Listar empresas e notas (passo 9)
GET /v1/empresas e GET /v1/notas devolvem {"itens": [...], "proximo_cursor": "..."}. A conta vê só o que é dela (a chave da plataforma vê tudo).
- Paginação:
limitede 1 a 100 (padrão 50). Enquantoproximo_cursorvier preenchido, repita a chamada comcursor=<valor>; ele é opaco, não monte nem interprete. Notas emitidas durante a leitura não repetem nem pulam itens. Cursor mal formado: 422. - Empresas: ordenadas por CNPJ.
- Notas: da mais recente para a mais antiga. Filtros opcionais:
empresa_id(de outra conta: 404),status(pendente,autorizada,rejeitada,erro_comunicacao,cancelada) ede(inclusivo) /ate(exclusivo), em ISO 8601 sobre a data de emissão; sem fuso, vale UTC, e o+do fuso precisa ir como%2Bna URL. - Cada nota vem resumida:
id,empresa_id,serie,numero,status,emitida_em,chave_acessoevalor_servico. Sem XML, eventos nem dado do tomador; para o detalhe useGET /v1/notas/{id}. - Sem filtro por tomador: CPF/CNPJ na URL iria para o log de acesso do servidor, e o provedor não grava dado de tomador em log.
Serviços salvos da empresa (desde o 1.4.0)
Os mesmos "Meus serviços" da página da empresa no portal: um apelido para o serviço que a empresa emite sempre.
GET /v1/empresas/{id}/servicos: lista os ativos, em ordem de apelido (id,apelido,codigo_tributacao_nacional,codigo_municipio_prestacao,descricao,codigo_nbs,criado_em).POST /v1/empresas/{id}/servicoscomapelido,codigo_tributacao_nacional,codigo_municipio_prestacao,descricaoe, se quiser,codigo_nbs: 201. Código e NBS aceitam pontos. Volta 422 com código fora da lista nacional, município fora da tabela do IBGE (0000000, Águas Marítimas, é aceito), NBS fora da tabela, apelido repetido na empresa ou acima de 50 serviços.DELETE /v1/empresas/{id}/servicos/{servico_id}: 204. O serviço sai da lista, mas fica guardado. Já removido ou de outra empresa: 404.- Para emitir, copie os campos do serviço para
servicoemPOST /v1/notas: o pedido da nota não referencia o serviço salvo, então mudar ou remover o serviço depois não altera nota nenhuma.
Clientes salvos da empresa (desde o 1.5.0)
Os mesmos clientes (tomadores) da tela "Clientes" do portal: quem integra e o portal veem a mesma lista.
GET /v1/empresas/{id}/clientes: lista os ativos, em ordem de nome (id,nome,cpfoucnpj,email,telefone,endereco,criado_em,atualizado_em).POST /v1/empresas/{id}/clientescom os campos dotomadorda emissão (cpfoucnpj,nomee, se quiser,email,telefoneeendereco): 201. Se a empresa já tem um cliente ativo com o mesmo CPF/CNPJ, ele é atualizado e a resposta é 200, sem apagar endereço, e-mail e telefone que o pedido não trouxe. Volta 422 com documento inválido, município do endereço fora da tabela do IBGE ou acima de 500 clientes por empresa.PUT /v1/empresas/{id}/clientes/{cliente_id}: substitui o cadastro inteiro (o que não vier fica vazio). CPF/CNPJ de outro cliente ativo da empresa: 422.DELETE /v1/empresas/{id}/clientes/{cliente_id}: 204. O cliente sai da lista, mas fica guardado. Já removido ou de outra empresa: 404.- Para emitir, copie os campos para
tomadoremPOST /v1/notas: a nota não referencia o cliente salvo. - LGPD: CPF, e-mail e telefone do tomador são dado pessoal, guardado em nome da empresa (controladora). Não vão para a auditoria nem para o log do provedor.
3. Emitir uma nota
curl -X POST https://<provedor>/v1/notas \
-H "X-API-Key: $CHAVE" -H "Content-Type: application/json" \
-d '{
"empresa_id": "8b1e…",
"chave_idempotencia": "servico-2026-10-01-roberto-0001",
"tomador": {"cpf": "52998224725", "nome": "Roberto Cezar",
"endereco": {"codigo_municipio": "5103403", "cep": "78055574",
"logradouro": "Rua das Flores", "numero": "10", "bairro": "Centro"}},
"servico": {"codigo_tributacao_nacional": "140101",
"descricao": "Manutenção preventiva de ar-condicionado split 12.000 BTUs",
"codigo_municipio_prestacao": "5103403"},
"valores": {"valor_servico": "600.00"}
}'
- O CNPJ do prestador não vai no pedido: vem do cadastro da empresa (
empresa_id). tomador:cpfoucnpj(exatamente um). O endereço é opcional.codigo_tributacao_nacional: 6 dígitos da lista nacional (Anexo B). Para o técnico de ar-condicionado: 14.01.01, 14.02.01 ou 14.06.01 (o contador decide).- Grupo
ibscbs(Reforma Tributária): opcional para o Simples em 2026. Ex.:{"cst": "000", "classificacao_tributaria": "000001", "indicador_operacao": "050102"}. Comibscbs, ocodigo_nbsdo serviço passa a ser obrigatório (E0322). Além do mínimo aceitaconsumidor_final,tipo_operacao,notas_referenciadas,tipo_ente_governamental,destinatario,imovel,credito_presumido,tributacao_regularediferimento; os valores de IBS/CBS são calculados pela Sefin, não pelo seu sistema.
Desconto, retenções federais e informações complementares (todos opcionais)
"servico": {"...": "...",
"informacoes_complementares": {"documento_tecnico": "ART 1234567", "documento_referencia": "Contrato 2026/10",
"numero_pedido": "OS-77", "itens_pedido": ["1", "2"],
"texto": "Garantia de 90 dias."}},
"valores": {"valor_servico": "600.00",
"desconto_incondicionado": "50.00", "desconto_condicionado": "10.00",
"tributos_federais": {"retencao_irrf": "9.00", "retencao_csll": "6.00",
"pis_cofins": {"cst": "01", "base_calculo": "600.00",
"aliquota_pis": "0.65", "valor_pis": "3.90"}}}
- Desconto: cada um deve ser maior que zero e menor que
valor_servico(E0431/E0432).valor_servicoprecisa cobrir a soma dos descontos e das retenções informadas (E0428). tributos_federais: informe ao menos um campo.retencao_cp,retencao_irrferetencao_csllsão valores retidos, maiores que zero e menores quevalor_servico(E0699 a E0701). Empis_cofins, ocsté da tabela do XSD, a base não passa devalor_servico(E0677) e, quando vêm base, alíquota e valor juntos, o valor tem que bater com base × alíquota, com tolerância de R$ 0,01 (E0694/E0696).tipo_retencao0 não aceitaretencao_csll(E0720); fora de 0 e 2 exigeretencao_csll(E0724, texto literal do Anexo I: hipótese a confirmar na Sefin).informacoes_complementares: informe ao menos um campo. Limites:documento_tecnico40,documento_referencia255,numero_pedido60, até 99itens_pedidode 60 caracteres etextode 2000 sem quebra de linha. Se o DANFSe mostra esses campos ainda não foi conferido (hipótese).- Todas essas regras são conferidas antes de qualquer envio: pedido que as viola volta com 422 e nada é reservado nem enviado à Sefin.
Regras que cruzam o pedido com o cadastro da empresa
Também voltam com 422 (lista de mensagens, cada uma com o código do Anexo I) e sem gastar número, na emissão e na prévia: competência posterior à emissão (E0015); tomador com o mesmo CNPJ do prestador (E0202); retencao_issqn 2 sem endereco do tomador (E0237); ISSQN retido (2 ou 3) para prestador MEI (E0583) ou com regime especial de tributação (E0588); e códigos de serviço de obra (07.02.01, 07.02.02, 07.04.01, 07.05.01, 07.05.02, 07.06.01, 07.06.02, 07.07.01, 07.08.01, 07.17.01, 07.19.01, 14.14.03, 14.14.04), que exigem o grupo de obra (E0370), ainda não suportado por este provedor.
Desde o 1.3.1, também com 422 e sem gastar número: código de serviço fora da lista nacional (E0310), NBS fora da tabela (E0316), município da prestação fora da tabela do IBGE (E0302; 0000000, "Águas Marítimas", é aceito), município do endereço do tomador (E0238) ou do destinatário do IBS/CBS (E0920) inexistente, e o serviço 20.01.01 com local 0000000 (E1402). Também, conforme o regime da empresa: MEI com aliquota_issqn informada (E0600); ME/EPP com ISSQN pelo Simples sem retenção e com alíquota (E0625/E0631), ou com retenção e sem alíquota ou abaixo de 1,8% (E0621/E0628, máximo 5%); retencao_issqn 3 (intermediário), porque o provedor ainda não envia os dados do intermediário (E0264, E0293); e retenção com tributacao_issqn 4 (E0580). As tabelas são a do IBGE e a do Anexo B v1.01. Os campos numéricos (CEP, município, código do serviço, NBS, série, inscrição municipal, telefone) aceitam só os dígitos de 0 a 9. No cadastro da empresa, codigo_municipio tem de existir na tabela do IBGE.
Substituir uma NFS-e já autorizada
Para corrigir uma nota autorizada sem cancelá-la antes, emita a substituta com o grupo opcional substituicao:
{ "...": "o pedido normal, completo, da nota nova",
"substituicao": { "chave_acesso": "51034032…(50 caracteres)", "motivo": 99,
"justificativa": "Correção do valor do serviço prestado" } }
motivo: 1 desenquadramento do Simples Nacional; 2 enquadramento no Simples Nacional; 3 inclusão retroativa de imunidade/isenção; 4 exclusão retroativa de imunidade/isenção; 5 rejeição pelo tomador/intermediário; 99 outros.justificativa(15 a 255 caracteres) é opcional, exceto no 99 (E0078).- A substituta é uma nota nova, com número e chave próprios (use outra
chave_idempotencia). Quem cancela a original é a Sefin, junto com a autorização da substituta (evento 105102): quando a nota nova ficaautorizada, a original passa acanceladaaqui também, ganha um eventotipo: "substituicao"(emeventos, commotivoejustificativa) e dispara o webhook de cancelamento. Na substituta,chave_substituidatraz a chave da original. Se a substituta ficar emerro_comunicacao, a original só muda quando o reenvio confirmar. - Conferido aqui, com 422 e sem gastar número: a chave ser de uma nota do mesmo prestador e município (E0042) e a original, quando o provedor a conhece, não estar cancelada nem fora do estado
autorizada(E0046). Nota emitida antes do provedor segue para a Sefin, que decide. - Fica por conta da Sefin e volta como nota
rejeitada, com o código emerros: nota substituída inexistente (E0044), prazo do município (E0050; não vale para os motivos 1 e 2), e os bloqueios por análise fiscal, manifestação do tomador ou bloqueio de ofício (E0056 a E0076). Não dá para desfazer uma substituição autorizada. - O
motivodo evento (eventos[].motivo) é um inteiro: no cancelamento são 1 erro na emissão, 2 serviço não prestado e 9 outros; na substituição, os da lista acima. Otipodiz qual tabela vale.
Resposta
{
"id": "3f0c…", "empresa_id": "8b1e…", "chave_idempotencia": "servico-2026-10-01-roberto-0001",
"serie": "1", "numero": 42, "status": "autorizada",
"chave_acesso": "51034032…", "erros": null, "tentativas": 0, "proxima_tentativa": null, "eventos": []
}
Desde o 1.6.0, a nota (resposta da emissão, GET /v1/notas/{id}, cancelamento e reprocessamento) traz também o essencial do pedido, para mostrar a nota e ligá-la ao seu cliente sem baixar o XML: tomador (nome, cpf, cnpj), servico (codigo_tributacao_nacional, descricao), valor_servico e competencia. A listagem GET /v1/notas continua sem dado do tomador.
status |
Significado | O que o seu sistema faz |
|---|---|---|
autorizada |
A NFS-e existe na Sefin | Baixa o PDF e manda ao cliente, ou deixa o provedor mandar por e-mail (seção 7) |
rejeitada |
A Sefin (ou o XSD local, código XSD_LOCAL) recusou |
Mostra erros[].mensagem, corrige e emite de novo com outra chave de idempotência |
erro_comunicacao |
Sem resposta da Sefin; pode ter sido gerada | Nada: o provedor descobre e reenvia sozinho, sem duplicar. Aguarde o webhook ou consulte GET /v1/notas/{id} |
cancelada |
Cancelamento registrado, ou a nota foi substituída por outra (evento substituicao) |
— |
4. Idempotência (não duplicar nota)
chave_idempotenciaé sua (até 100 caracteres), única por empresa. Gere uma por serviço confirmado pelo usuário.- Repetir o mesmo pedido com a mesma chave devolve a mesma nota (HTTP 200 em vez de 201) e nunca emite outra. Use isso com tranquilidade quando a internet do celular cair no meio.
- Mesma chave com pedido diferente dá 409.
5. Erros HTTP
| Código | Quando |
|---|---|
| 401 | Chave ausente, errada ou revogada |
| 403 | Conta em análise ou suspensa (não emite nem pede envio de e-mail), ou emissão de notas novas pausada por mensalidade em atraso (a mensagem diz qual; consulta, PDF, XML, cancelamento, substituição e repetição de pedido já gravado continuam) |
| 404 | Empresa ou nota inexistente ou de outra conta |
| 409 | Sem certificado válido; chave de idempotência com outro pedido; nota que não pode ser cancelada/reprocessada; e-mail de nota que ainda não tem NFS-e ou sem e-mail do tomador |
| 413 | Arquivo do certificado grande demais |
| 422 | Dados inválidos (o corpo explica o campo) |
| 429 | Cota diária ou mensal de emissões da conta atingida (nada foi emitido); limite diário de e-mails de NFS-e atingido |
Forçar a recuperação de uma nota sem resposta
POST /v1/notas/{id}/reprocessar (sem corpo) manda o provedor consultar a Sefin agora para uma nota em erro_comunicacao, sem esperar o reenvio automático. Não duplica: se a nota já existir na Sefin, ela é recuperada; se não, é reenviada com os mesmos número e data. Em qualquer outro status responde 409.
6. Webhook de status
Configure a URL na página da conta (admin) ou em "Chaves de API" (portal). Só https com endereço público. A cada mudança de situação de uma nota, o provedor faz POST na sua URL:
POST /nfse/webhook HTTP/1.1
Content-Type: application/json
X-Evento: nota.autorizada
X-Entrega-Id: 6c2d…
X-Assinatura: t=1790880000,v1=5f2a…
{"evento":"nota.autorizada","enviado_em":"2026-10-01T15:04:05-03:00",
"nota":{"id":"3f0c…","empresa_id":"8b1e…","chave_idempotencia":"…","serie":"1","numero":42,
"status":"autorizada","chave_acesso":"5103…","erros":null}}
- Eventos:
nota.autorizada,nota.rejeitada,nota.erro_comunicacao,nota.cancelada, eping(botão de teste). - Sem dados pessoais no aviso. Se precisar de mais, consulte
GET /v1/notas/{id}com a sua chave. - Responda 2xx em até 10 s. Qualquer outra resposta gera novas tentativas (30 s, 1 min, 2 min… até 6 h), por até 10 vezes. Use
X-Entrega-Idpara ignorar avisos repetidos. - Confira a assinatura sempre:
v1 = HMAC-SHA256(segredo, "<t>.<corpo bruto>"). Recuse se não bater ou settiver mais de 5 minutos.
import hashlib, hmac, time
def aviso_valido(segredo: str, corpo: bytes, cabecalho: str) -> bool:
partes = dict(p.split("=", 1) for p in cabecalho.split(","))
t, v1 = partes["t"], partes["v1"]
if abs(time.time() - int(t)) > 300:
return False
esperado = hmac.new(segredo.encode(), f"{t}.".encode() + corpo, hashlib.sha256).hexdigest()
return hmac.compare_digest(esperado, v1)
7. E-mail da NFS-e ao tomador
O provedor pode mandar a nota (PDF + XML) ao tomador. O e-mail sai do endereço da plataforma, com o nome da empresa como remetente ("Clima Frio via <nome da plataforma>", trocado pelo admin em Configurações > Identidade), e as respostas do tomador vão para o e-mail da empresa.
1. Informe o e-mail do tomador na emissão (opcional) e, se quiser, a opção de envio:
{"empresa_id": "8b1e…", "chave_idempotencia": "…", "enviar_email": true,
"tomador": {"cpf": "52998224725", "nome": "Roberto Cezar", "email": "roberto@exemplo.com.br"}, "…": "…"}
enviar_email:trueenvia ao autorizar;falsenão envia; omitido segue a configuração da empresa (padrão: não envia).- Só nota
autorizadagera o envio automático. Se a Sefin demorar e o provedor recuperar a nota depois, o e-mail sai nessa hora. Nota rejeitada ou pendente nunca gera e-mail. O envio automático acontece uma vez por nota. - O
email_tomadorvai de volta na nota. Ele é uma cópia para envio: corrigi-lo não altera o XML fiscal.
2. Configure a empresa (uma vez): PUT /v1/empresas/{id}/email. O pedido substitui os quatro campos: o que você omitir fica vazio/desligado.
{"email_nome_exibido": "Clima Frio Atendimento", "email_resposta": "contato@climafrio.com.br",
"email_copia": "arquivo@climafrio.com.br", "email_automatico": true}
email_nome_exibido(até 100 caracteres, sem quebra de linha): se vazio, usa a razão social.email_resposta: vira o Reply-To.email_copia: cópia oculta para a empresa guardar.email_automatico: liga o envio automático para todas as notas da empresa (a opção do pedido vale mais).
3. Envio manual e reenvio: POST /v1/notas/{id}/email com {"destinatario": "outro@exemplo.com"} (ou {} para usar o e-mail da nota). Responde 202: o pedido entra na fila e o e-mail sai em instantes. Informar um destinatário corrige o email_tomador da nota. Vale para nota autorizada e cancelada (esta vai com aviso de cancelamento).
4. Histórico: GET /v1/notas/{id}/emails lista os envios (tipo: automatico ou manual; status: pendente, enviado ou falhou; tentativas, ultimo_erro).
Regras que o seu app deve conhecer:
- A nota nunca depende do e-mail. Se o servidor de e-mail falhar, a nota continua autorizada; o provedor repete (5 min, 10 min, 20 min… até 6 h) por até 5 tentativas e então marca
falhou. Para tentar de novo, peça o envio manual. - A entrega é "pelo menos uma vez": em caso raro de queda no meio do envio, o tomador pode receber duas cópias.
- Cada conta tem limite diário de pedidos de e-mail (padrão 300): acima dele, 429. No envio automático, o limite estourado aparece como envio
falhouno histórico. - O provedor não guarda o texto nem os anexos enviados, só o histórico (destinatário, situação, tentativas).
- LGPD: o e-mail do tomador é dado pessoal. A empresa é a controladora e precisa ter motivo legítimo para escrever ao tomador (ver os Termos e
docs/juridico-pendencias.md). O app de voz deve mostrar o e-mail no cartão de confirmação antes de enviar. - Evento de webhook de e-mail não existe: o aviso
nota.*continua sendo só de status da nota.
8. Cotas
Cada conta tem limite diário e mensal de emissões (padrão 200/dia e 2.000/mês; o admin ajusta). Acima da cota: 429 e nada é emitido. Reenvio com a mesma chave de idempotência não conta.
GET /v1/conta (desde o 1.3.0) devolve a conta dona da chave: situacao (em_analise, ativa, suspensa, encerrada), plano, o uso da cota (notas.hoje, notas.limite_diario, notas.mes, notas.limite_mensal) e os complementos (assistente.ativo, assistente.interacoes_mes). Com a chave da plataforma responde 404.
9. Regras que o app precisa respeitar (do projeto)
- Nunca emitir ou cancelar nota sem o usuário confirmar no cartão de confirmação.
- A chave de API fica no servidor do app, nunca no aplicativo do celular.
- Mostre ao técnico os
erros[].mensagemda rejeição: eles vêm da Sefin e dizem o que corrigir.
Rejeições já vistas na Sefin real
| Código | O que significa | Quem corrige |
|---|---|---|
E0120 |
Inscrição municipal informada, mas a prefeitura não tem dados complementares da empresa no cadastro nacional | O admin ou o cliente apaga a inscrição municipal no cadastro do CNPJ e emite de novo |
Rejeição de cadastro (como a E0120) não se resolve no app: o app mostra a mensagem e orienta procurar o suporte. O número da nota rejeitada nunca é reaproveitado; a próxima sai com o número seguinte.
11. Política de versão do contrato
A API /v1 é estável: quem integrou hoje continua funcionando. O contrato congelado fica em app/api/contrato-v1.openapi.json e um teste do provedor falha se a API mudar sem esse arquivo ser atualizado de propósito.
O que pode mudar dentro de /v1 (sem aviso, o contrato sobe 1.x.0):
- rota nova;
- campo opcional novo no pedido ou na resposta;
- parâmetro opcional novo;
- código de resposta novo para uma situação nova;
- valor novo em campo de resposta como
status. O seu sistema deve ignorar o que não conhece: não quebre com campo ou valor novo.
O que só muda em /v2 (a /v1 segue funcionando em paralelo, com aviso prévio):
- tirar ou renomear rota, campo, parâmetro ou código de resposta;
- mudar o tipo ou o significado de um campo;
- tornar obrigatório um campo ou parâmetro que era opcional, ou criar um obrigatório;
- deixar de aceitar um valor que o pedido aceitava.
Correção de bug que muda comportamento errado para o certo não conta como quebra, mas é avisada. As regras da Sefin (rejeições E0xxx) são do governo e podem mudar sem relação com a versão da API.