RotaCerta

Documentação da API — RotaCerta

API de cálculo de rotas para carro e caminhão na América do Sul, com estimativa de custo de combustível e pedágio. Todo acesso é autenticado por API key e consome créditos pré-pagos.

Autenticação

Envie sua chave no cabeçalho X-API-Key em toda requisição a endpoints que consomem dados ou crédito (/saldo e /rota). A chave é gerada e vinculada ao seu cadastro no momento da contratação — fale com o suporte Consultline caso não tenha a sua.

curl -H "X-API-Key: SUA_CHAVE_AQUI" https://rotacerta.consultline.com.br/saldo
Cada chamada a POST /rota consome 1 crédito do seu saldo, independente do resultado ter custo estimado ou não. Consultas a /saldo e /health não consomem crédito.

Status do serviço

GET/health

Não exige autenticação. Usado para monitoramento.

curl https://rotacerta.consultline.com.br/health
{
  "api": "ok",
  "valhalla": "ok"
}

Consultar saldo

GET/saldo

Retorna o saldo de créditos restante vinculado à API key informada.

curl -H "X-API-Key: SUA_CHAVE_AQUI" https://rotacerta.consultline.com.br/saldo
{
  "ok": true,
  "saldo_restante": 4820,
  "ilimitado": false,
  "motivo": null
}
CampoTipoDescrição
okboolfalse se a chave for inválida ou estiver bloqueada
saldo_restanteintcréditos restantes (chamadas a /rota ainda disponíveis)
ilimitadobooltrue para contratos sem limite de créditos
motivostring ou nullpreenchido quando ok=false (ex.: chave_invalida, bloqueado)

Calcular rota

POST/rota

Calcula distância, duração e (opcionalmente) custo estimado de combustível/pedágio entre 2 ou mais pontos.

Corpo da requisição

