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.

Quatro garantias que valem para toda resposta: o LLM nunca faz conta nem escolhe alíquota — só classifica; qualquer lacuna vira 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:

header
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çãoResposta
Header ausente ou chave inválida/revogada401 unauthorized
Limite de taxa excedido429 rate_limited

Formato de erro

Todo erro segue a mesma forma, com um code estável para tratar programaticamente e uma message legível:

400 / 422 / 429 / 500
{
  "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.

header opcional
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.

TierLimite
Dev (self-serve, trib_test_)10 req/min
Starter30 req/min
Growth210 req/min
Scalenegociado 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:

ValorSignificado
deterministicPremissa verificada (regra verified), matemática exata.
classified_unverifiedMatemática exata, mas a categoria do item veio de classificação por LLM ainda não confirmada — confirme via POST /v1/catalog/confirm.
reviewO engine se recusa a decidir. reviewReasons traz o motivo acionável — nunca um valor inventado.

Motor de decisão

POST/v1/tax-decisionRequer chave

O 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

CampoDescrição
dateobrigatórioISO 8601, ex. "2026-08-15". Define qual janela de regra temporal se aplica.
documentTypeobrigatórionfe · nfce · nfse
kindobrigatóriovenda · prestacao_servico · devolucao · transferencia · exportacao
emitter.regimeobrigatóriolucro_real · lucro_presumido · simples_nacional · mei
emitter.ufobrigatórioUF do emitente
recipient.ufobrigatórioUF do destinatário
recipient.finalConsumeropcionalafeta operações estilo NFC-e
item.descriptionobrigatóriotexto livre — usado pela classificação quando não há taxCategory
item.ncmopcionalNCM (8 dígitos) ou código de serviço
item.taxCategoryopcionalcategoria já resolvida (pula a classificação) — ver catálogo
item.quantity / unitValueobrigatórionuméricos

Exemplo

curl
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"

200 OK
{
  "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)

200 OK — sem valor, sem chute
{
  "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"
}
Sem 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

POST/v1/validateRequer chave

Recebe 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
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

200 OK
{
  "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).

POST/v1/validate/freePúblico — sem chave

Mesmo parser/diff de /v1/validate, sem autenticação.

Exemplo

curl — sem Authorization
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

POST/v1/catalog/confirmRequer chaveGrowth ou superior

Confirma 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".

Disponível a partir do plano Growth. Chaves Dev/Starter recebem 403 forbidden.

Corpo

CampoDescrição
descriptionobrigatóriomesma descrição usada em item.description
taxCategoryobrigatóriouma das 9 categorias (padrao, reducao_60, reducao_30, aliquota_zero, isento, imune, suspensao, diferimento, monofasica)
ncmopcional8 dígitos

Resposta 200

200 OK
{ "confirmed": true, "description": "Notebook 14 pol", "ncm": "84713012", "taxCategory": "padrao" }
GET/v1/catalogRequer chaveGrowth ou superior

Lista o catálogo do cliente, ordenado por uso.

200 OK
{
  "items": [
    { "description": "Notebook 14 pol", "ncm": "84713012", "taxCategory": "padrao", "verified": true, "hits": 42, "updatedAt": "2026-07-01 10:22:00" }
  ]
}

Conta

GET/v1/usageRequer chave

Resumo 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.

200 OK
{
  "month": "2026-07",
  "total": 138,
  "billable": 120,
  "byEndpoint": { "/v1/tax-decision": 90, "/v1/validate": 48 },
  "byConfidence": { "deterministic": 101, "classified_unverified": 12, "review": 25 }
}
GET/v1/healthPúblico

Status do serviço, versão do engine e do ruleset ativo.

200 OK
{ "status": "ok", "engineVersion": "0.1.0", "rulesetVersion": "2026.07.0-seed" }