Leads API
Endpoints para listar, detalhar, consultar timeline e exportar seus leads. Todos os endpoints requerem autenticação via API Key com permissão leads:read.
Autenticação
Inclua sua API Key no header de todas as requisições:
Authorization: Bearer dskey_SUA_CHAVE_AQUIListar Leads
/api/leads/query/Lista leads do projeto com paginação e filtros avançados. Retorna dados resumidos de cada lead.
| Parâmetro | Tipo | Descrição |
|---|---|---|
project_idobrigatório | string (UUID) | ID do projeto |
limit | integer | Itens por página (1-1000, padrão: 50) |
offset | integer | Deslocamento para paginação (padrão: 0) |
order_by | string[] | Campos de ordenação. Prefixe com - para DESC. Padrão: ["-created_at"] |
filters | object | Filtros avançados com lógica AND/OR (ver seção Filtros) |
curl -X POST https://apiserver.crazyleads.com.br/api/leads/query/ \
-H "Authorization: Bearer dskey_SUA_CHAVE_AQUI" \
-H "Content-Type: application/json" \
-d '{
"project_id": "SEU_PROJECT_ID",
"limit": 20,
"order_by": ["-created_at"],
"filters": {
"operator": "AND",
"conditions": [
{ "field": "status", "operator": "equals", "value": "active" },
{ "field": "has_email", "operator": "equals", "value": true }
]
}
}'{
"total": 1523,
"items": [
{
"id": "a1b2c3d4-5678-90ab-cdef-111111111111",
"status": "active",
"display_name": "João Silva",
"primary_email": "joao@email.com",
"primary_phone": "+5511999998888",
"emails_count": 2,
"phones_count": 1,
"created_at": "2025-06-15T10:30:00Z",
"updated_at": "2025-07-20T14:00:00Z"
}
],
"page_info": {
"limit": 20,
"offset": 0,
"has_next": true,
"has_previous": false
}
}Detalhe do Lead
/api/leads/{lead_id}/Retorna todas as informações de um lead: emails, telefones, devices, endereços, atributos por namespace, informações de merge e estatísticas.
| Parâmetro | Tipo | Descrição |
|---|---|---|
lead_idobrigatório | string (UUID) | ID do lead (path parameter) |
project_idobrigatório | string (UUID) | ID do projeto (query parameter) |
curl "https://apiserver.crazyleads.com.br/api/leads/LEAD_ID/?project_id=SEU_PROJECT_ID" \
-H "Authorization: Bearer dskey_SUA_CHAVE_AQUI"{
"id": "a1b2c3d4-5678-90ab-cdef-111111111111",
"status": "active",
"display_name": "João Silva",
"created_at": "2025-06-15T10:30:00Z",
"updated_at": "2025-07-20T14:00:00Z",
"emails": [
{
"email": "joao@email.com",
"role": "primary",
"is_current": true,
"confidence": 1.0,
"source": "form_submit"
}
],
"phones": [
{
"e164": "+5511999998888",
"country": "BR",
"is_current": true,
"confidence": 1.0
}
],
"devices": [
{
"ussid": "ussid_abc123",
"is_current": true,
"first_seen": "2025-06-15T10:30:00Z"
}
],
"addresses": [
{
"city": "São Paulo",
"region": "SP",
"postal_code": "01310-100",
"country": "BR",
"is_primary": true
}
],
"attributes_by_namespace": {
"hotmart": [
{ "key": "product_name", "value": "Curso XYZ", "source": "hotmart_webhook" }
],
"custom": [
{ "key": "interesse", "value": "marketing", "source": "form" }
]
},
"merge_info": null,
"merged_leads": [],
"stats": {
"total_events": 47,
"total_attributes": 5,
"namespaces_count": 2
}
}Timeline do Lead
/api/leads/{lead_id}/timeline/Retorna o histórico de atividades e eventos de um lead com filtros por tipo de atividade e intervalo de datas.
| Parâmetro | Tipo | Descrição |
|---|---|---|
lead_idobrigatório | string (UUID) | ID do lead (path parameter) |
project_idobrigatório | string (UUID) | ID do projeto (query parameter) |
limit | integer | Itens por página (1-1000, padrão: 100) |
offset | integer | Offset para paginação (padrão: 0) |
activity_types | string | Tipos separados por vírgula. Ex: pageview,purchase,conversion |
start_date | string (ISO 8601) | Filtrar atividades após esta data |
end_date | string (ISO 8601) | Filtrar atividades antes desta data |
curl "https://apiserver.crazyleads.com.br/api/leads/LEAD_ID/timeline/?project_id=SEU_PROJECT_ID&limit=20&activity_types=purchase,conversion" \
-H "Authorization: Bearer dskey_SUA_CHAVE_AQUI"{
"total": 523,
"activities": [
{
"activity_ts": "2025-07-20T14:30:00Z",
"activity_date": "2025-07-20",
"activity_type": "pageview",
"source_system": "pixel",
"session_id": "sess_abc123",
"ussid": "ussid_device456",
"utm": {
"source": "google",
"medium": "cpc",
"campaign": "summer_sale",
"content": null,
"term": null
},
"transaction": null,
"metadata": {},
"extra": {}
},
{
"activity_ts": "2025-07-18T09:15:00Z",
"activity_date": "2025-07-18",
"activity_type": "purchase",
"source_system": "hotmart",
"transaction": {
"currency": "BRL",
"amount": 297.00
},
"metadata": { "product": "Curso Marketing Digital" }
}
],
"page_info": {
"limit": 20,
"offset": 0,
"has_next": true,
"has_previous": false
},
"filters_applied": {
"activity_types": ["purchase", "conversion"],
"start_date": null,
"end_date": null
}
}Exportar Leads (CSV)
/api/leads/export/Exporta leads como arquivo CSV. Aceita os mesmos filtros do endpoint de listagem. A resposta é retornada em streaming.
curl -X POST https://apiserver.crazyleads.com.br/api/leads/export/ \
-H "Authorization: Bearer dskey_SUA_CHAVE_AQUI" \
-H "Content-Type: application/json" \
-d '{"project_id": "SEU_PROJECT_ID"}' \
-o leads_export.csvContent-Type: text/csv e é enviada em streaming. Use a flag -o no cURL para salvar em arquivo.Filtros Avançados
Os endpoints de listagem e exportação aceitam filtros com lógica AND e OR aninhada. Cada condição tem um campo, operador e valor.
{
"filters": {
"operator": "AND",
"conditions": [
{ "field": "status", "operator": "equals", "value": "active" },
{ "field": "email", "operator": "contains", "value": "gmail.com" },
{
"operator": "OR",
"conditions": [
{ "field": "country", "operator": "equals", "value": "BR" },
{ "field": "country", "operator": "equals", "value": "US" }
]
}
]
}
}Identidade
| Campo | Operadores | Descrição |
|---|---|---|
id | equals, in | ID do lead (UUID) |
email | equals, not_equals, contains, starts_with, ends_with, in, not_in, is_set, is_not_set | Email do lead (case-insensitive) |
phone | equals, not_equals, contains, starts_with, ends_with, in, not_in, is_set, is_not_set | Telefone em formato E.164 |
name | equals, not_equals, contains, starts_with, ends_with, in, not_in, is_set, is_not_set | Nome de exibição (case-insensitive) |
Status
| Campo | Operadores | Descrição |
|---|---|---|
status | equals, not_equals, in, not_in | active, merged_into, archived |
Localização
| Campo | Operadores | Descrição |
|---|---|---|
country | equals, not_equals, contains, in | Código do país do telefone (BR, US...) |
city | equals, not_equals, contains, starts_with, ends_with, in, not_in, is_set, is_not_set | Cidade (do endereço) |
region | equals, not_equals, contains, starts_with, ends_with, in, not_in, is_set, is_not_set | Estado / região (do endereço) |
postal_code | equals, not_equals, contains, starts_with, ends_with, in, not_in, is_set, is_not_set | CEP (do endereço) |
address_country | equals, not_equals, contains, starts_with, ends_with, in, not_in, is_set, is_not_set | País do endereço |
Datas
| Campo | Operadores | Descrição |
|---|---|---|
created_at | equals, gt, gte, lt, lte, before, after, between | Data de criação (ISO 8601) |
updated_at | equals, gt, gte, lt, lte, before, after, between | Data de atualização (ISO 8601) |
between requer um array com dois valores: "value": ["2025-01-01", "2025-12-31"]Presença de Dados
| Campo | Operadores | Descrição |
|---|---|---|
has_email | equals | Possui email atual (true / false) |
has_phone | equals | Possui telefone atual (true / false) |
has_device | equals | Possui device rastreado (true / false) |
Segmentação
| Campo | Operadores | Descrição |
|---|---|---|
feature_id | equals | Membro ativo de uma feature (UUID) |
segment_id | equals | Membro ativo de um segmento (UUID) |
Referência de Operadores
| Operador | Descrição | Exemplo de valor |
|---|---|---|
equals | Valor exato (case-insensitive para strings) | "active" |
not_equals | Diferente do valor | "archived" |
contains | Contém o texto (case-insensitive) | "gmail" |
starts_with | Começa com (case-insensitive) | "+55" |
ends_with | Termina com (case-insensitive) | "@empresa.com" |
in | Valor está na lista | ["active", "archived"] |
not_in | Valor não está na lista | ["merged_into"] |
is_set | Campo possui valor (não nulo) | true |
is_not_set | Campo não possui valor (nulo) | true |
gt | Maior que (datas) | "2025-01-01" |
gte | Maior ou igual (datas) | "2025-01-01" |
lt | Menor que (datas) | "2025-12-31" |
lte | Menor ou igual (datas) | "2025-12-31" |
before | Antes de (alias para lt) | "2025-06-01" |
after | Após (alias para gt) | "2025-06-01" |
between | Entre duas datas (inclusivo) | ["2025-01-01", "2025-12-31"] |
Paginação
Todos os endpoints de listagem usam paginação baseada em offset. O campo page_info.has_next indica se existem mais resultados.
Página 1: { "limit": 50, "offset": 0 }
Página 2: { "limit": 50, "offset": 50 }
Página 3: { "limit": 50, "offset": 100 }Exemplos de Código
import requests
API_KEY = "dskey_SUA_CHAVE_AQUI"
BASE_URL = "https://apiserver.crazyleads.com.br"
PROJECT_ID = "SEU_PROJECT_ID"
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
# Listar leads ativos com email
resp = requests.post(f"{BASE_URL}/api/leads/query/", headers=headers, json={
"project_id": PROJECT_ID,
"limit": 50,
"filters": {
"operator": "AND",
"conditions": [
{"field": "status", "operator": "equals", "value": "active"},
{"field": "has_email", "operator": "equals", "value": True}
]
}
})
data = resp.json()
print(f"Total: {data['total']} leads")
for lead in data["items"]:
print(f" {lead['display_name']} — {lead['primary_email']}")
# Buscar detalhe completo
detail = requests.get(
f"{BASE_URL}/api/leads/{lead['id']}/",
headers=headers,
params={"project_id": PROJECT_ID}
).json()
print(f" Emails: {len(detail.get('emails', []))}")
print(f" Events: {detail['stats']['total_events']}")
# Paginar todos os leads
def fetch_all_leads(filters=None):
all_leads = []
offset = 0
while True:
resp = requests.post(f"{BASE_URL}/api/leads/query/", headers=headers, json={
"project_id": PROJECT_ID,
"limit": 200,
"offset": offset,
"filters": filters
})
data = resp.json()
all_leads.extend(data["items"])
if not data["page_info"]["has_next"]:
break
offset += 200
return all_leadsconst API_KEY = "dskey_SUA_CHAVE_AQUI";
const BASE_URL = "https://apiserver.crazyleads.com.br";
const PROJECT_ID = "SEU_PROJECT_ID";
const headers = {
Authorization: `Bearer ${API_KEY}`,
"Content-Type": "application/json",
};
// Listar leads
const resp = await fetch(`${BASE_URL}/api/leads/query/`, {
method: "POST",
headers,
body: JSON.stringify({
project_id: PROJECT_ID,
limit: 50,
filters: {
operator: "AND",
conditions: [
{ field: "status", operator: "equals", value: "active" },
],
},
}),
});
const data = await resp.json();
console.log(`Total: ${data.total} leads`);
// Detalhe de um lead
const leadId = data.items[0].id;
const detail = await fetch(
`${BASE_URL}/api/leads/${leadId}/?project_id=${PROJECT_ID}`,
{ headers }
).then((r) => r.json());
console.log("Lead:", detail.display_name);
console.log("Emails:", detail.emails.length);
console.log("Events:", detail.stats.total_events);Códigos de Erro
| Código | Descrição |
|---|---|
200 | Sucesso |
400 | Requisição inválida: parâmetros faltando ou inválidos |
401 | Não autorizado: API key inválida ou ausente |
403 | Proibido: sem permissão leads:read ou projeto incorreto |
404 | Lead não encontrado |
429 | Rate limit excedido |
500 | Erro interno do servidor |
{
"error": "Unauthorized",
"message": "Token de API inválido ou expirado",
"code": "INVALID_API_KEY"
}