CampoTipoDescrição
waypointslista de {lat, lon, tempo_parada_min?, janela_inicio?, janela_fim?}, mínimo 2obrigatóriopontos da rota, na ordem — origem, paradas intermediárias, destino. tempo_parada_min é o tempo de carga/descarga previsto nessa parada (soma no tempo total da viagem, mas não conta como direção). janela_inicio/janela_fim (datetime ISO 8601) definem a janela de agendamento aceita nessa parada — exigem partida_prevista pra gerar janelas_horario na resposta
veiculo"carro", "caminhao", "onibus" ou "moto"obrigatóriodefine o perfil de roteamento (restrições de tráfego de caminhão/ônibus são respeitadas); custo de pedágio para ônibus/moto ainda sem tarifa cadastrada em nenhuma praça — vem null até ser cadastrado no módulo Administração do portal (Pedágios)
incluir_custosboolopcional, padrão falsese true, calcula estimativa de combustível e pedágio
incluir_geometriaboolopcional, padrão falsese true, retorna a linha da rota como lista de pontos [lat, lon]
km_por_litrofloat > 0opcionalconsumo do veículo do cliente; se omitido, usa um padrão por tipo de veículo
produto_combustivel"gasolina", "etanol", "diesel", "gnv" ou "glp"opcionalcombustível considerado no cálculo; se omitido, usa o padrão do tipo de veículo (gasolina para carro, diesel para caminhão)
arla_por_kmfloat ≥ 0opcionalconsumo de Arla 32/DEF em litros por km (só se aplica quando o combustível considerado é diesel); se omitido, estima automaticamente ~5% do volume de diesel consumido
evitar_balsasboolopcional, padrão falsedesestimula fortemente o uso de travessias de balsa/ferry no traçado da rota
evitar_pedagiosboolopcional, padrão falsedesestimula fortemente o uso de vias com pedágio no traçado da rota
evitar_balsas foi testado com uma travessia real (Itajaí–Navegantes/SC) e reroteou corretamente pela ponte. evitar_pedagios usa o mesmo mecanismo do motor de rotas (não é uma exclusão absoluta), mas em testes reais — inclusive num trecho com alternativa livre de pedágio bem conhecida — não produziu nenhuma mudança perceptível na rota. Considere esse parâmetro experimental até confirmarmos a causa (provável: os dados de pedágio usados aqui vêm de fonte própria/ANTT, não da mesma tag OSM que o motor de rotas usa para decidir o trajeto).
CampoTipoDescrição
preco_combustivel_manualfloat > 0opcionalpreço do combustível em R$/L informado pelo cliente; sobrepõe a média por município da ANP no cálculo de custo
eixos_caminhaoint, 2 a 9opcionalnúmero de eixos do caminhão; ajusta o valor do pedágio (tarifa base × eixos) nas praças onde essa política já foi confirmada — sem isso, assume 2 eixos. Também serve como eixos_frete se este não for informado à parte
data_tarifadate (AAAA-MM-DD)opcional, padrão hojeconsulta a tarifa de pedágio vigente nessa data em vez da tarifa atual — útil pra reconstituir o custo de uma rota antiga
tipo_carga_frete"carga_geral", "granel_solido", "granel_liquido", "frigorificada", "conteinerizada", "neogranel", "granel_pressurizada", "perigosa_carga_geral", "perigosa_granel_solido", "perigosa_granel_liquido", "perigosa_frigorificada" ou "perigosa_conteinerizada"opcionalse informado (só faz efeito com veiculo=caminhao), calcula o piso mínimo legal de frete (ANTT) e compara com o custo estimado da rota — categorias idênticas às da calculadora oficial
eixos_freteint (2, 3, 4, 5, 6, 7 ou 9 — 8 não existe nas tabelas oficiais)opcionalnúmero de eixos do caminhão, usado no cálculo do piso mínimo; sem coeficiente exato pro valor informado, usa o mais próximo disponível (mesma regra da calculadora oficial)
tabela_frete"A", "B", "C" ou "D"opcional, padrão "A"tabela ANTT: A = composição completa, B = só unidade de tração, C/D = operação de alto desempenho
retorno_vazio_freteboolopcional, padrão falsesoma ao piso mínimo o valor do retorno vazio (0,92 × distância × CCD) — obrigatório para contêineres e frotas dedicadas/certificadas, ver Res. ANTT 5.867/2020 art. 5º §6º
valor_frete_cobradofloat > 0opcionalpreço que você realmente pretende cobrar do cliente; se informado, vira a "Receita" do dre_simulado (senão usa o piso mínimo legal, se calculado)
valor_diariafloat > 0opcionalvalor da diária do motorista em R$; se omitido, usa a sugestão cadastrada no módulo Administração do portal (Valor da diária do motorista) (só com veiculo=caminhao)
partida_previstadatetime ISO 8601opcionaldata/hora prevista de saída do primeiro waypoint; habilita o cálculo de janelas_horario pra cada parada que tenha janela_inicio e/ou janela_fim definidos
rotear_paradas_descansoboolopcional, padrão falsesó com veiculo=caminhao: recalcula a rota incluindo as paradas obrigatórias da jornada do motorista (jornada_motorista.paradas_sugeridas) como waypoints reais, com o posto sugerido como ponto de passagem e tempo_parada_min igual à duração do descanso (30min pausa / 660min pernoite). distancia_km/duracao_min passam a refletir esse trajeto recalculado — podem mudar pra mais ou pra menos em relação à rota sem essa opção, já que o motor de rotas reavalia o caminho com esses pontos como paradas obrigatórias, não é sempre um acréscimo
considerar_impostosboolopcional, padrão truequando true (padrão), deduz ICMS (custo_icms_reais) e PIS/COFINS (custo_pis_cofins_reais) da margem do dre_simulado. ICMS: se a rota é interestadual, a alíquota (7% ou 12%) é resolvida automaticamente pela Res. Senado 22/1989 a partir da UF de origem/destino — a alíquota configurada no módulo Administração do portal (Impostos) só é usada pra rota dentro do mesmo estado. PIS/COFINS sempre usa a alíquota configurada no módulo Administração (Impostos); sem alíquota disponível, aquele imposto específico não é deduzido — nunca inventa um valor
valor_veiculofloat > 0opcionalvalor do veículo em R$, usado pra estimar depreciação no dre_simulado (custo_depreciacao_reais = valor ÷ vida útil em km × distância da viagem); se omitido, usa a sugestão por tipo de veículo cadastrada no módulo Administração do portal (Depreciação)
filial_idintopcionalid de uma filial cadastrada em /empresa/filiais; usada pra estimar credito_fiscal_pis_cofins (depende do regime tributário da filial). Se omitido, usa a filial padrão do usuário que fez a chamada (filial_id_padrao, configurável em /empresa/usuarios/{id}/filial-padrao), se houver. Sem nenhum dos dois, sugestao_filiais ainda aparece se a empresa tiver filiais cadastradas, só o crédito fica indisponível
Pra veiculo=caminhao, toda resposta inclui jornada_motorista (independente de incluir_custos) — o tempo real de viagem considerando as pausas/descansos obrigatórios da Lei 13.103/2015 (Lei do Motorista), em dias/horas/minutos, com sugestão de posto de combustível pra cada parada obrigatória. Com incluir_custos=true, o custo de diária (nº de pernoites × valor da diária) entra em custos.diaria e no dre_simulado.
O piso mínimo de frete é o valor mínimo que a lei permite cobrar do cliente (ANTT, Resolução 5.867/2020 e atualizações) — não é um preço sugerido, é uma obrigação legal. Os coeficientes (CCD/CC) vêm direto da calculadora oficial (calculadorafrete.antt.gov.br), consultada por uma sincronia própria — não são valores estimados ou aproximados. O comparativo retornado (frete_minimo) ajuda a decidir quanto cobrar, mas a responsabilidade de cumprir o piso é do transportador.
ICMS de transporte de cargas é devido ao estado de início da rota, não ao estado da filial que emite o CT-e — por isso sugestao_filiais aponta quais filiais cadastradas (/empresa/filiais) estão na mesma UF de origem da viagem (evita recolhimento antecipado), mas não calcula economia em R$: a alíquota efetiva varia por par de estados/protocolo específico, o que exigiria uma fonte fiscal caso a caso que não temos hoje. Já credito_fiscal_pis_cofins é sobre um valor federal (não varia por UF): só existe no regime não-cumulativo (tipicamente Lucro Real) sobre insumos como combustível e depreciação de frota — não abate o custo do frete nesse DRE, é um crédito que se acumula pra abater outros débitos federais da empresa no futuro.
curl -X POST https://rotacerta.consultline.com.br/rota \
  -H "X-API-Key: SUA_CHAVE_AQUI" \
  -H "Content-Type: application/json" \
  -d '{
    "waypoints": [
      {"lat": -23.5505, "lon": -46.6333},
      {"lat": -22.9068, "lon": -43.1729}
    ],
    "veiculo": "caminhao",
    "incluir_custos": true,
    "incluir_geometria": false,
    "km_por_litro": 3.2,
    "produto_combustivel": "diesel",
    "arla_por_km": 0.05
  }'

