Você pode encontrar números de telefone do LinkedIn em Python enviando URLs públicas de perfis linkedin.com/in/... para a API Waterfall Phone Finder da Datablist. A API consulta, em sequência, os provedores de dados telefônicos elegíveis e retorna os números encontrados no formato internacional, com o código do país.
Este guia usa a biblioteca Requests para criar uma integração completa em Python. Depois, reaproveita os mesmos resultados para preparar uma lista local de chamadas comerciais, mantendo o nome, a URL do LinkedIn e o responsável pela conta de cada prospect.
📌 Resumo para quem está com pressa
Use uma única API para encontrar números de telefone a partir de uma lista de URLs públicas de perfis do LinkedIn. Em seguida, prepare uma lista local de chamadas com o nome e o responsável pela conta de cada prospect. O Waterfall Phone Finder testa os provedores elegíveis em sequência e deixa os números encontrados prontos para a revisão da sua equipe.
- Entrada: Registros de prospects com uma URL pública de perfil do LinkedIn.
- Saída: Uma lista local de chamadas com números internacionais encontrados, códigos de país, nomes e responsáveis pelas contas.
💡 Prefere uma solução no-code? Use o Waterfall Phone Finder da Datablist para encontrar números de telefone a partir de URLs de perfis do LinkedIn sem escrever código.
Se você tiver apenas os nomes, siga primeiro o fluxo no-code para encontrar telefones pelo nome ou encontre perfis do LinkedIn pelo nome em Python.
Configure Python, Requests e sua chave da API Datablist
Neste exemplo em Python, uso o pacote requests. Crie uma pasta para o projeto, ative um ambiente virtual, instale o Requests e crie o arquivo do script:
mkdir waterfall-phone-lookup
cd waterfall-phone-lookup
python -m venv .venv
source .venv/bin/activate
python -m pip install requests
touch find_phone_numbers.py
export DATABLIST_API_KEY="your-api-key"Crie uma Personal API Key na sua conta Datablist e use-a em DATABLIST_API_KEY. O acesso à REST API está disponível no plano Growth. Mais adiante, explico os créditos consumidos pelas consultas bem-sucedidas.
Encontre telefones com uma única função Python
O exemplo usa três registros editáveis de prospects. Cada registro contém um prospect_id estável, um nome, uma URL pública do LinkedIn e o responsável pela conta que deverá revisar o resultado:
- Florian Poullin em
https://www.linkedin.com/in/florianpoullin/ - Satya Nadella em
https://www.linkedin.com/in/satyanadella/ - Reid Hoffman em
https://www.linkedin.com/in/reidhoffman/
Somente o ID estável e a URL do LinkedIn precisam ser enviados à API. O nome e o responsável pela conta permanecem no registro de origem local. Essa separação mantém a requisição enxuta e preserva os dados comerciais de que sua equipe precisará quando o resultado chegar.
Cole este script completo em find_phone_numbers.py:
import json
import os
import time
import uuid
import requests
def find_phone_numbers(prospects, api_key, settings):
"""Submit one phone lookup task, wait, and return every result."""
tasks_url = "https://api.datablist.com/v1/enrichments/tasks"
headers = {"X-API-Key": api_key}
inputs = [
{
"inputId": prospect["prospect_id"],
"data": {"profileUrl": prospect["linkedin_url"]},
}
for prospect in prospects
]
unique_id = str(uuid.uuid4())
print(f"Task uniqueId: {unique_id}", flush=True)
payload = {
"enrichmentId": "waterfall-phone-finder",
"uniqueId": unique_id,
"settings": settings,
"inputs": inputs,
}
response = requests.post(tasks_url, headers=headers, json=payload)
response.raise_for_status()
task = response.json()
task_id = task["@id"]
task_url = f"{tasks_url}/{task_id}"
while task["status"] not in ("completed", "failed", "stopped"):
time.sleep(3)
response = requests.get(task_url, headers=headers)
response.raise_for_status()
task = response.json()
if task["status"] != "completed":
raise RuntimeError(
f"Task {task_id} {task['status']}: {task.get('error')}"
)
results = []
results_url = f"{task_url}/results"
params = {"limit": 100}
while True:
response = requests.get(results_url, headers=headers, params=params)
response.raise_for_status()
page = response.json()
results.extend(page["results"])
next_cursor = page["nextCursor"]
if next_cursor is None:
break
params["cursor"] = next_cursor
return results
if __name__ == "__main__":
api_key = os.environ.get("DATABLIST_API_KEY")
if not api_key:
raise SystemExit("Set DATABLIST_API_KEY before running this script.")
prospects = [
{
"prospect_id": "prospect-florian-poullin",
"name": "Florian Poullin",
"linkedin_url": "https://www.linkedin.com/in/florianpoullin/",
"account_owner": "Habib",
},
{
"prospect_id": "prospect-satya-nadella",
"name": "Satya Nadella",
"linkedin_url": "https://www.linkedin.com/in/satyanadella/",
"account_owner": "Florian",
},
{
"prospect_id": "prospect-reid-hoffman",
"name": "Reid Hoffman",
"linkedin_url": "https://www.linkedin.com/in/reidhoffman/",
"account_owner": "Habib",
},
]
settings = {"cacheAge": "30"}
phone_results = find_phone_numbers(prospects, api_key, settings)
print(json.dumps(phone_results, indent=2, ensure_ascii=False))Execute o arquivo com:
python find_phone_numbers.pyVocê também pode baixar o exemplo síncrono com Requests mantido pela Datablist. O script acima segue a mesma sequência simples: envia uma tarefa, aguarda sua conclusão e recupera todas as páginas de resultados.
Envie a consulta de telefone
A list comprehension transforma cada prospect de origem no formato de entrada da API. Seu prospect_id se torna inputId, enquanto linkedin_url se torna data.profileUrl. Use uma URL pública de perfil pessoal com o caminho linkedin.com/in/.... URLs do Sales Navigator não são compatíveis com este enrichment.
A função gera um uniqueId e o exibe antes do POST. A requisição envia esse valor junto com o ID do enrichment waterfall-phone-finder, a configuração de cache e os inputs. Um envio bem-sucedido retorna HTTP 202 Accepted e o @id da tarefa, enquanto o processamento continua em segundo plano.
A documentação da API Waterfall Phone Finder apresenta as configurações, os campos de entrada, os outputs, os créditos e os limites atuais.
Para um prospect, o corpo da requisição segue este formato:
{
"enrichmentId": "waterfall-phone-finder",
"uniqueId": "generated-uuid",
"settings": {
"cacheAge": "30"
},
"inputs": [
{
"inputId": "prospect-florian-poullin",
"data": {
"profileUrl": "https://www.linkedin.com/in/florianpoullin/"
}
}
]
}A URL pública do perfil é o dado usado na consulta. inputId é a chave de associação que conecta o resultado ao nome e ao responsável pela conta no registro de origem. Escolha um ID estável no seu próprio sistema e único dentro da tarefa.
Aguarde a tarefa em segundo plano
O cliente Requests fica bloqueado localmente enquanto verifica a tarefa a cada três segundos. A tarefa da Datablist continua sendo executada em segundo plano. Quando o status muda para completed, a função passa à recuperação dos resultados. Um status failed ou stopped gera um erro com o ID da tarefa para que você possa analisá-la.
Recupere todas as páginas de resultados
A requisição de resultados solicita até 100 linhas por vez. Ela continua buscando novas páginas até que nextCursor seja null. Cada resultado inclui seu inputId de origem, permitindo associá-lo ao prospect correto sem depender da ordem da resposta.
Como o waterfall gerenciado encontra um telefone
O exemplo define cacheAge como "30". Primeiro, a Datablist procura um resultado elegível com no máximo 30 dias. Se houver um, a API poderá reutilizá-lo. Essa configuração permite usar o cache, mas não garante que haverá um resultado armazenado.
Se o perfil continuar sem resultado, o waterfall gerenciado consulta os provedores de dados telefônicos elegíveis em sequência. Quando um provedor não retorna um número válido, o registro segue para o próximo. Um número válido encerra a sequência para aquele registro.
Por que o waterfall ajuda em diferentes mercados
A Datablist não depende de um único provedor de dados telefônicos. Os provedores usam bases diferentes, e sua cobertura varia entre países e mercados. Quando um deles não tem o telefone, outro pode encontrá-lo. A Datablist gerencia todos esses provedores por meio da mesma integração de API.
Para uma equipe comercial que cria uma lista de chamadas em vários mercados, isso significa que menos prospects ficam de fora quando o primeiro provedor não encontra nada. Seu código Python envia uma única tarefa e lê um formato único de resultado, sem exigir a criação e a manutenção de uma integração separada para cada provedor.
Defina cacheAge como "0" quando seu fluxo precisar especificamente de uma nova consulta. Mantenha "30" neste exemplo para permitir a reutilização de um resultado elegível do cache.
Leia o resultado completo
Veja um resultado para Florian Poullin. Os números de telefone abaixo estão mascarados.
{
"inputId": "prospect-florian-poullin",
"status": "success",
"outputs": {
"finderProvider": "wizleads",
"phoneNumber": "+33 • •• •• •• ••",
"phoneNumberCountry": "FR"
},
"creditsUsed": "500",
"error": null
}phoneNumber contém o número internacional quando disponível. O prefixo +33 e phoneNumberCountry: "FR" identificam um número francês.
finderProvider indica o finder responsável por esse resultado. A linha consumiu 500 créditos, e error: null significa que a API não retornou nenhum erro nessa linha.
Prepare uma lista de chamadas revisada
Quando phone_results estiver disponível, você poderá preparar uma lista local para a equipe comercial revisar. Adicione o bloco abaixo depois da impressão dos resultados no mesmo arquivo. Ele reutiliza os resultados existentes e não faz uma segunda chamada à API:
results_by_id = {
result["inputId"]: result
for result in phone_results
}
call_list = []
for prospect in prospects:
result = results_by_id.get(prospect["prospect_id"])
if not result or result["status"] != "success":
continue
phone_number = result.get("outputs", {}).get("phoneNumber")
if not phone_number:
continue
call_list_record = prospect.copy()
call_list_record["result"] = result
call_list.append(call_list_record)
print(json.dumps(call_list, indent=2, ensure_ascii=False))O índice de resultados usa inputId como chave de associação. Assim, cada resultado permanece vinculado ao registro de origem sem depender da posição na lista. O payload da API contém o ID e a URL de perfil de cada prospect, enquanto a lista original prospects mantém o nome e o responsável pela conta necessários para a lista de chamadas.
Na linha de Florian, prospect-florian-poullin conecta o resultado retornado aos valores originais de name, linkedin_url e account_owner. A equipe encontra o telefone e seu código de país FR em result.outputs. O objeto completo da API, incluindo status, créditos e erro, permanece anexado em result.
O loop da lista de chamadas segue a ordem de prospects. Ele copia cada prospect incluído antes de anexar result, deixando a lista de origem intacta para correções ou para outro canal de follow-up.
Uma linha sem resultado, com erro ou sem telefone permanece na lista prospects original, mas não entra em call_list. O código prepara uma lista local de chamadas comerciais para revisão.
Calcule os custos da API Waterfall Phone Finder
Cada novo número de telefone encontrado fora do cache pelo waterfall gerenciado padrão consome 500 créditos. Um resultado aceito do cache consome 0 crédito, assim como uma busca sem resultado. Consulte creditsUsed em cada linha retornada para saber o consumo real, em vez de multiplicar todos os perfis enviados por 500.
Para fazer uma estimativa, use esta fórmula:
novos números encontrados fora do cache × 500 créditos
Quarenta novos números consomem 20.000 créditos. Cem novos números consomem 50.000 créditos. Com a taxa básica atual de recarga em dólares, US$ 20 compram 20.000 créditos; portanto, 500 créditos equivalem a US$ 0,50. A assinatura Growth, que oferece acesso à REST API, é cobrada separadamente. Consulte os preços da Datablist para ver os planos e pacotes de créditos atuais.
Como exemplo de planejamento, imagine que 100 perfis gerem 20 números novos, 5 números aceitos do cache e 75 buscas sem resultado. A quantidade faturável corresponde aos 20 números novos, portanto a consulta consome 10.000 créditos. A lista de chamadas pode conter todos os 25 números encontrados. Insira 20 na calculadora, não os 100 inputs nem os 25 números encontrados. Este exemplo demonstra o cálculo da cobrança, não uma taxa de sucesso esperada.
Corrija erros comuns e recupere uma tarefa
DATABLIST_API_KEYestá ausente: o script para antes de fazer uma requisição. Exporte a variável e execute o arquivo novamente.- A API rejeita a chave:
raise_for_status()informa o erro HTTP. Copie novamente a Personal API Key e confirme que a requisição a envia no headerX-API-Key. - A URL do perfil não é compatível: substitua uma URL vazia, malformada, de empresa ou do Sales Navigator por um perfil pessoal público com o caminho
linkedin.com/in/.... - Os créditos são insuficientes: verifique o saldo da conta e os créditos disponíveis antes de enviar mais tarefas.
- A tarefa está com status
failedoustopped: analise o erro, os resultados disponíveis e o consumo de créditos antes de decidir o que ainda precisa ser executado. - Uma linha não tem resultado ou apresenta erro: mantenha o prospect de origem para correção ou uso em outro canal de follow-up. A linha, por si só, não revela qual provedor, região geográfica ou condição de visibilidade causou esse resultado.
Se a resposta do POST for perdida, use o uniqueId exibido antes do envio. Liste suas tarefas antes de enviar novamente. Substitua your-api-key nesta requisição e encontre a tarefa cujo uniqueId corresponde ao valor exibido:
curl --get "https://api.datablist.com/v1/enrichments/tasks" \
--header "X-API-Key: your-api-key" \
--data-urlencode "enrichmentId=waterfall-phone-finder" \
--data-urlencode "limit=100"Se a tarefa não estiver na primeira página, siga o nextCursor da resposta da lista de tarefas. Copie o @id da tarefa correspondente, substitua TASK_ID abaixo e verifique o status ou recupere os resultados existentes:
curl "https://api.datablist.com/v1/enrichments/tasks/TASK_ID" \
--header "X-API-Key: your-api-key"
curl --get "https://api.datablist.com/v1/enrichments/tasks/TASK_ID/results" \
--header "X-API-Key: your-api-key" \
--data-urlencode "limit=100"A documentação da API de tarefas explica os status das tarefas, a paginação dos resultados e o comportamento em caso de interrupção.
Próximos passos
Agora você tem uma função reutilizável com Requests para URLs públicas de perfis do LinkedIn e uma associação por ID estável que prepara os números encontrados para a revisão da equipe comercial.
Substitua os exemplos editáveis por um pequeno conjunto de prospects qualificados. Mantenha seus IDs estáveis e os responsáveis pelas contas e, depois, revise cada número encontrado antes de encaminhar a lista preparada ao processo de chamadas da sua equipe. Comece com um lote pequeno para conferir a associação dos IDs e os campos retornados. Se precisar de concorrência sem bloqueio, use o exemplo assíncrono com HTTPX mantido pela Datablist.


