Recruiting & Sourcing with the LinkedIn API: Build a Candidate Pipeline (2026)
Sourcing is two jobs pretending to be one. First you decide where to look — which companies are hiring for the role, which of them are worth your time. Then you find the people. Recruiters spend hours on the first job manually, tab by tab, before they ever open a candidate profile. The LinkedIn API collapses that first job into a script.
No single endpoint does "sourcing" — but three of them chain into a pipeline that does. The jobs endpoint tells you who is hiring for a role. The company endpoint enriches each of those employers with firmographics so you can rank them. The profile endpoint confirms a specific person. This guide wires all three together, with real data pulled on July 2, 2026 — and it is honest about where the chain stops, because a sourcing tool that overpromises wastes more time than it saves.
TL;DR: Chain three endpoints — /jobs (who's hiring for a role), /company (firmographics to rank employers), /profile (confirm the person). In a live test, one machine learning engineer search surfaced 28 postings from 25 companies; enriching them separated 300k-employee giants from five-person staffing agencies. Jobs and profile are $0.50/1K, company $3/1K — a full sourcing run for one role is about 8 cents. Honest limit: jobs is keyword-matched, not company-filtered. Public data, no login. Code below.
The sourcing chain: three endpoints, one workflow
Each endpoint answers one question in the sourcing funnel. Run them in sequence and the output of each feeds the next:
| Step | Endpoint | Question it answers |
|---|---|---|
| 1. Demand | /api/linkedin/jobs | Which companies are hiring for this role? |
| 2. Prioritize | /api/linkedin/company | Which of those employers are worth targeting? |
| 3. Confirm | /api/linkedin/profile | Who is this specific person? |
The jobs step gives you company names and their LinkedIn URLs, which is the hinge of the whole pipeline: the URL hands you the exact company slug you need for step 2, with no fuzzy name-matching in between.
Step 1: where is the demand?
Start with the role, not the company. A jobs search for a role in a location returns the postings — and every posting names the hiring company and links to its page. Deduplicate by job_id, group by company, and you have a live demand map.
Here is a real one. Searching machine learning engineer across the United States on July 2, 2026 returned 28 unique postings from 25 distinct companies. That set of 25 companies is your raw sourcing list — everyone actively advertising the role right now.
from urllib.parse import urlparse
def slug_from_url(url):
# https://www.linkedin.com/company/<slug> -> "<slug>"
parts = urlparse(url or "").path.strip("/").split("/")
return parts[1] if len(parts) > 1 and parts[0] == "company" else None
companies = {} # slug -> [name, posting_count]
for j in jobs: # jobs = deduped results from /jobs
slug = slug_from_url(j.get("company_linkedin_url"))
if slug:
row = companies.setdefault(slug, [j["company_name"], 0])
row[1] += 1
Step 2: prioritize employers with firmographics
Twenty-five company names is a list, not a plan. The next step turns it into one: enrich each with the company endpoint and rank by fit. Here is what came back for the top of that machine learning engineer list, unedited:
| Company | Postings | employee_count | Size band | HQ |
|---|---|---|---|---|
| Qualcomm | 2 | 57,517 | 10,001+ | San Diego |
| CNN | 2 | 6,810 | 1,001-5,000 | Atlanta |
| 1 | 313,835 | 10,001+ | Mountain View | |
| Paramount | 1 | 37,964 | 10,001+ | New York |
| Starbucks | 1 | 192,342 | 10,001+ | Seattle |
| Bread Financial | 1 | 4,623 | 5,001-10,000 | Columbus |
| Crossing Hurdles | 2 | 194 | 51-200 | — |
| Zest for Tech | 1 | 5 | 2-10 | London |
Method: /jobs?keywords=machine+learning+engineer&location=United+States (3 pages), grouped by company, each enriched via one /company call on 2026-07-02.
Firmographics do two things here that a bare company name cannot:
- They let you rank by fit. If you place candidates at large enterprises, Qualcomm, Google and Starbucks rise to the top; if your niche is mid-market, Bread Financial and CNN do. The same list, sorted differently for different desks.
- They unmask the reposters. "Zest for Tech" (5 employees) and "Crossing Hurdles" (194) are not hiring ML engineers for themselves — they are staffing agencies posting on a client's behalf. Firmographics flag them automatically, so you do not waste a sourcing pass on a middleman. This is the same enrich-and-validate discipline that keeps bad rows out of a CRM, applied to a talent pipeline.
Step 3: confirm the person
Once you have a shortlist of target employers — or a candidate name from your own network — the profile endpoint confirms the person's public basics: name, headline, current role, and location, from a profile URL or vanity username.
Be realistic about this step. Profile data is best-effort: most well-formed public profiles return solid basics, but some come back sparse or empty, and the endpoint returns only the public headline card — not full work history, education, or contact details. It is enough to confirm and contextualize a person, not to replace a recruiter's outreach and research. Treat it as the confirmation stage of the funnel, not a résumé database.
The full pipeline in code
Here is the whole chain: search a role, group the hiring companies, enrich each with firmographics, and print a ranked sourcing table. Extending it to a profile lookup is one more call per person.
import time, requests
from urllib.parse import urlparse
API_KEY = "YOUR_API_KEY"
JOBS = "https://apiserpent.com/api/linkedin/jobs"
COMPANY = "https://apiserpent.com/api/linkedin/company"
def search_jobs(keywords, location="", pages=3):
seen, out = set(), []
for p in range(pages):
r = requests.get(JOBS, headers={"X-API-Key": API_KEY},
params={"keywords": keywords, "location": location, "start": p*10},
timeout=90)
r.raise_for_status()
for j in r.json().get("data", {}).get("jobs", []):
if j["job_id"] not in seen:
seen.add(j["job_id"]); out.append(j)
time.sleep(0.4)
return out
def slug_from_url(url):
parts = urlparse(url or "").path.strip("/").split("/")
return parts[1] if len(parts) > 1 and parts[0] == "company" else None
def enrich(slug):
r = requests.get(COMPANY, headers={"X-API-Key": API_KEY},
params={"slug": slug}, timeout=60)
return r.json().get("data", {}) if r.status_code == 200 else {}
# 1) demand: who is hiring for the role?
jobs = search_jobs("machine learning engineer", "United States", pages=3)
companies = {}
for j in jobs:
slug = slug_from_url(j.get("company_linkedin_url"))
if slug:
row = companies.setdefault(slug, [j["company_name"], 0])
row[1] += 1
# 2) prioritize: enrich and rank
rows = []
for slug, (name, count) in companies.items():
d = enrich(slug)
rows.append((name, count, d.get("employee_count"), d.get("company_size")))
time.sleep(0.3)
for name, count, emp, band in sorted(rows, key=lambda r: -(r[2] or 0)):
print(f"{name:24} {count} post(s) {emp or '-':>8} {band or '-'}")
Honest limits
This pipeline automates the first pass of sourcing. It does not do the whole job, and the boundaries matter:
- Jobs is keyword-matched, not company-filtered. You cannot ask "show me every open role at Qualcomm." You search by role, and companies surface because their postings matched your query. To approximate a company's openings, search the relevant roles and filter by
company_name— but it will never be a complete list of that employer's jobs. (More on this in the jobs filters guide.) - The demand map is a snapshot, not a census. It reflects what is publicly posted for your keywords right now. Broaden the query and re-run to widen the net.
- Profiles are best-effort and shallow. The confirmation step gives you the public card, not a candidate database. It confirms a person; it does not qualify them.
- It finds companies and public profiles, not private contact details. There are no emails or phone numbers here — outreach is still yours to do, through channels you are permitted to use.
Used within those lines, the chain is a genuine time-saver: it turns "spend an afternoon mapping who's hiring" into a script that runs in seconds and hands a recruiter a ranked, de-duplicated, agency-filtered target list.
Build your sourcing pipeline. Create a key in under a minute — new accounts include 10 free Google searches to explore the platform. Grab a free key and run the chain on your own target role.
Pricing
A sourcing run touches all three endpoints, so the cost is a small mix. Jobs and basic profile are the cheap ones; company is the richest and priced accordingly.
| Endpoint | Default | Growth ($100) | Scale ($500) |
|---|---|---|---|
| Jobs search (per page) | $0.50 / 1,000 | $0.05 / 1,000 | $0.025 / 1,000 |
| Company (per employer) | $3.00 / 1,000 | $0.30 / 1,000 | $0.15 / 1,000 |
| Profile (per person) | $0.50 / 1,000 | $0.05 / 1,000 | $0.025 / 1,000 |
Do the math on one role: 3 job-search pages + 25 company enrichments + 10 profile lookups is about 8 cents on Default, and roughly a cent at Scale. Even mapping demand across dozens of roles daily costs a few dollars a month. One deposit unlocks the discount across all three endpoints. See the full pricing page for details.
A note on compliance
Sourcing touches personal data, so this deserves care. Serpent's endpoints access publicly available LinkedIn data only — a keywords query, a company slug, a public profile username, and your Serpent key. There is no login, cookie, or credential in the flow, and no access to private or connection-gated fields.
But "public" is not the same as "unrestricted", and handling people's information carries obligations that company data does not. Whether your specific sourcing use is permitted depends on LinkedIn's terms, your jurisdiction, and privacy law such as GDPR and CCPA — including how you store profiles and how you conduct outreach. Treat compliance as your own decision, get advice for anything at scale, and do not read this article as blanket permission to build a candidate database. The API only ever touches public data and never authenticates as a user; you remain responsible for lawful use.
Turn one role into a ranked sourcing list
Chain jobs, company and profile data into a pipeline that finds who's hiring, ranks employers by fit, and confirms the people — in seconds, for pennies. Jobs and profile from $0.50/1K, company from $3/1K, pay-as-you-go with no subscription.
Get Your Free API KeyExplore: LinkedIn API · Social Media APIs · Pricing
FAQ
Can I use the LinkedIn API for recruiting and sourcing?
Yes, by chaining three endpoints. The jobs endpoint surfaces where a role is in demand (which companies are actively posting it), the company endpoint enriches each of those employers with firmographics so you can prioritize, and the profile endpoint confirms a specific person's public basics. It automates the tedious first pass of sourcing — building and ranking a target list — rather than replacing a recruiter's judgment.
Can I get all the jobs at a specific company with the API?
Not directly. The jobs endpoint is keyword-matched, not company-filtered: you search by role and location, and companies appear because their postings match your query. To approximate "jobs at company X", search the roles you care about and filter the results by company_name client-side — but understand this is not an exhaustive list of that company's openings, only the ones matching your keywords.
How do I prioritize which employers to source from?
Enrich each hiring company with firmographics — employee count, size band, industry, and headquarters — and rank by fit. This also separates real employers from staffing agencies and reposters: in a real July 2026 pull, a "machine learning engineer" search surfaced companies ranging from 300,000-employee tech giants down to five-person recruiting agencies posting on a client's behalf. Firmographics let you tell them apart automatically.
How much does a LinkedIn sourcing workflow cost?
You pay per call across the three endpoints: jobs search and basic profile are $0.50 per 1,000 on Default, and company data is $3.00 per 1,000. A full sourcing run for one role — a few job-search pages, firmographic enrichment for around 25 companies, and a handful of profile lookups — costs roughly eight cents on Default, and far less at Growth or Scale tiers. It is pay-as-you-go with no subscription.
Do I need a LinkedIn login to use the API for sourcing?
No. You send public identifiers — a keywords query, a company slug, a profile username — and your Serpent API key in an X-API-Key header. The endpoints access publicly available LinkedIn data only, with no login, cookie, or OAuth flow on your side. Because sourcing involves personal data, you should treat privacy-law compliance (GDPR, CCPA) as your own responsibility.