Resposta

{
  "distancia_km": 429.7,
  "duracao_min": 322.4,
  "tempo_parada_total_min": 30.0,
  "duracao_total_com_paradas_min": 352.4,
  "veiculo": "caminhao",
  "pernas": [
    {
      "origem": {"lat": -23.5505, "lon": -46.6333},
      "destino": {"lat": -22.9068, "lon": -43.1729},
      "distancia_km": 429.7,
      "duracao_min": 322.4
    }
  ],
  "custos": {
    "combustivel": {
      "produto": "diesel",
      "litros_estimados": 134.3,
      "preco_medio_litro": 6.12,
      "custo_estimado_reais": 822.1,
      "postos_considerados": [
        {"nome": "Posto Exemplo", "municipio": "Resende", "uf": "RJ", "preco_medio_litro": 6.05}
      ],
      "observacao": "preço médio por município (ANP), não por posto específico"
    },
    "arla": {
      "litros_estimados": 6.7,
      "preco_litro": 3.0,
      "custo_estimado_reais": 20.1,
      "fonte_consumo": "estimado (5% do diesel consumido)",
      "observacao": "estimativa de Arla 32/DEF para motor diesel com SCR; informe arla_por_km para usar seu consumo real"
    },
    "pedagio": {
      "custo_estimado_reais": 187.4,
      "pracas": [
        {
          "nome": "Praça Arujá",
          "concessionaria": "CCR RioSP",
          "fonte": "concessionaria",
          "valor": 46.9,
          "lat": -23.397,
          "lon": -46.321
        }
      ]
    }
  },
  "frete_minimo": {
    "tabela": "A",
    "tipo_carga": "carga_geral",
    "eixos": 2,
    "ccd_reais_km": 3.9826,
    "cc_reais": 451.84,
    "piso_minimo_reais": 2140.02,
    "custo_estimado_rota_reais": 1607.98,
    "margem_reais": 532.04,
    "margem_percentual": 33.1,
    "vigencia_inicio": "2026-07-17",
    "fonte": "ANTT - resolucao vigente (ver calculadorafrete.antt.gov.br)",
    "retorno_vazio_reais": null,
    "valor_frete_cobrado_reais": null,
    "diferenca_cobrado_para_piso_reais": null,
    "abaixo_do_piso": null,
    "observacao": "piso legal mínimo de frete (ANTT, Res. 5.867/2020 e atualizações); é o mínimo permitido por lei, não inclui lucro nem demais custos operacionais (motorista, manutenção, seguro etc.)"
  },
  "dre_simulado": {
    "receita_frete_reais": 2140.02,
    "origem_receita": "piso mínimo legal (ANTT) -- informe valor_frete_cobrado pra simular com o preço realmente cobrado",
    "custo_combustivel_reais": 822.1,
    "custo_arla_reais": 20.1,
    "custo_pedagio_reais": 765.78,
    "custo_diaria_reais": 300.0,
    "custo_depreciacao_reais": 200.0,
    "custo_icms_reais": 256.8,
    "aliquota_icms_percentual": 12.0,
    "origem_aliquota_icms": "interestadual SP→RJ, Res. Senado 22/1989",
    "custo_pis_cofins_reais": 78.11,
    "aliquota_pis_cofins_percentual": 3.65,
    "custo_variavel_total_reais": 2442.89,
    "margem_contribuicao_reais": -302.87,
    "margem_contribuicao_percentual": -14.15,
    "memoria_calculo": [
      "Receita do frete (piso mínimo legal (ANTT)...): R$ 2.140,02",
      "(-) Combustível (diesel): 134,3 L x R$ 6,12/L = R$ 822,10",
      "(-) Arla 32/DEF: 6,70 L x R$ 3,00/L = R$ 20,10",
      "(-) Pedágio (3 praça(s) na rota): R$ 765,78",
      "(-) Diária (2 pernoite(s), R$ 150,00/dia): R$ 300,00",
      "(-) Depreciação (R$ 0,334/km): R$ 200,00",
      "(-) ICMS sobre o frete (alíquota 12,00%): R$ 256,80",
      "(-) PIS/COFINS sobre o frete (alíquota 3,65%): R$ 78,11",
      "(=) Total de custos (com impostos, se habilitado): R$ 2.442,89",
      "(=) Margem de contribuição: R$ -302,87 (-14,2% da receita)",
      "(i) IBS+CBS (alíquotas-teste 2026, informativo -- aparece no documento fiscal mas não é recolhido nessa fase de transição): R$ 21,40",
      "(i) CIOT (informativo -- taxa de registro obrigatório por viagem, MP 1.343/2026, ajuste no módulo Administração > Impostos): R$ 3,00"
    ],
    "linhas_tabela": [
      {"descricao": "Receita do frete (piso mínimo legal (ANTT)...)", "valor_reais": 2140.02, "tipo": "receita"},
      {"descricao": "Combustível (diesel)", "valor_reais": 822.1, "tipo": "custo"},
      {"descricao": "Arla 32/DEF", "valor_reais": 20.1, "tipo": "custo"},
      {"descricao": "Pedágio", "valor_reais": 765.78, "tipo": "custo"},
      {"descricao": "Diária do motorista", "valor_reais": 300.0, "tipo": "custo"},
      {"descricao": "Depreciação do veículo", "valor_reais": 200.0, "tipo": "custo"},
      {"descricao": "ICMS sobre o frete (12.00%)", "valor_reais": 256.8, "tipo": "imposto"},
      {"descricao": "PIS/COFINS sobre o frete (3.65%)", "valor_reais": 78.11, "tipo": "imposto"},
      {"descricao": "Total de custos", "valor_reais": 2442.89, "tipo": "total"},
      {"descricao": "Margem de contribuição", "valor_reais": -302.87, "tipo": "margem"},
      {"descricao": "IBS+CBS (informativo, alíquota-teste 2026)", "valor_reais": 21.4, "tipo": "informativo"},
      {"descricao": "CIOT (informativo, taxa por viagem)", "valor_reais": 3.0, "tipo": "informativo"}
    ],
    "observacao": "simulação simplificada (margem de contribuição); inclui depreciação estimada do veículo mas não outros custos fixos (motorista, seguro, administrativo). ICMS e PIS/COFINS são alíquotas configuradas por você -- ajuste no módulo Administração > Impostos ou desative com considerar_impostos=false, nunca um cálculo fiscal exato"
  },
  "jornada_motorista": {
    "duracao_dirigindo_min": 322.4,
    "duracao_total_com_descansos_min": 982.4,
    "dias": 0,
    "horas": 16,
    "minutos": 22,
    "numero_pausas_curtas": 0,
    "numero_pernoites": 1,
    "paradas_sugeridas": [
      {
        "tipo": "pernoite",
        "km_percorrido": 380.5,
        "lat": -22.4,
        "lon": -44.5,
        "posto_sugerido": {"nome": "Posto Exemplo", "municipio": "Resende", "uf": "RJ", "preco_medio_litro": null, "lat": -22.45, "lon": -44.3},
        "distancia_posto_m": 340.2
      }
    ],
    "paradas_roteirizadas": false,
    "fonte": "Lei 13.103/2015 (Lei do Motorista) -- CLT art. 235-C a 235-E",
    "observacao": "modelo simplificado: direção contínua máxima 5h30 (pausa de 30min), jornada diária de direção de até 8h (descanso de 11h entre jornadas); não considera parada pra carga/descarga, refeições intermediárias, descanso semanal após 6 dias, nem extensão de jornada por acordo coletivo"
  },
  "janelas_horario": [
    {
      "indice_waypoint": 1,
      "horario_estimado_chegada": "2026-08-06T13:22:00",
      "janela_inicio": "2026-08-06T13:00:00",
      "janela_fim": "2026-08-06T14:00:00",
      "dentro_da_janela": true,
      "atraso_min": -38.0,
      "observacao": "horário estimado considera apenas tempo de direção e tempo de carga/descarga das paradas anteriores; não inclui pausas/descansos obrigatórios da jornada do motorista (ver jornada_motorista pro tempo total real da viagem em rotas longas de caminhão)"
    }
  ],
  "geometria": null,
  "sugestao_filiais": [
    {
      "filial_id": 1, "nome": "Matriz SP", "uf": "SP", "regime_tributario": "lucro_real",
      "uf_compativel_com_origem": true,
      "observacao": "Filial em SP, mesma UF de início da rota -- ICMS é devido a essa UF, sem recolhimento antecipado."
    },
    {
      "filial_id": 2, "nome": "Filial RJ", "uf": "RJ", "regime_tributario": "lucro_presumido",
      "uf_compativel_com_origem": false,
      "observacao": "Filial em RJ, rota inicia em SP -- ICMS é devido a SP independente de qual filial emite o CT-e; sem inscrição estadual lá, o recolhimento é feito antecipado (mesma alíquota, um passo extra de conformidade)."
    }
  ],
  "credito_fiscal_pis_cofins": {
    "filial_id": 1, "filial_nome": "Matriz SP", "regime_considerado": "lucro_real",
    "aliquota_credito_percentual": 9.25, "base_calculo_reais": 1022.1, "credito_estimado_reais": 94.55,
    "observacao": "Crédito federal (não varia por UF) sobre combustível + depreciação usados nesta viagem -- acumula, não reduz o custo do frete nesse DRE; use pra abater outros débitos federais da filial (ex: na compra de veículos).",
    "fonte": "Leis 10.637/2002 e 10.833/2003 (PIS/COFINS não-cumulativo); Solução de Consulta Cosit nº 90/2025 e jurisprudência do TRF4 sobre créditos de frete/depreciação de frota"
  }
}
CampoDescrição
distancia_km / duracao_mintotais da rota completa (duracao_min é só tempo de direção)
tempo_parada_total_min / duracao_total_com_paradas_minsoma dos tempo_parada_min informados nos waypoints, e o total de direção + paradas de carga/descarga (não inclui os descansos obrigatórios da jornada — esses estão em jornada_motorista)
pernasuma entrada por trecho entre waypoints consecutivos
janelas_horarionull se partida_prevista não foi informado; senão, uma entrada para cada waypoint que tenha janela_inicio e/ou janela_fim definidos, com o horário estimado de chegada e se ficou dentro da janela (atraso_min negativo = chegou adiantado)
custosnull se incluir_custos=false ou se nenhuma das duas estimativas pôde ser calculada
custos.combustivel.postos_consideradospostos ao longo da rota usados para compor o preço médio — lista vazia se não há posto com preço próximo à rota
custos.arlanull quando o combustível considerado não é diesel; fonte_consumo indica se o litro/km veio do arla_por_km informado ou da estimativa padrão de 5% do diesel
custos.pedagio.pracaspraças de pedágio encontradas ao longo da rota, na ordem em que aparecem; valor: null quando a praça existe mas não há tarifa cadastrada para a categoria do veículo -- pra categoria carro (e caminhão com eixos_caminhao informado), se houver 1 praça sem tarifa nessa lista, o valor é preenchido automaticamente via Google Routes API e persistido pra próximas chamadas (sem repetir a consulta)
custos.pedagio.complemento_google_reaispresente só quando 2+ praças da rota estão sem tarifa cadastrada ao mesmo tempo (categoria carro/caminhão-com-eixos) -- nesse caso não é possível decompor o valor agregado do Google entre as praças individualmente, então o complemento entra só no total (custo_estimado_reais), com complemento_google_observacao explicando quantas praças ele cobre; fica cacheado localmente por essa combinação específica de praças, sem repetir a consulta
custos.diariapresente só com veiculo=caminhao e jornada_motorista calculada; numero_diarias = número de pernoites obrigatórios, pode ser 0 (viagem cabe em um dia, sem custo de diária)
jornada_motoristapresente só com veiculo=caminhao, independente de incluir_custos (é sobre tempo, não custo); paradas_sugeridas tem uma entrada por pausa/pernoite obrigatório — lat/lon nessa entrada é o ponto interpolado na rota original, enquanto posto_sugerido.lat/posto_sugerido.lon é a localização real do posto de combustível mais próximo (pode vir posto_sugerido: null, e nesse caso sem lat/lon nenhum, se não achar nenhum posto nas proximidades); paradas_roteirizadas indica se essas paradas já foram incluídas como waypoints reais no trajeto (só true quando rotear_paradas_descanso=true foi enviado e a nova rota foi calculada com sucesso)
frete_minimopresente só quando tipo_carga_frete+eixos_frete foram informados com veiculo=caminhao; os números do exemplo acima são reais (Tabela A, carga geral, 2 eixos, vigentes desde a Res. ANTT nº 6.084/26), não uma ilustração; eixos pode vir diferente do eixos_frete pedido se não houver coeficiente exato (usa o mais próximo); retorno_vazio_reais só vem preenchido se retorno_vazio_frete=true; margem_* (piso vs. custo operacional da rota) só vem preenchido se custos também foi calculado; valor_frete_cobrado_reais/diferenca_cobrado_para_piso_reais/abaixo_do_piso (piso vs. valor cobrado do cliente — comparação diferente da anterior) só vêm preenchidos se valor_frete_cobrado foi informado no request; diferenca_cobrado_para_piso_reais é valor_frete_cobrado − piso_minimo_reais (negativo = abaixo do piso legal)
dre_simuladonull só se incluir_custos=false ou nenhum custo pôde ser calculado — sempre presente quando há algum custo disponível, mesmo sem nenhuma receita informada (o objetivo é abrir todos os custos da viagem, a comparação com receita é um extra). "Receita" (receita_frete_reais) vem de valor_frete_cobrado quando informado, senão do piso mínimo legal, senão de uma sugestão por markup (preço que renderia a margem de contribuição padrão da empresa — ou global, se a empresa não configurou a própria — sobre o custo operacional, ver margem_contribuicao_padrao_percentual em /empresa/preferencias e no módulo Administração do portal (Margem de contribuição padrão)), senão fica null só se nem isso for calculável; memoria_calculo é a lista de linhas prontas pra exibir em texto, na ordem; linhas_tabela é a mesma informação em formato estruturado (descricao/valor_reais/tipo) pra montar uma tabela colorida por tipo (receita/custo/imposto/total/margem/informativo) em vez de parsear texto; é uma margem de contribuição (receita − custos variáveis da viagem − depreciação − ICMS − PIS/COFINS, conforme habilitado), não um DRE contábil completo — não inclui custos fixos como motorista/seguro/administrativo. custo_depreciacao_reais usa o valor sugerido por tipo de veículo (módulo Administração do portal, Depreciação) quando valor_veiculo não é informado. custo_icms_reais e custo_pis_cofins_reais são deduzidos independentemente quando considerar_impostos=true (padrão) — configurar só um dos dois é válido (o outro fica null, sem bloquear a dedução do que foi configurado). Pra ICMS interestadual, aliquota_icms_percentual vem resolvido automaticamente (7% ou 12%, Res. Senado 22/1989) e origem_aliquota_icms explica de onde veio ("interestadual UF→UF, Res. Senado 22/1989" ou "alíquota interna configurada no módulo Administração > Impostos" pra rota dentro do mesmo estado); sem alíquota disponível em nenhum dos dois casos, o campo vem null. IBS/CBS (alíquota-teste 2026) e CIOT aparecem em linhas_tabela com tipo="informativo" — nunca entram em custo_variavel_total_reais nem na margem
geometrianull se incluir_geometria=false; senão, lista de pontos [lat, lon] pronta para desenhar num mapa (ex.: Leaflet)
sugestao_filiaisnull se a empresa não tem nenhuma filial cadastrada em /empresa/filiais; senão, uma entrada por filial ativa, ordenadas com as de uf_compativel_com_origem=true primeiro — indica quais filiais já estão na UF de início da rota (ICMS devido a essa UF), não uma economia calculada em R$
credito_fiscal_pis_cofinsnull se nenhum custo pôde ser calculado (precisa de incluir_custos=true); credito_estimado_reais só vem preenchido se filial_id foi informado e essa filial está no regime não-cumulativo (Lucro Real) — Simples Nacional e Lucro Presumido não geram esse crédito (fica null com a observacao explicando o motivo)
Cobertura de custo é incremental: pedágio e preço de combustível hoje têm melhor cobertura nas rodovias e municípios já cadastrados (foco inicial: eixo Rio–São Paulo). Fora dessa cobertura, custos pode voltar com listas vazias ou custo_estimado_reais: null — a distância e duração da rota continuam sempre confiáveis.

