People Enrichment & Search (People Data Labs)
One script,
, with five subcommands over PDL's Person and Company datasets. All share the same API-key handling, the boolean-PII contact logic, status flags,
styling, and a
preflight mode.
| Subcommand | Input | Output | Billing |
|---|
| list of named people | profile + work history | 1 credit / match |
| list of people (ambiguous) | several scored candidates each | per PDL identify terms |
| criteria flags | a list of matching people | 1 credit / record returned |
| list of companies | firmographics | 1 credit / match |
| criteria flags | a list of matching companies | 1 credit / record returned |
The two
search commands return data per
result, so cost scales with
. Always state the rough cost before a large search and keep
modest unless the user asks for more (max 100 per request).
Scope and routing
Use this skill when the user wants PDL person/company enrichment or search for a legitimate, proportionate purpose. Do not use it to scrape LinkedIn directly, to compile an intrusive profile, or where a host environment mandates a different data provider.
Why People Data Labs, not a LinkedIn scraper
Scraping LinkedIn is fragile and legally risky. This skill uses PDL as a licensed aggregator rather than live LinkedIn scraping. If the user insists on live scraping, explain the trade-off rather than building a scraper.
The API key
needs a PDL key, resolved at runtime in this order:
env var →
in the cwd →
next to the script.
The key must never be written into this skill or any script. If absent, live commands exit with instructions.
and
do not require a key.
bash
echo 'PDL_API_KEY=their_key_here' > .env
Treat
as a secret: don't print, commit, or upload it.
runs offline (canned data, no key) and writes sample people + company sheets so the user can see the output format before spending credits.
Dry-run preflight
Before spending credits, especially on larger files or searches, run the same command with
:
bash
python scripts/enrich.py person-enrich --input people.csv --output out.xlsx --dry-run
python scripts/enrich.py person-search --company "Northwind Capital" --title director --size 25 --dry-run
python scripts/enrich.py company-search --industry "real estate" --country singapore --size 50 --dry-run
Dry-run validates the input/search, prints the planned output, and estimates maximum credits without requiring
, calling PDL, or writing
output.
Contact fields and the free plan
On the free plan, PDL returns PII fields (
,
) as a boolean, not the value:
= a contact exists but is paywalled,
= none on file. The people sheets surface this in
Email status /
Phone status columns:
(real value present, Pro plans),
(paywalled but present),
, or
.
The five commands
person-enrich — one-to-one match named people.
bash
python scripts/enrich.py person-enrich --input people.csv --output out.xlsx
Recognised input columns (case/space-insensitive): name/full name, first name, last name, company/employer, title, location, email, linkedin/profile. More context per row = higher match rate.
person-identify — when a single enrich is ambiguous, get the candidate set.
bash
python scripts/enrich.py person-identify --input people.csv --max-candidates 5
Same input as enrich. Output has multiple rows per input person, each a scored candidate (Match score column), so the user can pick the right one.
person-search — find people by criteria, no name list needed.
bash
python scripts/enrich.py person-search --company "Northwind Capital" --title director --size 25
Flags:
--company --title --location --country --industry --name
, plus
(1–100),
(default all), and
to pass a raw PDL SQL query for full control. Flags are combined with AND.
company-enrich — match a list of companies to firmographics.
bash
python scripts/enrich.py company-enrich --input companies.csv --output firms.xlsx
Recognised input columns: name/company, website/domain, ticker, linkedin/profile, location/country/region/locality. Needs at least one of name/website/ticker/profile per row.
company-search — find companies by criteria.
bash
python scripts/enrich.py company-search --industry "real estate" --country singapore --min-employees 50 --size 50
Flags:
--name --industry --country --locality --tag --min-employees
, plus
and
.
Reviewing output with the user
People sheets have two tabs:
People (one row per person, status colour-coded) and
Employment history (one row per past role). Company sheets have a single
Companies tab. The
Status column is the first thing to check:
(green),
(amber),
(red),
(orange). Call out the amber/red rows explicitly so the user knows what to double-check.
Tuning matches
(1–10) is the confidence floor for the enrich/identify commands. Raise it (6–8) when names/companies are common and you'd rather miss than mis-match; lower it when you have rich context and want coverage. Company enrichment is most reliable with a website/domain; person enrichment with a company or email alongside the name.
Swapping providers later
The PDL-specific pieces are the
builders,
, and the
/
mappers. To support another provider, implement those against its API and keep the same record dict shape; input parsing, status logic, SQL/flag handling, dry-run summaries, and
writing stay as is.
Principles
- Drafts, not advice — output is a research aid for a person to review, not a determination.
- Never invent — surface only what PDL returns; mark / honestly rather than guessing an identity.
- Deterministic where it counts — input parsing, status logic, dry-run estimates and writing are deterministic.
- Honesty and calibration — flag low-confidence matches and show the rough credit cost up front.
- Workspace hygiene — write outputs where the user expects; never write the API key to disk in the skill.
Data handling
PDL is a third party and enrichment sends the real name/company to it — it cannot be tokenised, because the name
is the lookup. Treat the
/
as a secret: never print, commit or upload it. For people, confirm a legitimate and proportionate purpose and collect only fields relevant to that purpose.
Pitfalls
- Free plan hides contact values — emails/phones come back as booleans; read the status columns.
- Search cost scales with — quote the rough credit cost and keep modest.
- Common names mis-match — raise or add context columns (company/email).
- Never commit — the key is a secret; and need no key.
- Dry-run is an estimate — actual billing follows PDL's endpoint terms and returned records/matches.
Verification checklist
Requirements
- Python 3.8+
- (HTTP uses the stdlib — no needed)
- (env var or ) for live API calls; get one at https://www.peopledatalabs.com
- Network access to the PDL API. and run fully offline.