Referência técnica

Endpoints, campo a campo

Aqui está o que cada endpoint espera receber e cada formato de resposta possível, com exemplo real de corpo de requisição e resposta para cada um. Se você ainda não leu, vale começar pela visão geral de como o sistema funciona primeiro.

Antes de começar: toda rota, exceto /health, exige o cabeçalho Authorization: Bearer <sua-chave>. Sem ele (ou com uma chave inválida), a resposta é sempre 401.
POST /api/v1/frete/calcular

Recebe origem, destino e as regras de cobrança; devolve distância e valor do frete.

Corpo da requisição

CampoObrigatórioDescrição
origem.ruasimNome da rua
origem.numerosimNúmero do imóvel
origem.bairrosimBairro
origem.cidadesimCidade
origem.ufsimSigla do estado (2 letras)
origem.cepnãoAjuda a desambiguar o endereço
origem.lat / origem.lngnão, juntosSe enviados, pulam a geocodificação
origem.rua_confirmadanãoPula a correção automática do nome da rua
destino.*simMesma estrutura de origem
valor_kmsimPreço cobrado por km rodado, > 0
parametros.taxa_basenãoValor fixo somado ao frete (padrão 0)
parametros.frete_minimonãoPiso do valor final (padrão 0)
parametros.frete_maximonãoTeto do valor final
parametros.raio_max_kmnãoDistância máxima de entrega (0,5 a 100)
parametros.fator_rotanãoMultiplicador sobre a linha reta (padrão 1,30)
parametros.arredondamento_kmnãoDegrau de arredondamento: 0, 0.1, 0.5 ou 1 (padrão 0,5)
parametros.subtotalnãoValor do carrinho, usado com frete_gratis_acima
parametros.frete_gratis_acimanãoA partir de qual subtotal o frete fica grátis

Exemplo de requisição

POST /api/v1/frete/calcular
Authorization: Bearer SUA_CHAVE
Content-Type: application/json

{
  "origem": {
    "rua": "Rua Barão de Jaguara",
    "numero": "1000",
    "bairro": "Centro",
    "cidade": "Campinas",
    "uf": "SP"
  },
  "destino": {
    "rua": "Av Brasil",
    "numero": "250",
    "bairro": "Jardim Guanabara",
    "cidade": "Campinas",
    "uf": "SP"
  },
  "valor_km": 1.50,
  "parametros": {
    "taxa_base": 3.00,
    "frete_minimo": 5.00,
    "raio_max_km": 10
  }
}

Resposta — 200 OK

{
  "data": {
    "entrega": true,
    "valor": 11.25,
    "distancia_km": 5.5,
    "distancia_linha_reta_km": 4.2,
    "frete_gratis": false,
    "detalhamento": {
      "taxa_base": 3.00,
      "valor_km": 1.50,
      "valor_distancia": 8.25,
      "aplicou_minimo": false,
      "aplicou_maximo": false
    },
    "origem": {
      "lat": -22.9035,
      "lng": -47.0602,
      "precisao": "numero",
      "rua_utilizada": "Rua Barão de Jaguara",
      "rua_corrigida": false,
      "endereco_formatado": "Rua Barão de Jaguara, 1000, Centro, Campinas, SP"
    },
    "destino": { "...": "mesmo formato de origem" },
    "requer_confirmacao": false
  },
  "message": ""
}

Outras respostas possíveis

200 Fora do raio entrega: false, valor: null — endereço válido, mas fora do raio máximo configurado.
400 Dados inválidos Campo obrigatório faltando ou fora do formato esperado.
401 Sem autorização Chave de API ausente ou inválida.
422 Rua ambígua Nome digitado parecido com mais de uma rua conhecida — vêm sugestões pra escolher.
422 Não localizado Endereço não encontrado — reenvie com lat/lng.
429 Muitas requisições Limite por minuto da sua chave excedido.
503 Indisponível Serviço de mapas externo fora do ar — tente de novo em instantes.
Ver exemplo — 400, dados inválidos
{
  "data": {
    "erros": [
      "O campo 'origem.rua' e obrigatorio.",
      "O campo 'valor_km' e obrigatorio."
    ]
  },
  "message": "Dados invalidos."
}
Ver exemplo — 422, rua ambígua
{
  "data": {
    "motivo": "rua_ambigua",
    "endereco": "destino",
    "sugestoes": [
      { "nome": "Rua Barão de Jaguara", "score": 0.86 },
      { "nome": "Rua Barão de Parnaíba", "score": 0.74 }
    ]
  },
  "message": "Confirme o nome da rua do destino"
}

Reenvie com o nome escolhido e "rua_confirmada": true nesse endereço.

Ver exemplo — 422, endereço não localizado
{
  "data": { "motivo": "nao_localizado", "endereco": "origem" },
  "message": "Nao foi possivel localizar o endereco de origem. Envie lat/lng para prosseguir."
}
GET /api/v1/rua/sugestoes

Autocomplete de nome de rua — consulta só a base local, sem chamar serviço externo na hora.

Parâmetros de consulta

CampoObrigatórioDescrição
ruasimTexto digitado até agora, até 150 caracteres
cidadesimCidade, até 100 caracteres
ufsimSigla de UF válida
limitenãoQuantas sugestões devolver, 1 a 10 (padrão 5)

Exemplo de requisição

GET /api/v1/rua/sugestoes?rua=Barao+de+Jaguara&cidade=Campinas&uf=SP
Authorization: Bearer SUA_CHAVE

Resposta — 200, cidade já com base local

{
  "data": {
    "sugestoes": [
      { "nome": "Rua Barão de Jaguara", "score": 0.96 },
      { "nome": "Rua Barão de Parnaíba", "score": 0.74 }
    ],
    "importando": false
  },
  "message": ""
}

Resposta — 200, cidade ainda sem base local

{
  "data": { "sugestoes": [], "importando": true },
  "message": "Base de ruas desta cidade esta sendo carregada. Tente novamente em instantes para sugestoes completas."
}

Outras respostas possíveis

400 Dados inválidos rua, cidade ou uf ausentes, ou uf não é uma sigla válida.
401 Sem autorização Chave de API ausente ou inválida.
429 Muitas requisições Limite por minuto da sua chave excedido.
GET /api/v1/health sem autenticação

Confere se o banco de dados está respondendo. Pensado pra monitoramento.

Resposta — 200 OK

{
  "data": { "banco": "ok", "horario_servidor": "2026-09-24 18:24:00" },
  "message": ""
}

Outra resposta possível

503 Banco indisponível data.banco: "indisponivel" — a conexão com o banco falhou.