Reportar erro de rota

POST/rota/reportar-erro

Registra que uma rota calculada não corresponde à realidade, para revisão da equipe Consultline. Não consome crédito.

curl -X POST https://rotacerta.consultline.com.br/rota/reportar-erro \
  -H "X-API-Key: SUA_CHAVE_AQUI" \
  -H "Content-Type: application/json" \
  -d '{
    "waypoints": [{"lat": -23.5505, "lon": -46.6333}, {"lat": -22.9068, "lon": -43.1729}],
    "veiculo": "caminhao",
    "mensagem": "pedágio da praça X não existe mais nessa rodovia"
  }'

Conta: histórico, rotas salvas e preferências

Não existe senha separada — a própria X-API-Key é o login, individual por usuário (controle de acesso em 3 níveis: usuario, admin e super_admin, ver seção Empresa). Créditos são compartilhados por todos os usuários da mesma empresa. Nenhum endpoint desta seção consome crédito.

Histórico de chamadas

GET/historico

Lista as últimas chamadas a POST /rota feitas com essa API key (toda chamada bem-sucedida é registrada automaticamente).

curl -H "X-API-Key: SUA_CHAVE_AQUI" "https://rotacerta.consultline.com.br/historico?limite=20"
[
  {
    "id": 42,
    "waypoints": [{"lat": -23.5505, "lon": -46.6333}, {"lat": -22.9068, "lon": -43.1729}],
    "veiculo": "caminhao",
    "distancia_km": 429.7,
    "duracao_min": 322.4,
    "custo_total_reais": 1029.5,
    "valor_faturado_reais": null,
    "criado_em": "2026-08-05T14:22:10.123Z"
  }
]

