Leaper Desenvolvedores
Central de Ajuda Entrar
API de Integração

API de Integração

A API de Integração conecta o seu sistema à Leaper. Com ela você cria e atualiza leads, registra as mensagens de WhatsApp que acontecem fora da Leaper, move leads entre os status do funil e consulta leads, conversas e a configuração do funil. Para ser avisado quando algo muda na Leaper, sem precisar consultar a API, use os webhooks.

Abrir no ChatGPT ↗ Abrir no Claude ↗ Ver .md

Visão geral

O que você quer fazerEndpoint
Registrar uma mensagem de WhatsAppPOST /v1/message
Criar um leadPOST /v1/leads
Atualizar os dados de um leadPUT /v1/leads/{lead_id}
Mover um lead de statusPUT /v1/leads/{lead_id}/status
Listar e buscar leadsGET /v1/leads
Consultar um leadGET /v1/leads/{lead_id}
Consultar a conversa de um leadGET /v1/leads/{lead_id}/conversation
Consultar os status do funilGET /v1/statuses
Consultar a empresaGET /v1/company

Todas as rotas usam a URL base https://api.external.leaper.com.br. A API recebe e devolve JSON em UTF-8; nas requisições com corpo, envie o cabeçalho Content-Type: application/json.

Autenticação

Toda requisição precisa do cabeçalho X-API-Key com a chave da sua empresa:

Cabeçalho
X-API-Key: sua-chave-de-api

Para obter a chave, fale com o suporte da Leaper. Cada chave dá acesso aos dados de uma empresa.

Atenção A chave dá acesso aos leads e às conversas da empresa. Guarde-a numa variável de ambiente ou num cofre de segredos e use a API só a partir do seu servidor, nunca no navegador ou num aplicativo.
RespostaQuando acontece
401O cabeçalho não foi enviado ou a chave é inválida
403A empresa está desativada

Primeira requisição

Para testar a chave, consulte os dados da empresa. Os exemplos leem a chave da variável de ambiente LEAPER_API_KEY.

cURL
curl "https://api.external.leaper.com.br/v1/company" \
  -H "X-API-Key: $LEAPER_API_KEY"
JavaScript
const response = await fetch("https://api.external.leaper.com.br/v1/company", {
  headers: {
    "X-API-Key": process.env.LEAPER_API_KEY,
  },
});

const data = await response.json();
PHP
$ch = curl_init('https://api.external.leaper.com.br/v1/company');

curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => [
        'X-API-Key: ' . getenv('LEAPER_API_KEY'),
    ],
]);

$data = json_decode(curl_exec($ch), true);
Python
import os

import requests

response = requests.get(
    "https://api.external.leaper.com.br/v1/company",
    headers={"X-API-Key": os.environ["LEAPER_API_KEY"]},
    timeout=30,
)

data = response.json()

Com a chave certa, a resposta é 200:

Resposta 200
{
  "id": "6201138c-fc0a-4478-820f-8907907e7f00",
  "name": "Clínica Exemplo",
  "document": "12345678000190",
  "address": "Rua dos Pinheiros, 1000 - São Paulo/SP",
  "phone_number": "551130000000"
}

Conceitos

O recurso lead

Consultar, criar e atualizar um lead devolvem o mesmo formato, dividido em blocos:

BlocoConteúdo
leadDados do contato, origem, tags, valor e datas
statusStatus atual do lead no funil e o anterior
trackingAtribuição: campanha, UTMs, clique, página e dispositivo
form_submissionsFormulários enviados pelo lead, do mais recente para o mais antigo

São os mesmos blocos enviados pelos webhooks, com os nomes dos campos sempre em snake_case. Na listagem de leads, cada item traz lead e status, e os outros dois só quando você pede com include. O formato completo de cada campo está em Objetos.

Status do funil

Cada empresa configura os status do seu funil no painel. Consulte-os em GET /v1/statuses.

  • Identifique um status pelo id. Ele não muda. O code é gerado a partir do nome, muda quando o status é renomeado e pode se repetir entre status da empresa.
  • END_WON e END_LOST são fixos. Eles marcam o lead convertido e o lead perdido em todas as empresas.
  • Mover um lead de status pela API dispara os eventos de conversão configurados para o status e os webhooks de mudança de status.

Datas e fuso horário

  • As datas das respostas vêm em ISO 8601 com fuso, no horário de Brasília: 2026-09-02T15:41:05-03:00.
  • Os filtros start_date e end_date aceitam YYYY-MM-DD ou YYYY-MM-DD HH:MM:SS, no horário de Brasília. Só a data vale para o dia inteiro.
  • O timestamp das mensagens precisa ter fuso: 2026-09-11T10:30:00-03:00 ou 2026-09-11T13:30:00Z.

