ChartQuery

Enriquecer lead con LinkedIn

Enriquece automáticamente el perfil de empresa de un prospecto con datos de LinkedIn — industria, número de empleados, descripción y publicaciones recientes — usando solo un nombre de dominio.

Descripción general

Este tutorial crea una pipeline de enriquecimiento CRM: a partir del dominio web de una empresa, obtiene su perfil de LinkedIn y extrae datos estructurados como industria, número de empleados, sede y especialidades.

Prerrequisitos

  • Una clave de API de Piloterr — consigue una en app.piloterr.com
  • Instala las dependencias para tu lenguaje:
pip install requests

Sin dependencias adicionales — usa la API nativa fetch (Node 18+).

Extensión curl habilitada (activa por defecto).

Sin dependencias adicionales — usa net/http (Go 1.18+).

Sin dependencias adicionales — usa java.net.http (Java 11+).

Sin dependencias adicionales — usa System.Net.Http (.NET 6+).

# Cargo.toml
[dependencies]
reqwest = { version = "0.12", features = ["json"] }
tokio = { version = "1", features = ["full"] }
serde_json = "1"

Pasos

Busca la empresa por dominio

Pasa el dominio web de la empresa al parámetro domain. También puedes usar una URL de LinkedIn a través de query.

import requests

API_KEY  = "YOUR_API_KEY"
response = requests.get(
    "https://api.piloterr.com/v2/linkedin/company/info",
    headers={"x-api-key": API_KEY},
    params={"domain": "stripe.com"},
)
company = response.json()
print(company)
const API_KEY = "YOUR_API_KEY";

const params   = new URLSearchParams({ domain: "stripe.com" });
const response = await fetch(`https://api.piloterr.com/v2/linkedin/company/info?${params}`, {
  headers: { "x-api-key": API_KEY },
});
const company = await response.json();
console.log(company);
<?php
$apiKey = "YOUR_API_KEY";
$params = http_build_query(["domain" => "stripe.com"]);

$ch = curl_init("https://api.piloterr.com/v2/linkedin/company/info?{$params}");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["x-api-key: {$apiKey}"]);
$company = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($company);
package main

import (
    "encoding/json"
    "fmt"
    "io"
    "net/http"
)

func main() {
    req, _ := http.NewRequest("GET",
        "https://api.piloterr.com/v2/linkedin/company/info?domain=stripe.com", nil)
    req.Header.Set("x-api-key", "YOUR_API_KEY")

    resp, _ := http.DefaultClient.Do(req)
    defer resp.Body.Close()
    body, _ := io.ReadAll(resp.Body)

    var company map[string]any
    json.Unmarshal(body, &company)
    fmt.Println(company)
}
import java.net.URI;
import java.net.http.*;

var client  = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.piloterr.com/v2/linkedin/company/info?domain=stripe.com"))
    .header("x-api-key", "YOUR_API_KEY")
    .GET().build();

var response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
using System.Net.Http;

using var client = new HttpClient();
client.DefaultRequestHeaders.Add("x-api-key", "YOUR_API_KEY");

var body = await client.GetStringAsync(
    "https://api.piloterr.com/v2/linkedin/company/info?domain=stripe.com");
Console.WriteLine(body);
#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
    let company = reqwest::Client::new()
        .get("https://api.piloterr.com/v2/linkedin/company/info")
        .header("x-api-key", "YOUR_API_KEY")
        .query(&[("domain", "stripe.com")])
        .send().await?.json::<serde_json::Value>().await?;

    println!("{:#?}", company);
    Ok(())
}

Extrae los campos clave de la empresa

La respuesta contiene company_name, industry, staff_count, staff_range, tagline, description, headquarter y specialities.