limite é opcional (padrão 50, máximo 200); offset é opcional (padrão 0) — pra paginar sobre todo o histórico, nunca só uma janela dos mais recentes. Lista só o histórico do próprio usuário que fez a chamada. Nenhuma chamada é apagada automaticamente — o histórico completo fica salvo até você mesmo excluir alguma entrada.

Excluir uma chamada do histórico

DELETE/historico/{id}

Remove permanentemente uma entrada do próprio histórico. Só apaga se o id pertencer ao usuário que fez a chamada — devolve 404 caso contrário.

curl -X DELETE https://rotacerta.consultline.com.br/historico/42 \
  -H "X-API-Key: SUA_CHAVE_AQUI"

Registrar faturamento real de uma viagem

POST/historico/{id}/faturamento

Registra o valor realmente cobrado naquela viagem específica (qualquer papel pode chamar, só pro próprio histórico) — permite comparar depois margem real vs. o dre_simulado calculado na hora. Só pode ser chamado uma vez por id de histórico útil; chamadas seguintes sobrescrevem o valor.

curl -X POST https://rotacerta.consultline.com.br/historico/42/faturamento \
  -H "X-API-Key: SUA_CHAVE_AQUI" \
  -H "Content-Type: application/json" \
  -d '{"valor_faturado_reais": 2500.00}'