Paginação

A listagem de leads é paginada com limit (de 1 a 200, padrão 50) e offset (padrão 0). O total de leads que atendem aos filtros vem em count:

Resposta
{
  "data": [],
  "count": 120,
  "limit": 50,
  "offset": 0
}

Para percorrer todos, some limit ao offset a cada página até chegar a count.

Valores nulos e campos novos

  • Qualquer campo pode vir null quando o dado não existe. Isso é normal, não um erro.
  • Campos novos podem aparecer nas respostas. Ignore os que o seu sistema não conhece em vez de rejeitar a resposta.

Erros

Todo erro vem no mesmo formato, com uma mensagem em inglês que diz o que corrigir:

Resposta
{ "error": "lead_value must be a non-negative number with a dot as decimal separator, e.g. 1500.50" }
CódigoSignificado
400Corpo ou parâmetro inválido
401Cabeçalho X-API-Key ausente ou chave inválida
403Empresa desativada
404O recurso não existe ou é de outra empresa
405Método não aceito nessa rota
422Pedido válido que não pode ser atendido, como um status de outra empresa
429Limite de requisições atingido. Veja Limite de requisições
500Erro interno. Tente de novo em alguns instantes

Limite de requisições

Cada empresa tem um limite de requisições por minuto, contado por chave:

RotasLimite
Leitura e escrita em geral120 por minuto
Relatórios (/v1/reports/...)20 por minuto

Toda resposta traz quantas requisições ainda cabem na janela:

CabeçalhoSignificado
X-RateLimit-LimitRequisições permitidas na janela
X-RateLimit-RemainingRequisições que ainda cabem

Ao estourar o limite, a resposta é 429 com o cabeçalho Retry-After, em segundos:

Resposta
{ "error": "Too many requests" }

Espere o tempo de Retry-After antes de tentar de novo. Para cargas grandes, use limit alto na listagem em vez de muitas chamadas pequenas, e guarde os relatórios por alguns minutos no seu lado em vez de pedir a cada acesso do usuário.

Casos de uso

Registrar mensagens de WhatsApp

Se as conversas acontecem num sistema seu, como um chatbot, uma central de atendimento ou outro provedor de WhatsApp, envie cada mensagem para POST /v1/message. A Leaper encontra o lead pelo telefone ou pelo LID do WhatsApp, cria o lead se ele ainda não existir e registra a mensagem na conversa.

cURL
curl -X POST "https://api.external.leaper.com.br/v1/message" \
  -H "X-API-Key: $LEAPER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "5511987654321",
    "name": "Marina Alves",
    "message": "Olá, quero agendar uma avaliação",
    "message_id": "wamid.HBgNNTUxMTk4NzY1NDMyMRUCABIYFjNFQjA",
    "timestamp": "2026-09-11T10:30:00-03:00",
    "ctwa_clid": "ARAkLgdbrocNABYQnQoGHmFy"
  }'
  • A resposta é 201 quando o lead foi criado e 200 quando ele já existia. Nos dois casos vem o id do lead.
  • Envie o message_id do seu provedor. Com ele, repetir uma chamada que falhou não duplica a mensagem na conversa.
  • Informe o telefone com DDI. Só os dígitos contam: +55 (11) 98765-4321 e 5511987654321 são o mesmo contato.
  • Quando a mensagem de um contato cria o lead, os parâmetros de rastreamento (ctwa_clid, fbclid, gclid, wbraid, gbraid e utm) definem a origem. A regra completa está na referência.

Para registrar uma mensagem enviada pela empresa, envie "from_me": true. Se o contato ainda não for lead, ele só é criado quando a opção Criar lead ao iniciar conversa estiver ligada nas configurações da empresa. Com a opção desligada, a resposta é 200 com { "lead": null } e nada é registrado.

Criar leads do seu site ou CRM

Use POST /v1/leads para cadastrar um lead com origem, dados de contato, valor e tags. O lead entra no primeiro status do funil.

cURL
curl -X POST "https://api.external.leaper.com.br/v1/leads" \
  -H "X-API-Key: $LEAPER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "source": "WEBSITE",
    "client": {
      "name": "Marina Alves",
      "phone": "5511987654321",
      "email": "marina.alves@exemplo.com.br"
    },
    "lead_value": "3200"
  }'
