Direct Data

Look a Like

Manual de Integração — API Direct Data


Produto: Look a Like — Geração de Listas Similares por Critérios de Negócio

Base URL: /api/LookALike

Autenticação: Header Token (Guid)

Versão: 1.0

Sumário

1. Visão Geral

1.1 Descrição do Produto

O Look a Like é o produto da Direct Data que identifica empresas semelhantes ao perfil desejado. A partir de um conjunto de filtros (CNAE, UF, cidade, porte, situação cadastral, etc.), o cliente obtém uma lista de CNPJs qualificados e enriquecidos.

A API pública v2 substitui integralmente o fluxo anterior (Filter → Preview → Quote → Purchase v1), com três diferenças principais:

1.2 Conceitos-Chave

TermoDescrição
Filtro Conjunto de critérios de busca (CNAE, UF, cidade, porte, etc.). Pelo menos um filtro (whitelist) deve ser fornecido no SearchPreview.
SearchGuid Identificador efêmero de uma busca em aberto, retornado pelo SearchPreview. Válido por 15 minutos e consumido na primeira Purchase. Não é persistido.
ListGuid Identificador persistente da lista, retornado pela primeira Purchase. Reutilizável em novas Purchase para comprar mais empresas da mesma busca, durante 30 dias.
ExportGuid Identificador de um lote de compra específico. Cada Purchase gera um ExportGuid — use-o em GetExport para acompanhar o status e em Download para baixar o arquivo final.
Quantidade cobrada Quantidade de empresas efetivamente incluídas no lote. Se a quantidade solicitada exceder o disponível, a API rejeita com 400 — nenhuma cobrança parcial silenciosa.
Hierarquia: um Filtro gera um SearchGuid. A primeira Purchase materializa esse SearchGuid em um ListGuid. Cada Purchase (primeira ou subsequente) gera um ExportGuid distinto.

1.3 Autenticação

Todos os endpoints exigem o header Token com o Guid de autenticação da sua conta. Sem token válido, a resposta é 401 Unauthorized.

Token: aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee

1.4 Estrutura de Resposta Padrão

Todas as respostas seguem o formato:

{
  "success": true,
  "status": "OK",
  "elapsedTimeMs": 42,
  "dateTimeExecution": "07/07/2026 16:41:01",
  "error": null,
  ... (campos específicos do endpoint)
}

Em caso de erro:

{
  "success": false,
  "status": "Bad Request",
  "elapsedTimeMs": 15,
  "dateTimeExecution": "07/07/2026 16:41:02",
  "error": {
    "fieldName": "Quantity",
    "message": "A quantidade deve ser maior que zero e não pode exceder o total encontrado no preview."
  }
}

1.5 Fluxo de Integração

CLIENTE API LookALike v2
  1. 1
    GET /v2/Quote OPCIONAL

    Consulta o preço unitário antes de iniciar a busca.

    ENVIArequisição de cotação
    RECEBE{ unitPrice }
  2. 2
    POST /v2/SearchPreview

    Envia os filtros e recebe o total encontrado + uma amostra da busca.

    ENVIA{ filtros }
    RECEBE{ total, searchGuid, rows[] }
  3. 3
    POST /v2/Purchase

    Confirma a compra usando o searchGuid e a quantidade desejada.

    ENVIA{ searchGuid, quantity }
    RECEBE{ listGuid, exportGuid, … }
  4. 4
    GET /Export/{exportGuid} POLLING · REPETIR ATÉ CONCLUIR

    Consulta o status do export em intervalos até que fique Concluído.

    ENVIAexportGuid (na URL)
    RECEBE{ exportStatus, … }
  5. 5
    GET /Export/{exportGuid}/Download

    Baixa o arquivo final assim que o export estiver concluído.

    ENVIAexportGuid (na URL)
    RECEBEstream ZIP
  6. 6
    POST /v2/Purchase REUTILIZAÇÃO · OPCIONAL

    Compra mais empresas da mesma lista usando o listGuid, sem refazer a busca — gera um novo export (volta ao passo 4).

    ENVIA{ listGuid, quantity }
    RECEBE{ novo exportGuid, … }
Boas práticas:

2. Endpoints — Busca e Cotação