print(f"Empresa      : {company.get('company_name')}")
print(f"Industria    : {company.get('industry')}")
print(f"Empleados    : {company.get('staff_count')} ({company.get('staff_range')})")
print(f"Web          : {company.get('website')}")
hq = company.get("headquarter", {})
print(f"Sede         : {hq.get('city')}, {hq.get('country')}")
print(f"Especialidades: {', '.join(company.get('specialities', [])[:5])}")
console.log(`Empresa      : ${company.company_name}`);
console.log(`Industria    : ${company.industry}`);
console.log(`Empleados    : ${company.staff_count} (${company.staff_range})`);
console.log(`Web          : ${company.website}`);
console.log(`Sede         : ${company.headquarter?.city}, ${company.headquarter?.country}`);
console.log(`Especialidades: ${(company.specialities ?? []).slice(0, 5).join(", ")}`);
echo "Empresa      : {$company['company_name']}\n";
echo "Industria    : {$company['industry']}\n";
echo "Empleados    : {$company['staff_count']} ({$company['staff_range']})\n";
echo "Sede         : {$company['headquarter']['city']}, {$company['headquarter']['country']}\n";
echo "Especialidades: " . implode(", ", array_slice($company["specialities"] ?? [], 0, 5)) . "\n";
c := company
fmt.Printf("Empresa      : %v\nIndustria    : %v\nEmpleados    : %v (%v)\nWeb          : %v\n",
    c["company_name"], c["industry"], c["staff_count"], c["staff_range"], c["website"])
if hq, ok := c["headquarter"].(map[string]any); ok {
    fmt.Printf("Sede         : %v, %v\n", hq["city"], hq["country"])
}
import org.json.*;

var c = new JSONObject(response.body());
System.out.printf("Empresa      : %s%nIndustria    : %s%nEmpleados    : %d (%s)%nWeb          : %s%n",
    c.getString("company_name"), c.getString("industry"),
    c.getInt("staff_count"), c.getString("staff_range"), c.getString("website"));
var hq = c.optJSONObject("headquarter");
if (hq != null) System.out.printf("Sede         : %s, %s%n", hq.getString("city"), hq.getString("country"));
using System.Text.Json;

var c = JsonDocument.Parse(body).RootElement;
Console.WriteLine($"Empresa      : {c.GetProperty("company_name")}");
Console.WriteLine($"Industria    : {c.GetProperty("industry")}");
Console.WriteLine($"Empleados    : {c.GetProperty("staff_count")} ({c.GetProperty("staff_range")})");
Console.WriteLine($"Web          : {c.GetProperty("website")}");
var hq = c.GetProperty("headquarter");
Console.WriteLine($"Sede         : {hq.GetProperty("city")}, {hq.GetProperty("country")}");
let c = &company;
println!("Empresa      : {}", c["company_name"].as_str().unwrap_or(""));
println!("Industria    : {}", c["industry"].as_str().unwrap_or(""));
println!("Empleados    : {} ({})", c["staff_count"], c["staff_range"].as_str().unwrap_or(""));
println!("Sede         : {}, {}", c["headquarter"]["city"].as_str().unwrap_or(""), c["headquarter"]["country"].as_str().unwrap_or(""));

Enriquecer un lote de leads

Itera sobre una lista de dominios de email y crea perfiles de empresa enriquecidos listos para importar a tu CRM.

import json, time, requests

API_KEY = "YOUR_API_KEY"
leads = [
    {"email": "[email protected]",  "domain": "stripe.com"},
    {"email": "[email protected]",     "domain": "notion.so"},
    {"email": "[email protected]",   "domain": "figma.com"},
]
enriched = []

for lead in leads:
    r = requests.get("https://api.piloterr.com/v2/linkedin/company/info",
        headers={"x-api-key": API_KEY}, params={"domain": lead["domain"]})
    if r.status_code == 200:
        c = r.json()
        enriched.append({"email": lead["email"], "domain": lead["domain"],
            "company": c.get("company_name"), "industry": c.get("industry"),
            "employees": c.get("staff_count"), "hq_country": c.get("headquarter", {}).get("country"),
            "linkedin_url": c.get("company_url")})
    time.sleep(0.5)

with open("enriched_leads.json", "w") as f:
    json.dump(enriched, f, indent=2)
print(f"{len(enriched)} leads enriquecidos → enriched_leads.json")
import { writeFileSync } from "fs";

