ChartQuery

Enrich a Lead with LinkedIn

Automatically enrich a prospect's company record with LinkedIn data — industry, headcount, description, and recent posts — using only a domain name.

Overview

This playbook builds a CRM enrichment pipeline: given a company's website domain, fetch its LinkedIn profile and extract structured data like industry, employee count, headquarters, and specialities.

Prerequisites

  • A Piloterr API key — get one at app.piloterr.com
  • Install dependencies for your language:
pip install requests

No extra dependencies — uses the native fetch API (Node 18+).

curl extension enabled (on by default in most PHP installs).

No extra dependencies — uses net/http (Go 1.18+).

No extra dependencies — uses java.net.http (Java 11+).

No extra dependencies — uses System.Net.Http (.NET 6+).

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

Steps

Look up a company by domain

Pass the company's website domain to the domain parameter. You can also use a LinkedIn URL via 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(())
}

Extract key company fields

The response contains company_name, industry, staff_count, staff_range, tagline, description, headquarter, and specialities.

print(f"Company   : {company.get('company_name')}")
print(f"Industry  : {company.get('industry')}")
print(f"Employees : {company.get('staff_count')} ({company.get('staff_range')})")
print(f"Website   : {company.get('website')}")
hq = company.get("headquarter", {})
print(f"HQ        : {hq.get('city')}, {hq.get('country')}")
print(f"Topics    : {', '.join(company.get('specialities', [])[:5])}")
console.log(`Company   : ${company.company_name}`);
console.log(`Industry  : ${company.industry}`);
console.log(`Employees : ${company.staff_count} (${company.staff_range})`);
console.log(`Website   : ${company.website}`);
console.log(`HQ        : ${company.headquarter?.city}, ${company.headquarter?.country}`);
console.log(`Topics    : ${(company.specialities ?? []).slice(0, 5).join(", ")}`);
echo "Company   : {$company['company_name']}\n";
echo "Industry  : {$company['industry']}\n";
echo "Employees : {$company['staff_count']} ({$company['staff_range']})\n";
echo "HQ        : {$company['headquarter']['city']}, {$company['headquarter']['country']}\n";
echo "Topics    : " . implode(", ", array_slice($company["specialities"] ?? [], 0, 5)) . "\n";
c := company
fmt.Printf("Company   : %v\nIndustry  : %v\nEmployees : %v (%v)\nWebsite   : %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("HQ        : %v, %v\n", hq["city"], hq["country"])
}
import org.json.*;

var c = new JSONObject(response.body());
System.out.printf("Company   : %s%nIndustry  : %s%nEmployees : %d (%s)%nWebsite   : %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("HQ        : %s, %s%n", hq.getString("city"), hq.getString("country"));
using System.Text.Json;

var c = JsonDocument.Parse(body).RootElement;
Console.WriteLine($"Company   : {c.GetProperty("company_name")}");
Console.WriteLine($"Industry  : {c.GetProperty("industry")}");
Console.WriteLine($"Employees : {c.GetProperty("staff_count")} ({c.GetProperty("staff_range")})");
Console.WriteLine($"Website   : {c.GetProperty("website")}");
var hq = c.GetProperty("headquarter");
Console.WriteLine($"HQ        : {hq.GetProperty("city")}, {hq.GetProperty("country")}");
let c = &company;
println!("Company   : {}", c["company_name"].as_str().unwrap_or(""));
println!("Industry  : {}", c["industry"].as_str().unwrap_or(""));
println!("Employees : {} ({})", c["staff_count"], c["staff_range"].as_str().unwrap_or(""));
println!("HQ        : {}, {}", c["headquarter"]["city"].as_str().unwrap_or(""), c["headquarter"]["country"].as_str().unwrap_or(""));

Enrich a batch of leads

Loop over a list of email domains and build enriched company records ready to push to your 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"Enriched {len(enriched)} leads → 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 ${enriched.length} leads → 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 "Enriched " . count($enriched) . " leads → 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("Enriched %d leads → 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 " + enriched.length() + " leads → 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 {enriched.Count} leads → 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!("Enriched {} leads → enriched_leads.json", enriched.len());
    Ok(())
}

You can also pass a LinkedIn company URL or username to the query parameter instead of a domain — useful when you already have the LinkedIn URL from a scrape or manual research.

On this page