Os endpoints desta seção não geram cobrança e não persistem nada. Quote devolve o preço unitário; SearchPreview devolve total + amostra da busca com um SearchGuid para reutilização na compra.

2.1 SearchPreview

POST /api/LookALike/v2/SearchPreview

Executa a busca de forma síncrona. Retorna o total de empresas que batem com o filtro (capado internamente), uma amostra de até 5 empresas e um SearchGuid efêmero que pode ser reutilizado no Purchase sem precisar reenviar o filtro.

Body da Requisição

CampoTipoObrigatórioDescrição
numberOfResultslongNãoLimite máximo de resultados a considerar na busca. Mínimo: 1. Máximo: 100.000. Default: 1.000.
filtersobjectSimConjunto de filtros de busca — ver tabela abaixo. Pelo menos uma whitelist deve estar preenchida em algum filtro.
ignoredCnpjListarray<string>NãoLista de CNPJs que devem ser excluídos do resultado. Útil para remover clientes já existentes ou empresas que não devem ser prospectadas. Aceita CNPJ formatado ("12.345.678/0001-99") ou apenas dígitos ("12345678000199"). CNPJs duplicados são ignorados automaticamente. Máximo: 100.000 itens.

Objeto filters

A maioria dos campos aceita o formato FormValue: { "whiteList": ["valor1", "valor2"], "blackList": ["valor3"] }
whiteList inclui apenas empresas que possuem os valores informados; blackList exclui empresas que possuem os valores informados. Ambas as listas podem ser vazias.

CampoTipoObrigatórioDescrição
employeeCountRange { min: int,
max: int }
Não Faixa de número de funcionários. Use exatamente uma das cinco faixas válidas:
  • { "min": 1, "max": 9 } — 1 a 9 funcionários
  • { "min": 10, "max": 49 } — 10 a 49 funcionários
  • { "min": 50, "max": 99 } — 50 a 99 funcionários
  • { "min": 100, "max": 499 } — 100 a 499 funcionários
  • { "min": 500, "max": 0 } — 500 ou mais funcionários (0 = sem limite superior)
postalCodes FormValue Não CEPs no formato XXXXX-XXX (ex: "01310-100").
states FormValue Não Siglas de UF brasileiras, 2 letras (ex: "SP", "RJ").
cities FormValue Não Nomes de cidades (ex: "São Paulo", "Campinas").
neighborhoods FormValue Não Nomes de bairros (ex: "Centro", "Jardim Paulista").
primaryCnae FormValue Não Código CNAE primário da empresa (apenas dígitos, ex: "6201500").
secondaryCnae FormValue Não Código CNAE secundário da empresa (apenas dígitos, ex: "6201500").
unifiedCnae { mode: int,
whiteList: string[],
blackList: string[] }
Não Filtro unificado de CNAE — aplica sobre CNAE primário, secundário ou ambos conforme o mode:
  • 1 — Somente CNAE primário (PrimaryOnly)
  • 2 — Somente CNAE secundário (SecondaryOnly)
  • 3 — Primário ou secundário (PrimaryOrSecondary)
companySize FormValue Não Sigla do porte da empresa. Envie exatamente uma destas strings — qualquer valor fora da lista retorna 400:
  • "MEI" — Microempreendedor Individual
  • "ME" — Micro Empresa
  • "EPP" — Empresa de Pequeno Porte
  • "MEDIA" — Média Empresa
  • "GRANDE" — Grande Empresa
  • "S/INFO" — Sem Informação
specialStatus FormValue Não ID da situação especial da empresa:
  • "2" — Em liquidação extra-judicial
  • "3" — Em liquidação
  • "4" — Espólio ev 407
  • "5" — Falido
  • "6" — Intervenção
  • "7" — Liquidação extra-judicial
  • "8" — Liquidação judicial
  • "9" — Recuperação judicial
registrationStatus FormValue Não ID da situação cadastral da empresa:
  • "1" — Ativa
  • "2" — Baixada
  • "3" — Inapta
  • "4" — Nula
  • "5" — Suspensa
