Pular para o conteúdo
Kinota

Documentação técnica

Guia de integração da API

API v1 · contrato 1.6.0

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 (contrato 1.6.0; o 1.0.0 de 01/10/2026 ganhou as listagens no 1.1.0, a substituição de NFS-e no 1.2.0, GET /v1/conta no 1.3.0, no 1.3.1 a 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 no 1.4.0, os clientes salvos no 1.5.0 e, no 1.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: limite de 1 a 100 (padrão 50). Enquanto proximo_cursor vier preenchido, repita a chamada com cursor=<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) e de (inclusivo) / ate (exclusivo), em ISO 8601 sobre a data de emissão; sem fuso, vale UTC, e o + do fuso precisa ir como %2B na URL.
  • Cada nota vem resumida: id, empresa_id, serie, numero, status, emitida_em, chave_acesso e valor_servico. Sem XML, eventos nem dado do tomador; para o detalhe use GET /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}/servicos com apelido, codigo_tributacao_nacional, codigo_municipio_prestacao, descricao e, 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 servico em POST /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, cpf ou cnpj, email, telefone, endereco, criado_em, atualizado_em).
  • POST /v1/empresas/{id}/clientes com os campos do tomador da emissão (cpf ou cnpj, nome e, se quiser, email, telefone e endereco): 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 tomador em POST /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: cpf ou cnpj (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"}. Com ibscbs, o codigo_nbs do serviço passa a ser obrigatório (E0322). Além do mínimo aceita consumidor_final, tipo_operacao, notas_referenciadas, tipo_ente_governamental, destinatario, imovel, credito_presumido, tributacao_regular e diferimento; 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_servico precisa cobrir a soma dos descontos e das retenções informadas (E0428).
  • tributos_federais: informe ao menos um campo. retencao_cp, retencao_irrf e retencao_csll são valores retidos, maiores que zero e menores que valor_servico (E0699 a E0701). Em pis_cofins, o cst é da tabela do XSD, a base não passa de valor_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_retencao 0 não aceita retencao_csll (E0720); fora de 0 e 2 exige retencao_csll (E0724, texto literal do Anexo I: hipótese a confirmar na Sefin).
  • informacoes_complementares: informe ao menos um campo. Limites: documento_tecnico 40, documento_referencia 255, numero_pedido 60, até 99 itens_pedido de 60 caracteres e texto de 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 fica autorizada, a original passa a cancelada aqui também, ganha um evento tipo: "substituicao" (em eventos, com motivo e justificativa) e dispara o webhook de cancelamento. Na substituta, chave_substituida traz a chave da original. Se a substituta ficar em erro_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 em erros: 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 motivo do 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. O tipo diz 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, e ping (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-Id para ignorar avisos repetidos.
  • Confira a assinatura sempre: v1 = HMAC-SHA256(segredo, "<t>.<corpo bruto>"). Recuse se não bater ou se t tiver 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: true envia ao autorizar; false não envia; omitido segue a configuração da empresa (padrão: não envia).
  • Só nota autorizada gera 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_tomador vai 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 falhou no 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[].mensagem da 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.