Para empresas

API do 10leva

Peça entregas e corridas de moto direto do seu site, loja virtual ou sistema. O valor sai do seu saldo pré-pago e o seu sistema recebe cada mudança de status por webhook.

Começando

  1. Crie uma conta de empresa (CNPJ) no 10leva.
  2. Recarregue o saldo na aba Saldo (Pix ou cartão).
  3. Na aba API, crie uma chave. Ela começa com lv_ e aparece uma vez só.
  4. Envie a chave em todas as chamadas: Authorization: Bearer lv_...

Chame a API do seu servidor. A chave dá acesso ao seu saldo: nunca coloque no navegador, no código do site ou no app instalado no celular do cliente.

Endereço base: https://10oferta.com/api/leva/v1 (ou o domínio onde o seu 10leva estiver).

Rotas

GET/saldoSaldo pré-pago da empresa, em centavos.
GET/tarifasTarifas em vigor (base, por km, mínimo, limite de distância).
POST/cotacoesCalcula o valor. A cotação vale 30 minutos.
POST/entregasCria a entrega (com cotacao_id ou com os endereços) e desconta do saldo.
GET/entregasLista as últimas entregas (?limite=1..100, ?referencia_externa=...).
GET/entregas/{id}Status, motoboy, código de entrega e link de acompanhamento.
POST/entregas/{id}/cancelarCancela antes da coleta. O valor volta para o saldo.

Pedir uma entrega

tipo é "entrega" ou "passageiro". Na coleta, nome e telefone são obrigatórios; na entrega, também (exceto em corrida com passageiro). Use referencia_externa com o número do pedido no seu sistema: repetir a chamada com a mesma referência devolve a mesma entrega, sem cobrar de novo.

curl -X POST https://10oferta.com/api/leva/v1/entregas \
  -H "Authorization: Bearer lv_SUA_CHAVE" \
  -H "Content-Type: application/json" \
  -d '{
    "tipo": "entrega",
    "veiculo": "moto",
    "coleta": {
      "cep": "80010-000", "rua": "Rua XV de Novembro", "numero": "100",
      "bairro": "Centro", "cidade": "Curitiba", "uf": "PR",
      "nome": "Loja Exemplo", "telefone": "41999990000",
      "instrucoes": "Retirar no balcão"
    },
    "entrega": {
      "cep": "80250-000", "rua": "Av. Sete de Setembro", "numero": "2500",
      "complemento": "Apto 31", "bairro": "Rebouças", "cidade": "Curitiba", "uf": "PR",
      "nome": "Maria Souza", "telefone": "41988887777"
    },
    "descricao": "Caixa pequena, 2 kg",
    "observacoes": "Frágil",
    "referencia_externa": "pedido-1234"
  }'

Resposta (201):

{
  "id": "6b0c2a8e-...",
  "tipo": "entrega",
  "status": "procurando_motoboy",
  "valor_centavos": 1490,
  "distancia_km": 3.9,
  "codigo_entrega": "LV-7K2QX",
  "referencia_externa": "pedido-1234",
  "acompanhar_url": "https://10oferta.com/10leva/acompanhar/Xy...",
  "coleta": { "endereco": "...", "nome": "Loja Exemplo", "telefone": "..." },
  "entrega": { "endereco": "...", "nome": "Maria Souza", "telefone": "..." },
  "motoboy": null,
  "criada_em": "2026-10-27T14:03:11Z", ...
}

Mande ao seu cliente o acompanhar_url e o codigo_entrega: o motoboy só conclui a entrega com esse código (ou com uma foto de comprovação).

Veículos

Envie veiculo com um destes valores (padrão moto). Para caminhão, informe também carroceria (opcional; sem ela, qualquer carroceria serve) e peso_kg. Corrida com passageiro (tipo: "passageiro") só de moto ou carro. As tarifas de cada um estão em GET /tarifas.

veiculo

moto · carro · utilitario · vuc · toco · truck · carreta · bitrem · rodotrem

carroceria (caminhões)

bau · sider · refrigerado · graneleiro · cacamba · tanque · prancha · cegonha · gaiola · container

{ "tipo": "entrega", "veiculo": "carreta", "carroceria": "refrigerado", "peso_kg": 18000,
  "coleta": {...}, "entrega": {...}, "descricao": "24 paletes de laticínios" }

Cotar antes de pedir

Mostre o frete no seu checkout com uma cotação e depois peça com o cotacao_id: o valor cobrado é exatamente o da cotação.

POST https://10oferta.com/api/leva/v1/cotacoes     { "tipo": "entrega", "coleta": {...}, "entrega": {...} }
→ 201 { "id": "c1d2...", "valor_centavos": 1490, "distancia_km": 3.9, "expira_em": "..." }

POST https://10oferta.com/api/leva/v1/entregas     { "cotacao_id": "c1d2...", "descricao": "...", "referencia_externa": "pedido-1234" }

Status

  • procurando_motoboyPaga e na fila dos motoboys perto da coleta.
  • motoboy_a_caminhoUm motoboy aceitou e está indo até a coleta.
  • em_rotaO motoboy pegou o item (ou o passageiro).
  • entregueConcluída com o código de entrega (ou foto).
  • canceladaCancelada. Se estava paga, o valor voltou para o saldo.

Webhook

Cadastre um endereço https:// na aba API. A cada mudança enviamos um POST com o evento e a entrega no mesmo formato da API. Eventos: entrega.procurando_motoboy, entrega.motoboy_a_caminho, entrega.em_rota, entrega.entregue, entrega.cancelada.

Confira a assinatura no cabeçalho X-10leva-Assinatura: t=TIMESTAMP,v1=HMAC, em que HMAC é o SHA-256 de `${t}.${corpo}` com o seu segredo whlv_.... Recuse avisos com mais de 5 minutos.

// Node.js
import crypto from "node:crypto";

function assinaturaValida(corpo, cabecalho, segredo) {
  const partes = Object.fromEntries(cabecalho.split(",").map((p) => p.split("=")));
  if (Math.abs(Date.now() / 1000 - Number(partes.t)) > 300) return false;
  const esperado = crypto.createHmac("sha256", segredo).update(`${partes.t}.${corpo}`).digest("hex");
  const recebido = Buffer.from(partes.v1 ?? "");
  return recebido.length === esperado.length && crypto.timingSafeEqual(Buffer.from(esperado), recebido);
}

Erros e limites

{ "erro": { "codigo": "saldo_insuficiente", "mensagem": "Saldo insuficiente. Recarregue..." } }
  • 400 dados_invalidos (com detalhes por campo), 401 nao_autorizado, 402 saldo_insuficiente, 404 nao_encontrada.
  • 409 cotacao_invalida (vencida ou já usada), 409 nao_cancelavel (o motoboy já coletou).
  • 422 coleta_nao_encontrada / entrega_nao_encontrada (endereço não achado no mapa), 422 distancia_maxima.
  • 429 limite: 120 chamadas por minuto por chave; 30 cotações e 30 pedidos por minuto.