openingDateStart string Não Data de abertura mínima, no formato dd/MM/yyyy (ex: "01/01/2010").
openingDateEnd string Não Data de abertura máxima, no formato dd/MM/yyyy (ex: "31/12/2020"). Deve ser maior ou igual a openingDateStart quando ambos forem informados.

Exemplo de Requisição

POST /api/LookALike/v2/SearchPreview HTTP/1.1
Host: {base-url-directdata}
Token: 00000000-0000-0000-0000-000000000000
Content-Type: application/json

{
  "numberOfResults": 5000,
  "filters": {
    "states": { "whiteList": ["SP"], "blackList": [] },
    "cities": { "whiteList": ["São Paulo"], "blackList": [] },
    "neighborhoods": { "whiteList": ["Centro", "Bela Vista"], "blackList": [] },
    "primaryCnae": { "whiteList": ["6201500", "6202300"], "blackList": [] },
    "companySize": { "whiteList": ["ME", "EPP"], "blackList": [] },
    "registrationStatus": { "whiteList": ["1"], "blackList": [] },
    "employeeCountRange": { "min": 10, "max": 49 },
    "openingDateStart": "01/01/2010",
    "openingDateEnd": "31/12/2020"
  },
  "ignoredCnpjList": [
    "12.345.678/0001-99",
    "98765432000111"
  ]
}

Exemplo alternativo — busca por CNAE unificado

{
  "numberOfResults": 1000,
  "filters": {
    "states": { "whiteList": ["SP", "RJ"], "blackList": [] },
    "unifiedCnae": {
      "mode": 3,
      "whiteList": ["4711302", "4712100"],
      "blackList": []
    },
    "companySize": { "whiteList": ["EPP", "MEDIA", "GRANDE"], "blackList": [] }
  }
}

Response — 200 OK

CampoTipoDescrição
totallongTotal de empresas encontradas (capado em numberOfResults).
searchGuidGuidChave efêmera desta busca. Envie-a no Purchase em vez de reenviar os filtros. Válida por 15 min e consumida na primeira compra.
rowsarrayAmostra de até 5 empresas (razão social mascarada, CNPJ mascarado, UF, porte, situação, data de abertura, CNAE principal e CNAEs secundários).
{
  "total": 42,
  "searchGuid": "653805e2-1e6b-43c6-acb8-ccedbf44a96e",
  "rows": [
    {
      "companyName": "ACM* ****CI* LTDA",
      "cnpj": "12.***.***/**01-**",
      "state": "SP",
      "companySize": "ME",
      "registrationStatus": "Ativa",
      "foundationDate": "12/03/2010",
      "mainCnae": { "code": "47.11-3-02", "description": "Comércio varejista de mercadorias em geral" },
      "secondaryCnaes": []
    }
  ],
  "success": true,
  "elapsedTimeMs": 4523,
  "dateTimeExecution": "07/07/2026 16:41:01",
  "error": null
}
Atenção — múltiplos SearchGuid: cada chamada de SearchPreview gera um SearchGuid novo, mesmo se você mandar exatamente o mesmo filtro. Se chamar 3 vezes, você tem 3 guids válidos ao mesmo tempo (cada um com seu TTL de 15 min). Sempre use o SearchGuid mais recente na hora de comprar — os anteriores continuam válidos até expirarem, mas usar um antigo não traz benefício e ainda ocupa espaço no cache.

2.2 Quote

GET /api/LookALike/v2/Quote

Retorna o preço unitário atual do Look a Like. Valor global — não varia por cliente. Não gera cobrança.

Request

Sem body e sem query params. Só o header Token.

Response — 200 OK

CampoTipoDescrição
unitPricedecimalPreço unitário atual por empresa (em currency).
currencystringMoeda do preço. Fixo BRL.
{
  "unitPrice": 0.36,
  "currency": "BRL",
  "success": true,
  "elapsedTimeMs": 3,
  "dateTimeExecution": "07/07/2026 16:40:00",
  "error": null
}
A resposta é cacheada por 10 min no servidor. Se o preço for alterado, o valor antigo pode aparecer até o cache expirar.

3. Endpoints — Compra

3.1 Purchase

POST /api/LookALike/v2/Purchase

Confirma a compra e cobra sua empresa por cada empresa incluída no lote. Aceita dois modos:

