Introdução
TribAPI é uma API de decisão, não um emissor: você manda uma operação, ela devolve o tratamento IBS/CBS correto — CST, cClassTrib, alíquotas e valores calculados — com explicação e fonte oficial, prontos para injetar no XML da NF-e/NFC-e/NFS-e.
confidence: "review" em vez de um valor chutado; toda regra tem janela de validade e citação oficial; e toda resposta carrega engineVersion/rulesetVersion para rastreabilidade.
Base URL: https://api.tribapi.com.br
Todos os endpoints falam JSON (exceto /v1/validate*, que recebem XML de NF-e) e retornam Content-Type: application/json; charset=utf-8, mais os headers X-Engine-Version e X-Ruleset-Version em toda resposta.
Autenticação
Endpoints pagos exigem uma chave no header Authorization, no formato Bearer:
Authorization: Bearer trib_live_xxxxxxxxxxxxxxxxxxxxxxxx
Chaves trib_test_... (modo sandbox) e trib_live_... (modo produção) usam o mesmo formato. Chaves de teste nunca são cobradas e nunca sincronizam uso para a Stripe. Pegue uma chave de teste grátis em tribapi.com.br/#comecar — sem cartão, na hora.
| Situação | Resposta |
|---|---|
| Header ausente ou chave inválida/revogada | 401 unauthorized |
| Limite de taxa excedido | 429 rate_limited |
Formato de erro
Todo erro segue a mesma forma, com um code estável para tratar programaticamente e uma message legível:
{
"error": {
"code": "validation_error",
"message": "Operation payload is invalid.",
"details": [
"\`kind\` must be one of: venda, prestacao_servico, devolucao, transferencia, exportacao.",
"\`emitter\` object is required."
]
}
}
details só aparece quando faz sentido (erros de validação, principalmente) — nunca é preciso adivinhar o que falhou.
Idempotência
Em POST /v1/tax-decision, envie um header Idempotency-Key (qualquer string única sua) para tornar retries seguros. Uma repetição com a mesma chave retorna a resposta cacheada — mesmo status, mesmo corpo, nunca cobrada de novo — e vem com Idempotency-Replayed: true.
Idempotency-Key: pedido-83291-tentativa-1
Limites de taxa
Aplicados por chave, janela deslizante de 60 segundos. Ao estourar, toda rota autenticada responde 429 rate_limited informando o próprio limite no corpo do erro.
| Tier | Limite |
|---|---|
Dev (self-serve, trib_test_) | 10 req/min |
| Starter | 30 req/min |
| Growth | 210 req/min |
| Scale | negociado por contrato |
O validador gratuito (/v1/validate/free) tem limite próprio por IP (12/min), bem mais baixo — pensado para bloquear abuso anônimo, não uso legítimo.
Confidence & review
Toda decisão do engine carrega um nível de confiança — é assim que a API admite o que não sabe em vez de chutar:
| Valor | Significado |
|---|---|
deterministic | Premissa verificada (regra verified), matemática exata. |
classified_unverified | Matemática exata, mas a categoria do item veio de classificação por LLM ainda não confirmada — confirme via POST /v1/catalog/confirm. |
review | O engine se recusa a decidir. reviewReasons traz o motivo acionável — nunca um valor inventado. |
Motor de decisão
/v1/tax-decisionRequer chaveO endpoint central. Manda uma operação, recebe CST, cClassTrib, alíquotas e valores de IBS/CBS — ou review com o motivo, nunca um chute. Suporta Idempotency-Key (ver acima).
Corpo da requisição
| Campo | Descrição | |
|---|---|---|
| date | obrigatório | ISO 8601, ex. "2026-08-15". Define qual janela de regra temporal se aplica. |
| documentType | obrigatório | nfe · nfce · nfse |
| kind | obrigatório | venda · prestacao_servico · devolucao · transferencia · exportacao |
| emitter.regime | obrigatório | lucro_real · lucro_presumido · simples_nacional · mei |
| emitter.uf | obrigatório | UF do emitente |
| recipient.uf | obrigatório | UF do destinatário |
| recipient.finalConsumer | opcional | afeta operações estilo NFC-e |
| item.description | obrigatório | texto livre — usado pela classificação quando não há taxCategory |
| item.ncm | opcional | NCM (8 dígitos) ou código de serviço |
| item.taxCategory | opcional | categoria já resolvida (pula a classificação) — ver catálogo |
| item.quantity / unitValue | obrigatório | numéricos |
Exemplo
curl -X POST https://api.tribapi.com.br/v1/tax-decision \
-H "Authorization: Bearer trib_live_..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: pedido-83291" \
-d '{
"date": "2026-03-10",
"documentType": "nfe",
"kind": "venda",
"emitter": { "regime": "lucro_real", "uf": "SP" },
"recipient": { "uf": "RJ" },
"item": {
"description": "Notebook 14 pol",
"ncm": "84713012",
"taxCategory": "padrao",
"quantity": 1,
"unitValue": 5000.00
}
}'
Resposta 200 — confidence: "deterministic"
{
"engineVersion": "0.1.0",
"rulesetVersion": "2026.07.0-seed",
"applicable": true,
"cst": "000",
"cClassTrib": "000001",
"cbs": { "base": 5000, "rate": 0.009, "value": 45 },
"ibs": {
"uf": { "base": 5000, "rate": 0.0005, "value": 2.5 },
"municipal": { "base": 5000, "rate": 0.0005, "value": 2.5 }
},
"explanation": [
"Item classificado como \\"padrao\\" → fator de alíquota 1 (category.treatments.lc214-base).",
"CST-IBS/CBS 000 — Tributação integral.",
"cClassTrib 000001 (cclasstrib.standard).",
"Base de cálculo R$ 5000.00; CBS 0.9000% = R$ 45.00; IBS UF 0.0500% = R$ 2.50; IBS Municipal 0.0500% = R$ 2.50 (rate.teste-2026).",
"2026: destaque meramente informativo — recolhimento dispensado desde que cumpridas as obrigações acessórias (LC 214/2025, art. 348)."
],
"sources": [
{ "ruleId": "rate.teste-2026", "source": "LC 214/2025, art. 348 (alíquotas-teste)", "url": "https://www.planalto.gov.br/ccivil_03/leis/lcp/Lcp214.htm" }
],
"confidence": "deterministic",
"mode": "live"
}
Resposta 200 — confidence: "review" (item não mapeado)
{
"engineVersion": "0.1.0",
"rulesetVersion": "2026.07.0-seed",
"applicable": true,
"confidence": "review",
"explanation": [],
"sources": [],
"reviewReasons": [
"Item \\"Item sem classificação\\" sem taxCategory resolvida e sem NCM. Encaminhar à camada de classificação."
],
"mode": "live"
}
ncm nem taxCategory, o item passa pela classificação (catálogo → LLM → review). Toda chamada é registrada para métrica, inclusive as que caem em review (flag BILL_REVIEW_DECISIONS).Validação de NF-e
/v1/validateRequer chaveRecebe o XML de uma NF-e/NFC-e já emitida (autorizada), roda cada item pelo mesmo engine de decisão e compara com o que foi declarado no grupo UB (IBS/CBS) — sinalizando risco de rejeição, especialmente a 1115 (documento sem os campos IBS/CBS após 03/08/2026).
Corpo
XML bruto (Content-Type: application/xml) ou envelope JSON { "xml": "..." }. Máximo 512KB por documento.
Exemplo
curl -X POST https://api.tribapi.com.br/v1/validate \
-H "Authorization: Bearer trib_live_..." \
-H "Content-Type: application/xml" \
--data-binary @nota-fiscal.xml
Resposta 200
{
"document": {
"model": "55",
"key": "53260199999999000191550010000008281155473668",
"date": "2026-01-10",
"emitter": { "regime": "simples_nacional", "uf": "DF" }
},
"items": [
{ "nItem": 1, "description": "BICICLETA VENZO THUNDER A/29", "status": "ok", "confidence": "deterministic", "findings": [] }
],
"summary": { "status": "ok", "risks": 0, "reviews": 0, "rejection1115Enforced": false },
"mode": "live"
}
summary.status é "ok", "risk" ou "review". Cada item com problema traz findings[] explicando o que diverge do esperado (código, valor, ou grupo UB ausente quando deveria estar presente).
/v1/validate/freePúblico — sem chaveMesmo parser/diff de /v1/validate, sem autenticação.
Exemplo
curl -X POST https://api.tribapi.com.br/v1/validate/free \
-H "Content-Type: application/xml" \
--data-binary @nota-fiscal.xml
Resposta idêntica à de /v1/validate, mais "free": true.
Catálogo
/v1/catalog/confirmRequer chaveGrowth ou superiorConfirma a categoria tributária de uma descrição de item — vira memória por cliente. A próxima decisão com a mesma descrição (normalizada: acento/caixa/espaço não importam) usa o catálogo em vez de chamar o classificador de novo, e sai como confidence: "deterministic".
403 forbidden.Corpo
| Campo | Descrição | |
|---|---|---|
| description | obrigatório | mesma descrição usada em item.description |
| taxCategory | obrigatório | uma das 9 categorias (padrao, reducao_60, reducao_30, aliquota_zero, isento, imune, suspensao, diferimento, monofasica) |
| ncm | opcional | 8 dígitos |
Resposta 200
{ "confirmed": true, "description": "Notebook 14 pol", "ncm": "84713012", "taxCategory": "padrao" }
/v1/catalogRequer chaveGrowth ou superiorLista o catálogo do cliente, ordenado por uso.
{
"items": [
{ "description": "Notebook 14 pol", "ncm": "84713012", "taxCategory": "padrao", "verified": true, "hits": 42, "updatedAt": "2026-07-01 10:22:00" }
]
}
Conta
/v1/usageRequer chaveResumo de uso do mês corrente (ou de um mês específico via ?month=2026-06). Reflete exatamente o que será sincronizado para a Stripe.
{
"month": "2026-07",
"total": 138,
"billable": 120,
"byEndpoint": { "/v1/tax-decision": 90, "/v1/validate": 48 },
"byConfidence": { "deterministic": 101, "classified_unverified": 12, "review": 25 }
}
/v1/healthPúblicoStatus do serviço, versão do engine e do ruleset ativo.
{ "status": "ok", "engineVersion": "0.1.0", "rulesetVersion": "2026.07.0-seed" }