Rotas salvas

GET/rotas-salvas
POST/rotas-salvas
DELETE/rotas-salvas/{id}

Grupos de rota nomeados, salvos pra reutilizar depois — opcoes é um objeto livre (mesmos campos aceitos por POST /rota, ex.: km_por_litro, evitar_pedagios) devolvido junto quando a lista é consultada. Opcionalmente aceita geometria (mesmo formato de POST /rota) e resultado_calculado (objeto livre — normalmente um retrato do que POST /rota devolveu naquele momento: distancia_km, duracao_min, custos, frete_minimo, dre_simulado, jornada_motorista), pra não precisar recalcular do zero toda vez que a rota salva for reaberta.

curl -X POST https://rotacerta.consultline.com.br/rotas-salvas \
  -H "X-API-Key: SUA_CHAVE_AQUI" \
  -H "Content-Type: application/json" \
  -d '{
    "nome": "SP -> RJ semanal",
    "waypoints": [{"lat": -23.5505, "lon": -46.6333}, {"lat": -22.9068, "lon": -43.1729}],
    "veiculo": "caminhao",
    "opcoes": {"eixos_caminhao": 6, "evitar_pedagios": false},
    "geometria": [[-23.5505, -46.6333], [-23.0, -45.0], [-22.9068, -43.1729]],
    "resultado_calculado": {"distancia_km": 429.7, "duracao_min": 322.4}
  }'