const API_KEY = "YOUR_API_KEY";
const leads   = [
  { email: "[email protected]", domain: "stripe.com" },
  { email: "[email protected]",    domain: "notion.so" },
  { email: "[email protected]",  domain: "figma.com" },
];
const enriched: any[] = [];

for (const lead of leads) {
  const params = new URLSearchParams({ domain: lead.domain });
  const res    = await fetch(`https://api.piloterr.com/v2/linkedin/company/info?${params}`, {
    headers: { "x-api-key": API_KEY },
  });
  if (res.ok) {
    const c = await res.json();
    enriched.push({ email: lead.email, domain: lead.domain, company: c.company_name,
      industry: c.industry, employees: c.staff_count, hq_country: c.headquarter?.country,
      linkedin_url: c.company_url });
  }
  await new Promise(r => setTimeout(r, 500));
}

writeFileSync("enriched_leads.json", JSON.stringify(enriched, null, 2));
console.log(`${enriched.length} leads enriquecidos → enriched_leads.json`);
<?php
$apiKey = "YOUR_API_KEY";
$leads  = [
    ["email" => "[email protected]", "domain" => "stripe.com"],
    ["email" => "[email protected]",    "domain" => "notion.so"],
    ["email" => "[email protected]",  "domain" => "figma.com"],
];
$enriched = [];

foreach ($leads as $lead) {
    $params = http_build_query(["domain" => $lead["domain"]]);
    $ch = curl_init("https://api.piloterr.com/v2/linkedin/company/info?{$params}");
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, ["x-api-key: {$apiKey}"]);
    $c = json_decode(curl_exec($ch), true);
    if (curl_getinfo($ch, CURLINFO_HTTP_CODE) === 200) {
        $enriched[] = ["email" => $lead["email"], "domain" => $lead["domain"],
            "company" => $c["company_name"] ?? null, "industry" => $c["industry"] ?? null,
            "employees" => $c["staff_count"] ?? null, "hq_country" => $c["headquarter"]["country"] ?? null];
    }
    curl_close($ch);
    usleep(500000);
}

file_put_contents("enriched_leads.json", json_encode($enriched, JSON_PRETTY_PRINT));
echo count($enriched) . " leads enriquecidos → enriched_leads.json\n";
package main

import (
    "encoding/json"
    "fmt"
    "io"
    "net/http"
    "os"
    "time"
)

func enrichDomain(apiKey, domain string) map[string]any {
    req, _ := http.NewRequest("GET",
        "https://api.piloterr.com/v2/linkedin/company/info?domain="+domain, nil)
    req.Header.Set("x-api-key", apiKey)
    resp, _ := http.DefaultClient.Do(req)
    defer resp.Body.Close()
    body, _ := io.ReadAll(resp.Body)
    var c map[string]any
    json.Unmarshal(body, &c)
    return c
}

func main() {
    apiKey := "YOUR_API_KEY"
    leads  := []struct{ Email, Domain string }{
        {"[email protected]", "stripe.com"},
        {"[email protected]",    "notion.so"},
        {"[email protected]",  "figma.com"},
    }

    var enriched []map[string]any
    for _, lead := range leads {
        c := enrichDomain(apiKey, lead.Domain)
        hq, _ := c["headquarter"].(map[string]any)
        enriched = append(enriched, map[string]any{
            "email": lead.Email, "domain": lead.Domain,
            "company": c["company_name"], "industry": c["industry"],
            "employees": c["staff_count"], "hq_country": hq["country"],
        })
        time.Sleep(500 * time.Millisecond)
    }

    b, _ := json.MarshalIndent(enriched, "", "  ")
    os.WriteFile("enriched_leads.json", b, 0644)
    fmt.Printf("%d leads enriquecidos → enriched_leads.json\n", len(enriched))
}
import java.net.URI;
import java.net.http.*;
import java.nio.file.*;
import java.util.*;
import org.json.*;