Request

CampoTipoObrigatórioDescrição
searchGuidGuid?Exclusivo com listGuidSearchGuid do SearchPreview. Use na primeira compra.
listGuidGuid?Exclusivo com searchGuidListGuid da primeira compra. Use para comprar mais empresas da mesma lista.
quantityintSimQuantidade de empresas a comprar neste lote. Se maior que o disponível, a API rejeita com 400.
Regra de exclusividade: envie exatamente um entre searchGuid ou listGuid. Enviar ambos, ou nenhum, resulta em 400. Não use string vazia ("") — omita o campo ou envie null.
POST /api/LookALike/v2/Purchase HTTP/1.1
Token: aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee
Content-Type: application/json

{
  "searchGuid": "653805e2-1e6b-43c6-acb8-ccedbf44a96e",
  "quantity": 10
}

Ou, para comprar mais empresas de uma lista existente:

{
  "listGuid": "589d81b6-a5f5-4dc9-b061-4578f59323f4",
  "quantity": 5
}

Response — 200 OK

CampoTipoDescrição
listGuidGuidIdentificador persistente da lista. Guarde para futuras compras da mesma busca (até availableUntil).
exportGuidGuidIdentificador deste lote específico. Use em GetExport/Download.
quantityChargedlongQuantidade efetivamente cobrada (igual ao quantity pedido em caso de sucesso).
amountChargeddecimalValor total cobrado nesta transação.
currencystringMoeda. Fixo BRL.
statusstringStatus descritivo do compilado (ex.: "Pago", "Enriquecendo Arquivo", "Concluído").
availableUntilstringData-limite (30 dias após a criação da lista) até quando o listGuid aceita novas compras.
purchasedAtstringData-hora desta compra.
totalOfListlongTotal original da lista (valor da busca original, imutável).
alreadyPurchasedlongTotal já comprado da lista (inclui esta transação).
availablelongEmpresas ainda disponíveis para compras futuras nesta lista.
{
  "listGuid": "589d81b6-a5f5-4dc9-b061-4578f59323f4",
  "exportGuid": "3da0f3eb-3748-453b-900b-c8f2e50a59e7",
  "quantityCharged": 10,
  "amountCharged": 3.60,
  "currency": "BRL",
  "status": "Enriquecendo Arquivo",
  "availableUntil": "06/08/2026, 16:31",
  "purchasedAt": "07/07/2026, 16:41",
  "totalOfList": 42,
  "alreadyPurchased": 10,
  "available": 32,
  "success": true,
  "elapsedTimeMs": 16595,
  "dateTimeExecution": "07/07/2026 16:41:01",
  "error": null
}
Estado do consumo sempre presente: totalOfList, alreadyPurchased e available vêm populados tanto no sucesso quanto no erro. Se você receber 400 por quantidade inválida, esses campos mostram exatamente quantas empresas restam para compra, sem precisar chamar outro endpoint.

Response — 400 Bad Request (quantidade excede disponível)

{
  "listGuid": "00000000-0000-0000-0000-000000000000",
  "exportGuid": null,
  "quantityCharged": 0,
  "amountCharged": 0,
  "currency": "BRL",
  "status": "Bad Request",
  "availableUntil": "",
  "purchasedAt": null,
  "totalOfList": 42,
  "alreadyPurchased": 32,
  "available": 10,
  "success": false,
  "elapsedTimeMs": 45,
  "dateTimeExecution": "07/07/2026 17:15:22",
  "error": {
    "fieldName": "Quantity",
    "message": "A quantidade deve ser maior que zero e não pode exceder o total encontrado no preview."
  }
}

4. Endpoints — Acompanhamento e Download

4.1 GetExport

GET /api/LookALike/Export/{exportGuid}

Retorna o status atual de um lote de compra. Após o Purchase, o compilado passa pelos estágios Pago → Enriquecendo Arquivo → Concluído. Baixe o arquivo em Download apenas quando isDownloadReady for true.

Path

CampoTipoDescrição
exportGuidGuidRetornado no Purchase.

Response — 200 OK

