Comece por aqui
A API da Kontrib conecta o seu ERP à inteligência fiscal da Reforma Tributária: envie notas de entrada e saída, sincronize o cadastro de produtos e consulte a classificação fiscal por código de barras — como o mercado classifica hoje e o enquadramento em CBS/IBS/IS com a carga da transição 2026→2033.
https://app.kontrib.com.br/api/v1/erpEnviar notas
XML ou ZIP com milhares de NF-e/NFC-e, processamento assíncrono e idempotente.
Classificar produtos
GTIN → NCM, CEST, CST/CSOSN pelo regime + cClassTrib e alíquotas da reforma.
Sincronizar cadastro
Lotes de até 5.000 produtos por chamada, reenvio seguro.
Metodologia aberta
Toda regra fiscal usada nas respostas é versionada, com base legal publicada.
Seu primeiro request
1. Crie uma chave no app (Importações → API ERP) — uma chave por empresa/CNPJ.
2. Chame o /ping:
curl -s https://app.kontrib.com.br/api/v1/erp/ping \ -H "X-Api-Key: r360_SUACHAVE" # 200 OK { "ok": true, "empresaId": "1c2f0a9e-..." }
- Formato JSON (UTF-8), exceto o envio de notas (XML/ZIP).
- Datas ISO-8601 em UTC · decimais com ponto · percentuais em escala 0–100.
- Contrato estável: campos podem ser adicionados às respostas — ignore os desconhecidos.
Autenticação
Toda requisição leva a chave no header X-Api-Key. A chave:
- é criada no app em Importações → API ERP, uma por empresa/CNPJ;
- é exibida uma única vez (formato
r360_...) — guarde em cofre de segredos; - identifica a empresa: notas e produtos enviados são vinculados a ela automaticamente;
- pode ser revogada a qualquer momento (crie outra para rotacionar sem downtime);
- tem o uso medido por dia e endpoint, visível na tela de chaves.
Erros e limites
Erros seguem o padrão Problem Details (RFC 7807) — leia sempre o campo detail:
{
"status": 422,
"title": "Unprocessable Content",
"detail": "O envio tem 7000 itens; o máximo por chamada é 5000. Envie em páginas e aguarde a resposta de cada uma."
}| Código | Quando acontece | O que fazer |
|---|---|---|
400 | ZIP sem XML válido · lote acima de 10.000 XMLs | Corrigir/dividir e reenviar |
401 | Chave ausente, inválida ou revogada | Conferir a chave |
404 | Job de outra empresa · GTIN fora da base | — |
413 | Arquivo acima de 100 MB | Dividir o ZIP |
422 | Paginação estourada · GTIN malformado · regime inválido | Ler o detail |
429 | Rate limit · lotes pendentes · força bruta | Esperar o header Retry-After (segundos) e repetir |
Limites de produção
| Limite | Valor | Estouro |
|---|---|---|
| Requisições por minuto, por chave | 120 | 429 + Retry-After: 60 |
| Tamanho por envio de notas | 100 MB | 413 |
| XMLs por ZIP | 10.000 | 400 |
| Lotes de notas processando ao mesmo tempo, por empresa | 5 | 429 + Retry-After: 30 |
| Produtos por chamada | 5.000 | 422 |
| GTINs por lote de classificação | 500 | 422 |
429 nunca perde dado — é backpressure. Espere o
Retry-After e repita a mesma chamada.Enviar notas (entrada e saída)
/nfeAceita um XML de NF-e/NFC-e ou um ZIP com vários XMLs. Envie compras e vendas
sem distinção — o vínculo é com a empresa da chave, e entrada × saída é detectado pelo
emitente da nota. O processamento é sempre assíncrono: resposta 202 imediata.
| Header | Valor |
|---|---|
Content-Type | application/xml (um XML) ou application/octet-stream (ZIP) |
| Corpo | os bytes do arquivo |
# um XML curl -s -X POST https://app.kontrib.com.br/api/v1/erp/nfe \ -H "X-Api-Key: $KEY" -H "Content-Type: application/xml" \ --data-binary @nota.xml # um ZIP com milhares de XMLs curl -s -X POST https://app.kontrib.com.br/api/v1/erp/nfe \ -H "X-Api-Key: $KEY" -H "Content-Type: application/octet-stream" \ --data-binary @lote-2026-06.zip # 202 Accepted { "jobId": "7e1b3c44-..." }
duplicada — nunca duplica dado nem gera erro.
Se a carga cair no meio, reenvie o mesmo ZIP.Status do lote
/nfe/{jobId}Acompanhe o processamento até status = "CONCLUIDO". Faça polling com intervalo ≥ 5 s.
{
"jobId": "7e1b3c44-...",
"status": "PROCESSANDO",
"totalNotas": 9800,
"processadas": 6210,
"duplicadas": 3,
"comErro": 1,
"canceladas": 12,
"finishedAt": null
}XML que não parseia conta em comErro — o job conclui
mesmo assim. canceladas são notas com evento de cancelamento detectado.
Receita para milhões de notas
- Gere ZIPs de até 10.000 XMLs (mês a mês costuma dar certo).
- Envie um ZIP → guarde o
jobId→ aguardeCONCLUIDO. - Mantenha no máximo 5 lotes em voo; ao receber
429, espere oRetry-After. - Carga caiu? Reenvie o mesmo ZIP — duplicadas não fazem mal.
- Produtos: páginas de 5.000, sequenciais.
Por trás: cada nota vira uma mensagem em fila (RabbitMQ) e o
consumo é paralelo — a API responde rápido mesmo sob carga, e a proteção degrada com
429 em vez de derrubar o serviço.
Cadastro de produtos em lote
/produtosJSON com até 5.000 itens por chamada (síncrono). Só codigo (ou ncm) é
obrigatório; reenvio atualiza o cadastro existente (casamento por código).
[
{ "codigo": "P001", "descricao": "ARROZ BRANCO TIPO 1 5KG",
"ncm": "10063021", "cfop": "5102",
"valorUnitario": 22.90, "quantidade": 1 }
]
# 200 OK
{ "importados": 4980 }Classificação por código de barras
/classificacao/{gtin}· opcional ?regime=SIMPLES|MEI|PRESUMIDO|REALEnvie o GTIN (8/12/13/14 dígitos) e receba três blocos: como o mercado classifica hoje (base de 5,2 milhões de códigos de barras, cortada pelo regime), o enquadramento na reforma pelas regras versionadas da Kontrib, e a carga da transição 2026→2033 calculada pelo mesmo motor auditável das análises.
Sem o parâmetro regime, vale o regime cadastrado da
empresa da chave. Simples/MEI recebem csosn; Presumido/Real recebem CST de ICMS,
PIS/COFINS com natureza de receita e IPI.
{
"gtin": "7891234500017",
"descricao": "ARROZ BRANCO TIPO 1 5KG",
"regime": "REAL",
"consenso": {
"ncm": "10063021", "ncmConcordancia": 96.5,
"cest": "1704700", "origem": "0",
"cstIcms": "00", "cstIcmsConcordancia": 88.0,
"aliquotaIcms": 7.00,
"cstPis": "06", "aliquotaPis": 0.00,
"cstCofins": "06", "aliquotaCofins": 0.00,
"naturezaReceita": "407",
"cstIpi": "53", "aliquotaIpi": 0.00,
"fontes": 210
},
"reforma": {
"cclasstrib": "200003", "cstIbsCbs": "200",
"rotulo": "Cesta básica nacional — Anexo I (alíquota zero)",
"enquadramento": "Alíquota zero",
"impostoSeletivo": false, "monofasicoHoje": false,
"aliquotaCbs2033": 0.00, "aliquotaIbs2033": 0.00,
"aliquotaTotal2033": 0.00
},
"transicao": [
{ "ano": 2026, "cargaFuturaPct": 0.00 },
{ "ano": 2027, "cargaFuturaPct": 0.00 },
"... um por ano até 2033"
],
"atualizadoEm": "2026-07-12T03:00:00Z",
"aviso": "Consenso de mercado da base Kontrib + sugestão pelas regras versionadas da reforma. Orientativo — a responsabilidade pela classificação é do contribuinte; confirme com o seu contador antes de aplicar no ERP."
}Como interpretar
| Bloco | O que é |
|---|---|
consenso | Como a maioria das empresas da base classifica ESTE código de barras hoje. ncmConcordancia/fontes medem a força — abaixo de ~80%, trate como sugestão fraca. A aliquotaIcms não tem dimensão de UF (referência, não parametrização). |
reforma | Enquadramento pelas regras versionadas (base legal pública na /metodologia): cclasstrib/cstIbsCbs prontos para o leiaute 2026 da NF-e, enquadramento (Alíquota zero · Redução 60% · Integral), Imposto Seletivo e alíquotas do modelo pleno. |
transicao | Carga futura efetiva (% sobre o valor) ano a ano, 2026→2033, para venda interna típica (CFOP 5102) no regime aplicado. Em 2026 o ano-teste é neutralizado (CBS/IBS compensáveis). |
aviso ao usuário final. Consenso de mercado
não é verdade fiscal — a responsabilidade pela classificação é do contribuinte, e a resposta
existe para ACELERAR a decisão dele, não para substituí-la.Erros: 404 GTIN fora da base (não é cobrado) · 422 GTIN malformado ou regime inválido.
Catálogo inteiro (lote)
/classificacao/loteAté 500 GTINs por chamada. Cada item tem o mesmo formato do GET, sem o bloco
transicao (use o GET unitário para o detalhe ano a ano).
curl -s -X POST https://app.kontrib.com.br/api/v1/erp/classificacao/lote \ -H "X-Api-Key: $KEY" -H "Content-Type: application/json" \ -d '{"gtins":["7891234500017","7891149100103","7890000000000"],"regime":"SIMPLES"}' # 200 OK { "itens": [ { "gtin": "7891234500017", "..." } ], "naoEncontrados": ["7890000000000"], "aviso": "Consenso de mercado da base Kontrib + ..." }
naoEncontrados e não é cobrado.Versionamento e mudanças
- O contrato
/api/v1/erpé estável: campos novos podem ser adicionados às respostas (ignore campos desconhecidos); nada é removido ou renomeado dentro da v1. - Mudança de regra fiscal não muda o contrato: reflete nos VALORES (
reforma/transicao), sempre versionada por vigência e publicada na /metodologia com base legal e changelog. - Especificação viva gerada da própria aplicação: Swagger UI · /v3/api-docs.
Segurança
- Tráfego 100% HTTPS; a chave nunca em URL.
- Só o hash SHA-256 da chave é armazenado; a chave em claro aparece uma única vez.
- A chave resolve a empresa e todo acesso a dados passa pelo Row-Level Security do banco — isolamento por cliente garantido na camada mais baixa.
- Força bruta bloqueada por IP (
429); rate limit por chave; sobrecarga degrada com429+Retry-After, nunca derruba nem silencia dados. - Auditoria: toda importação e uso de chave ficam registrados (LGPD desde o primeiro commit).