Observação Essa rota sempre cria um lead novo, mesmo que já exista um lead com o mesmo telefone. Para alterar um lead, use PUT /v1/leads/{lead_id}.

O lead_value aceita número ou texto numérico com ponto como separador decimal e sem separador de milhar, como 1500.50. Valores como 1.500,00 são recusados, e 1.500 é lido como 1,5.

Mover um lead no funil

  1. 1Consulte os status do funil em GET /v1/statuses e guarde os id.
  2. 2Envie o id do status de destino para PUT /v1/leads/{lead_id}/status.
cURL
curl -X PUT "https://api.external.leaper.com.br/v1/leads/b7d4e1a2-8f3c-4a19-9c62-1e5f0a7d3b84/status" \
  -H "X-API-Key: $LEAPER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "status_id": "5f3c9a1e-2b7d-4c8a-9e61-0d4b8a7c3f21" }'

A resposta traz o status atual, o anterior e o histórico. Enviar o status em que o lead já está não conta como mudança: nada entra no histórico e nenhum evento é disparado.

Buscar leads

GET /v1/leads combina busca por texto, status, origem, tag e período. Para trazer os leads que entraram em um status desde uma data:

cURL
curl -G "https://api.external.leaper.com.br/v1/leads" \
  -H "X-API-Key: $LEAPER_API_KEY" \
  --data-urlencode "status_id=5f3c9a1e-2b7d-4c8a-9e61-0d4b8a7c3f21" \
  --data-urlencode "date_field=status_changed_at" \
  --data-urlencode "start_date=2026-09-01" \
  --data-urlencode "limit=100"

A listagem traz lead e status de cada item. Se você também precisa da atribuição e dos formulários, peça com include:

cURL
curl -G "https://api.external.leaper.com.br/v1/leads" \
  -H "X-API-Key: $LEAPER_API_KEY" \
  --data-urlencode "include=tracking,form_submissions" \
  --data-urlencode "limit=50"

Os blocos são os mesmos de Consultar lead. Com include, o limit vale no máximo 50 — acima disso a resposta é 400, em vez de devolver menos itens em silêncio e fazer você pular leads ao paginar. Sem include, o teto segue sendo 200.

Para acompanhar novos leads e mudanças de status assim que acontecem, prefira os webhooks a consultar a listagem de tempos em tempos.

Montar um painel com os números do funil

Em vez de baixar todos os leads para somar no seu sistema, peça os números já somados. GET /v1/reports/summary traz os totais do período:

cURL
curl -G "https://api.external.leaper.com.br/v1/reports/summary" \
  -H "X-API-Key: $LEAPER_API_KEY" \
  --data-urlencode "start_date=2026-09-01" \
  --data-urlencode "end_date=2026-09-30"
Resposta 200
{
  "period": {
    "start_date": "2026-09-01 00:00:00",
    "end_date": "2026-09-30 23:59:59",
    "date_field": "created_at"
  },
  "leads": 184,
  "converted": 37,
  "lost": 52,
  "converted_value": 148200.5,
  "open_value": 96400
}

converted são os leads no status END_WON e lost, os que estão em END_LOST. Os valores somam o lead_value de cada lead, então só aparecem se o valor estiver preenchido.

Para abrir esses números, use GET /v1/reports/leads-by-status, que mostra quantos leads estão em cada etapa do funil, e GET /v1/reports/leads-by-source, que mostra de onde vieram e quanto cada origem converteu.

Os três aceitam o mesmo período: start_date, end_date e date_field. Sem período, valem os últimos 30 dias; a janela pode ter no máximo 92 dias. Com date_field=status_changed_at, o período passa a considerar a última mudança de status, útil para "o que foi fechado neste mês".

Boas práticas

  • Chame a API do seu servidor. A chave não pode ficar exposta no navegador ou em aplicativos.
  • Guarde os ids. Use o id do lead e o id do status como referência no seu sistema; nomes e códigos podem mudar.
  • Repita só o que falhou por instabilidade. Em erro 500 ou falha de conexão, tente de novo aguardando alguns segundos entre as tentativas. Em erros 4xx, corrija o pedido antes de reenviar.
  • Envie message_id nas mensagens, para que repetir uma chamada não duplique a conversa.
  • Prefira os relatórios a somar no seu lado. Para painéis, as rotas /v1/reports/... já devolvem os números do período.
  • Respeite o Retry-After. Em erro 429, espere o tempo indicado; acompanhe X-RateLimit-Remaining para não chegar no limite.
  • Aceite campos novos e valores nulos nas respostas.