A practical guide: enrich one profile, handle slow profiles, enrich thousands in parallel and deal with rate limits, using the requests library.
Create a free account, open API keys in the dashboard and copy your key. Store it in an environment variable, never in your code:
export ENRICHGRID_KEY=lk_...import os, requests
API = "https://enrichgrid.com/v1"
H = {"x-api-key": os.environ["ENRICHGRID_KEY"]}
r = requests.post(f"{API}/enrich/person", headers=H,
json={"identifier": "https://www.linkedin.com/in/brendaneich"},
timeout=120)
data = r.json()
if data.get("found"):
p = data["profile"]
print(p["first_name"], p["last_name"], "-", p["current_title"], "@", p["current_company_name"])Most profiles return 200 within seconds. Rare ones return 202 with a poll URL; polling is free:
import time
def enrich(identifier):
r = requests.post(f"{API}/enrich/person", headers=H, json={"identifier": identifier}, timeout=120)
data = r.json()
while r.status_code == 202:
time.sleep(3)
r = requests.get("https://enrichgrid.com" + data["poll"], headers=H, timeout=30)
data = r.json()
if data["status"] != "pending":
break
return dataUse a thread pool sized to your plan's rate limit (Free 2, Starter 5, Growth 10, Scale 25, Enterprise 50 requests per second) and retry on 429 using Retry-After:
from concurrent.futures import ThreadPoolExecutor
def safe_enrich(url, tries=5):
for _ in range(tries):
r = requests.post(f"{API}/enrich/person", headers=H, json={"identifier": url}, timeout=120)
if r.status_code in (429, 503):
time.sleep(float(r.headers.get("Retry-After", 2)))
continue
return r.json()
urls = [...] # your LinkedIn URLs
with ThreadPoolExecutor(max_workers=5) as pool:
results = list(pool.map(safe_enrich, urls))Prefer no code? Upload the list as Excel or CSV.
Building your own scraper means proxies, logins and constant breakage. An API returns structured data with one request and no maintenance.
Any Python 3 with the requests library (pip install requests).
50 free credits. No credit card. Pay only for what we find.
Create a free account →