CampoTipoDescrição
exportGuidGuidEco do path.
exportStatusstringStatus descritivo em pt-BR (ex.: "Pago", "Enriquecendo Arquivo", "Concluído").
listNamestringNome da lista pai (auto-gerado como API_Preview_{listGuid}).
quantitylongQuantidade cobrada neste lote.
amountChargeddecimalValor cobrado neste lote.
currencystringMoeda. Fixo BRL.
purchasedAtstringData-hora da compra.
completedAtstring?Data-hora de conclusão (preenchido só quando Concluído).
refundReasonstring?Motivo do estorno, se houver.
isDownloadReadybooltrue quando o arquivo está pronto para download.
{
  "exportGuid": "3da0f3eb-3748-453b-900b-c8f2e50a59e7",
  "exportStatus": "Concluído",
  "listName": "API_Preview_589d81b6-a5f5-4dc9-b061-4578f59323f4",
  "quantity": 10,
  "amountCharged": 3.60,
  "currency": "BRL",
  "purchasedAt": "07/07/2026 16:41:01",
  "completedAt": "07/07/2026 16:44:38",
  "refundReason": null,
  "isDownloadReady": true,
  "success": true,
  "elapsedTimeMs": 12,
  "dateTimeExecution": "07/07/2026 17:00:00",
  "error": null
}
Frequência de polling recomendada: a cada 10–30 segundos. O enriquecimento tipicamente leva entre 1 e 5 minutos, dependendo do tamanho do lote.

4.2 Download

GET /api/LookALike/Export/{exportGuid}/Download

Baixa o arquivo ZIP enriquecido do lote. Disponível apenas quando exportStatus == "Concluído".

Path

CampoTipoDescrição
exportGuidGuidRetornado no Purchase.

Response

Em caso de sucesso, retorna 200 OK com o corpo em application/zip (stream binário — não é JSON). Nome do arquivo: LookALike-{ListName}.zip.

Códigos de erro específicos

HTTPSituação
404Export não encontrado ou não pertence à empresa autenticada.
409Export ainda não está com status Concluído.
502Falha ao recuperar o arquivo do serviço de enriquecimento (indisponibilidade temporária).

5. Códigos de Erro

5.1 Estrutura do Erro

Em qualquer resposta com success: false, o corpo inclui o campo error:

"error": {
  "fieldName": "Quantity",
  "message": "A quantidade deve ser maior que zero e não pode exceder o total encontrado no preview."
}

5.2 Códigos HTTP e Mensagens

HTTPSituaçãoEndpoints
400Body inválido, filtros vazios ou quantity <= 0 / quantity > disponível.SearchPreview, Purchase
400Enviou searchGuid + listGuid juntos, ou nenhum dos dois.Purchase
401Token ausente/inválido.Todos
402Saldo insuficiente ou falha no pagamento.Purchase
403Cliente bloqueado ou produto não contratado.Purchase
404SearchGuid ou ListGuid não encontrado (ou pertence a outro cliente).Purchase
404Export não encontrado ou não é do cliente.GetExport, Download
409Busca expirada (SearchGuid ficou no cache mais de 15 min).Purchase
409Busca retornou total = 0 — nenhuma empresa bate com o filtro.Purchase
409Lista é de uma versão anterior (v1) e não aceita novas compras.Purchase
409Lista expirou (30 dias após a criação).Purchase
409Lista ainda está sendo materializada — aguarde alguns segundos e tente novamente.Purchase
409Lista totalmente consumida — todas as empresas já foram compradas.Purchase
409Export ainda não está com status Concluído.Download
429Limite de requisições simultâneas atingido.SearchPreview, Purchase
500Erro interno inesperado.Todos
502Falha ao contatar o serviço de enriquecimento.Download

6. Limites e Boas Práticas

6.1 Rate Limit

Os endpoints SearchPreview e Purchase têm limite de requisições simultâneas por Token (não por janela de tempo, pois cada requisição pode levar até 5 min no pior caso).

EndpointSimultâneasFila
POST /v2/SearchPreview22
POST /v2/Purchase12

Quando o limite é atingido, a API retorna 429 Too Many Requests. Espere alguma requisição pendente concluir antes de tentar de novo.

6.2 SearchGuid e Cache

6.3 ListGuid e Expiração de Lista