DELETE /rotas-salvas/{id} só remove se o id pertencer à API key que fez a chamada — devolve 404 caso contrário.

Empresa: usuários e preferências

admin e super_admin gerenciam os usuários e os valores padrão da própria empresa (nunca de outra). usuario só pode ler as preferências, não alterar.

Preferências padrão da empresa

GET/empresa/preferencias
PUT/empresa/preferencias admin/super_admin

Valores padrão (veículo, consumo, evitar balsas/pedágios, valor da diária, margem de contribuição padrão) usados para pré-preencher o formulário do portal, como piso de valor_diaria em POST /rota quando não informado, e como base da sugestão de receita por markup no dre_simulado — não têm efeito em chamadas diretas à API que já informam o campo explicitamente. margem_contribuicao_padrao_percentual tem prioridade sobre o padrão global (módulo Administração do portal, Margem de contribuição padrão) quando definido.

curl -X PUT https://rotacerta.consultline.com.br/empresa/preferencias \
  -H "X-API-Key: SUA_CHAVE_DE_ADMIN_AQUI" \
  -H "Content-Type: application/json" \
  -d '{
    "veiculo_padrao": "caminhao",
    "km_por_litro_padrao": 3.2,
    "evitar_pedagios_padrao": false,
    "valor_diaria_padrao": 180.00,
    "margem_contribuicao_padrao_percentual": 25.0
  }'