public class Main {
    public static void main(String[] args) throws Exception {
        var client  = HttpClient.newHttpClient();
        var apiKey  = "YOUR_API_KEY";
        var leads   = List.of(
            Map.of("email", "[email protected]", "domain", "stripe.com"),
            Map.of("email", "[email protected]",    "domain", "notion.so"),
            Map.of("email", "[email protected]",  "domain", "figma.com"));
        var enriched = new JSONArray();

        for (var lead : leads) {
            var url  = "https://api.piloterr.com/v2/linkedin/company/info?domain=" + lead.get("domain");
            var req  = HttpRequest.newBuilder().uri(URI.create(url))
                .header("x-api-key", apiKey).GET().build();
            var resp = client.send(req, HttpResponse.BodyHandlers.ofString());
            if (resp.statusCode() == 200) {
                var c  = new JSONObject(resp.body());
                var hq = c.optJSONObject("headquarter");
                enriched.put(new JSONObject()
                    .put("email",    lead.get("email"))
                    .put("domain",   lead.get("domain"))
                    .put("company",  c.optString("company_name"))
                    .put("industry", c.optString("industry"))
                    .put("employees", c.optInt("staff_count"))
                    .put("hq_country", hq != null ? hq.optString("country") : ""));
            }
            Thread.sleep(500);
        }

        Files.writeString(Path.of("enriched_leads.json"), enriched.toString(2));
        System.out.println(enriched.length() + " leads enriquecidos → enriched_leads.json");
    }
}
using System.Net.Http;
using System.Text.Json;

using var client = new HttpClient();
client.DefaultRequestHeaders.Add("x-api-key", "YOUR_API_KEY");

var leads    = new[] {
    (email: "[email protected]", domain: "stripe.com"),
    (email: "[email protected]",    domain: "notion.so"),
    (email: "[email protected]",  domain: "figma.com"),
};
var enriched = new List<object>();

foreach (var lead in leads)
{
    var resp = await client.GetAsync(
        $"https://api.piloterr.com/v2/linkedin/company/info?domain={lead.domain}");
    if (resp.IsSuccessStatusCode)
    {
        var c    = JsonDocument.Parse(await resp.Content.ReadAsStringAsync()).RootElement;
        var hq   = c.GetProperty("headquarter");
        enriched.Add(new {
            email      = lead.email, domain    = lead.domain,
            company    = c.GetProperty("company_name").GetString(),
            industry   = c.GetProperty("industry").GetString(),
            employees  = c.GetProperty("staff_count").GetInt32(),
            hq_country = hq.GetProperty("country").GetString(),
        });
    }
    await Task.Delay(500);
}

File.WriteAllText("enriched_leads.json",
    JsonSerializer.Serialize(enriched, new JsonSerializerOptions { WriteIndented = true }));
Console.WriteLine($"{enriched.Count} leads enriquecidos → enriched_leads.json");
use reqwest::Client;
use serde_json::{json, Value};
use std::{fs, time::Duration};
use tokio::time::sleep;

#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
    let client  = Client::new();
    let api_key = "YOUR_API_KEY";
    let leads   = vec![("[email protected]", "stripe.com"), ("[email protected]", "notion.so"), ("[email protected]", "figma.com")];
    let mut enriched: Vec<Value> = Vec::new();

    for (email, domain) in &leads {
        let c = client.get("https://api.piloterr.com/v2/linkedin/company/info")
            .header("x-api-key", api_key).query(&[("domain", domain)])
            .send().await?.json::<Value>().await?;
        enriched.push(json!({
            "email": email, "domain": domain,
            "company": c["company_name"], "industry": c["industry"],
            "employees": c["staff_count"], "hq_country": c["headquarter"]["country"],
        }));
        sleep(Duration::from_millis(500)).await;
    }

    fs::write("enriched_leads.json", serde_json::to_string_pretty(&enriched).unwrap()).unwrap();
    println!("{} leads enriquecidos → enriched_leads.json", enriched.len());
    Ok(())
}

También puedes pasar una URL o nombre de usuario de LinkedIn al parámetro query en lugar de un dominio — útil cuando ya tienes la URL de LinkedIn de un scraping o búsqueda manual.

En esta página