API Reference/Leads

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:

Header
Authorization: Bearer dskey_SUA_CHAVE_AQUI
Nunca exponha sua API Key em código client-side, repositórios públicos ou logs. Ela dá acesso completo de leitura aos leads do seu projeto.

Listar Leads

POST/api/leads/query/

Lista leads do projeto com paginação e filtros avançados. Retorna dados resumidos de cada lead.

ParâmetroTipoDescrição
project_idobrigatóriostring (UUID)ID do projeto
limitintegerItens por página (1-1000, padrão: 50)
offsetintegerDeslocamento para paginação (padrão: 0)
order_bystring[]Campos de ordenação. Prefixe com - para DESC. Padrão: ["-created_at"]
filtersobjectFiltros avançados com lógica AND/OR (ver seção Filtros)
Requisição
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 }
      ]
    }
  }'
Resposta
{
  "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

GET/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âmetroTipoDescrição
lead_idobrigatóriostring (UUID)ID do lead (path parameter)
project_idobrigatóriostring (UUID)ID do projeto (query parameter)
Requisição
curl "https://apiserver.crazyleads.com.br/api/leads/LEAD_ID/?project_id=SEU_PROJECT_ID" \
  -H "Authorization: Bearer dskey_SUA_CHAVE_AQUI"
Resposta
{
  "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

GET/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âmetroTipoDescrição
lead_idobrigatóriostring (UUID)ID do lead (path parameter)
project_idobrigatóriostring (UUID)ID do projeto (query parameter)
limitintegerItens por página (1-1000, padrão: 100)
offsetintegerOffset para paginação (padrão: 0)
activity_typesstringTipos separados por vírgula. Ex: pageview,purchase,conversion
start_datestring (ISO 8601)Filtrar atividades após esta data
end_datestring (ISO 8601)Filtrar atividades antes desta data
Requisição
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"
Resposta
{
  "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)

POST/api/leads/export/

Exporta leads como arquivo CSV. Aceita os mesmos filtros do endpoint de listagem. A resposta é retornada em streaming.

Requisição
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.csv
A resposta tem Content-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.

Estrutura
{
  "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

CampoOperadoresDescrição
idequals, inID do lead (UUID)
emailequals, not_equals, contains, starts_with, ends_with, in, not_in, is_set, is_not_setEmail do lead (case-insensitive)
phoneequals, not_equals, contains, starts_with, ends_with, in, not_in, is_set, is_not_setTelefone em formato E.164
nameequals, not_equals, contains, starts_with, ends_with, in, not_in, is_set, is_not_setNome de exibição (case-insensitive)

Status

CampoOperadoresDescrição
statusequals, not_equals, in, not_inactive, merged_into, archived

Localização

CampoOperadoresDescrição
countryequals, not_equals, contains, inCódigo do país do telefone (BR, US...)
cityequals, not_equals, contains, starts_with, ends_with, in, not_in, is_set, is_not_setCidade (do endereço)
regionequals, not_equals, contains, starts_with, ends_with, in, not_in, is_set, is_not_setEstado / região (do endereço)
postal_codeequals, not_equals, contains, starts_with, ends_with, in, not_in, is_set, is_not_setCEP (do endereço)
address_countryequals, not_equals, contains, starts_with, ends_with, in, not_in, is_set, is_not_setPaís do endereço

Datas

CampoOperadoresDescrição
created_atequals, gt, gte, lt, lte, before, after, betweenData de criação (ISO 8601)
updated_atequals, gt, gte, lt, lte, before, after, betweenData de atualização (ISO 8601)
O operador between requer um array com dois valores: "value": ["2025-01-01", "2025-12-31"]

Presença de Dados

CampoOperadoresDescrição
has_emailequalsPossui email atual (true / false)
has_phoneequalsPossui telefone atual (true / false)
has_deviceequalsPossui device rastreado (true / false)

Segmentação

CampoOperadoresDescrição
feature_idequalsMembro ativo de uma feature (UUID)
segment_idequalsMembro ativo de um segmento (UUID)

Referência de Operadores

OperadorDescriçãoExemplo de valor
equalsValor exato (case-insensitive para strings)"active"
not_equalsDiferente do valor"archived"
containsContém o texto (case-insensitive)"gmail"
starts_withComeça com (case-insensitive)"+55"
ends_withTermina com (case-insensitive)"@empresa.com"
inValor está na lista["active", "archived"]
not_inValor não está na lista["merged_into"]
is_setCampo possui valor (não nulo)true
is_not_setCampo não possui valor (nulo)true
gtMaior que (datas)"2025-01-01"
gteMaior ou igual (datas)"2025-01-01"
ltMenor que (datas)"2025-12-31"
lteMenor ou igual (datas)"2025-12-31"
beforeAntes de (alias para lt)"2025-06-01"
afterApós (alias para gt)"2025-06-01"
betweenEntre 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

Python
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_leads
JavaScript / Node.js
const 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ódigoDescrição
200Sucesso
400Requisição inválida: parâmetros faltando ou inválidos
401Não autorizado: API key inválida ou ausente
403Proibido: sem permissão leads:read ou projeto incorreto
404Lead não encontrado
429Rate limit excedido
500Erro interno do servidor
Formato do Erro
{
  "error": "Unauthorized",
  "message": "Token de API inválido ou expirado",
  "code": "INVALID_API_KEY"
}