Usuários da empresa

GET/empresa/usuarios admin/super_admin
POST/empresa/usuarios admin/super_admin
POST/empresa/usuarios/{id}/desativar admin/super_admin
PUT/empresa/usuarios/{id}/filial-padrao admin/super_admin

Cria um novo usuário na própria empresa com papel "usuario" ou "admin" — a API key gerada só é devolvida nessa resposta, não há como recuperá-la depois (só reemitir criando outro usuário). filial_id_padrao (opcional, em /empresa/filiais) é usado como filial_id em POST /rota quando esse usuário faz a chamada sem informar um explicitamente -- ajustável depois em PUT /empresa/usuarios/{id}/filial-padrao.

curl -X POST https://rotacerta.consultline.com.br/empresa/usuarios \
  -H "X-API-Key: SUA_CHAVE_DE_ADMIN_AQUI" \
  -H "Content-Type: application/json" \
  -d '{"nome": "Motorista João", "papel": "usuario", "filial_id_padrao": 1}'
{
  "id": 5,
  "nome": "Motorista João",
  "papel": "usuario",
  "ativo": true,
  "criado_em": "2026-08-06T13:00:00Z",
  "filial_id_padrao": 1,
  "filial_nome_padrao": null,
  "api_key": "chave-gerada-so-aparece-aqui"
}
curl -X PUT https://rotacerta.consultline.com.br/empresa/usuarios/5/filial-padrao \
  -H "X-API-Key: SUA_CHAVE_DE_ADMIN_AQUI" \
  -H "Content-Type: application/json" \
  -d '{"filial_id": 2}'

filial_id: null remove a filial padrão do usuário.

Filiais da empresa

GET/empresa/filiais
POST/empresa/filiais admin/super_admin
PUT/empresa/filiais/{id} admin/super_admin
POST/empresa/filiais/{id}/desativar admin/super_admin

Cadastro de município/UF/regime tributário ("simples_nacional", "lucro_presumido" ou "lucro_real") por filial. Usado em POST /rota pra sugerir qual filial faturar (comparando a UF de cada filial com a UF de início da rota, já que o ICMS de transporte é devido ao estado de início da prestação — ver sugestao_filiais na resposta de /rota) e pra estimar o crédito de PIS/COFINS de cada viagem quando a filial escolhida (filial_id em POST /rota) está no regime não-cumulativo.

curl -X POST https://rotacerta.consultline.com.br/empresa/filiais \
  -H "X-API-Key: SUA_CHAVE_DE_ADMIN_AQUI" \
  -H "Content-Type: application/json" \
  -d '{
    "nome": "Matriz SP",
    "municipio": "São Paulo",
    "uf": "SP",
    "inscricao_estadual": "110.042.490.114",
    "regime_tributario": "lucro_real"
  }'
{
  "id": 1,
  "nome": "Matriz SP",
  "municipio": "São Paulo",
  "uf": "SP",
  "inscricao_estadual": "110.042.490.114",
  "regime_tributario": "lucro_real",
  "ativo": true,
  "criado_em": "2026-08-10T17:26:55Z"
}

Códigos de erro

HTTPQuando ocorreCorpo
402 API key inválida, usuário inativo, ou sem créditos restantes {"erro": "chave_invalida" | "inativo" | "bloqueado" | "sem_saldo", "mensagem": "..."}
403 endpoint /empresa/* de gestão chamado com papel usuario (exige admin ou super_admin) {"erro": "permissao_insuficiente", "mensagem": "..."}
422 corpo da requisição inválido (campo faltando/tipo errado), ou não foi possível traçar rota entre os pontos informados {"erro": "rota_nao_encontrada", "motivo": "..."} ou erro de validação padrão do FastAPI
503 sistema de billing (Odoo) temporariamente indisponível — tente novamente em instantes {"erro": "billing_indisponivel"}

Dúvidas ou necessidade de aumentar cobertura de pedágio/combustível numa rodovia específica: fale com o suporte Consultline.