Try it
Run a live LinkedIn lookup
One real call, no signup and no key. Give it any public profile and read the JSON it returns.
Endpoints & Pricing
Six LinkedIn Endpoints, One API Key
Every endpoint publishes its own rate, and the tier you are on is the only thing that changes it. Deposits are one-time; there is no monthly plan.
Profile
GET /api/linkedin/profile— by URL or by username- Name, headline, occupation, location and current role
- Experience and education, best-effort by design
- Follower count and the LinkedIn Top Voice flag
- Languages, honours and organisation memberships where published
- Two opt-in field groups, each +20%
Jobs
- Per job that is $0.05/1,000, or $0.035 at Scale
GET /api/linkedin/jobs— keyword and location search- Filter by date posted, job type and remote
GET /api/linkedin/job— one posting in full, same rate- Description, seniority, employment and workplace type
- Applicant count, and salary range when it is listed
Company
GET /api/linkedin/company— by company URL or slug- Employee count as a number, plus the published size band
- Industry, founded year, company type and specialities
- HQ street, city, state, postal code and country
- Website and logo URL
- Tagline and the company’s full description text
Full Profile
GET /api/linkedin/profile/full- Summary, fuller experience history, education
- Profile photo, follower count, best-effort connections
- Languages and honours where published
- Organisation memberships and public web links
- On a slow lookup it returns what it has, not an error
- Same object shape as Profile, so one parser covers both
Posts
GET /api/linkedin/posts- Up to 50 recent public posts — text, image, article, video
- Content, permalink, published timestamp and images
- Reactions, comments and hashtags
- Depth is priced per post: base × (0.4 + 0.06 × limit)
- So 50 posts is 3.4× the base rate, 10 posts is the base
- Comment threads and video transcripts opt-in, +20% each
Profile Search (beta)
GET /api/linkedin/search- Find a person by name when you do not have a profile URL
- Narrow the search by company, job title or location
- Up to 10 candidate public profiles per search
- Name, headline and profile URL for each match
- Feeds straight into Profile or Full Profile for the detail
- Beta — match quality varies with how common the name is
Growth unlocks with a one-time $100 deposit and Scale with a one-time $500. Both are permanent and neither expires. Free to start on eligible endpoints, with the allowance shared across them.
Quick Start
One Request, Typed JSON Back
Send a profile URL, a company URL or a keyword. Nothing to log into, no session to keep alive, and the same auth header as every other endpoint in the catalog.
# A public profile, by URL or by username curl "https://apiserpent.com/api/linkedin/profile?username=williamhgates" \ -H "X-API-Key: YOUR_API_KEY" # Company firmographics by company URL curl "https://apiserpent.com/api/linkedin/company?url=https://www.linkedin.com/company/stripe" \ -H "X-API-Key: YOUR_API_KEY" # One jobs call = one page of ~10 postings, billed as ONE call curl "https://apiserpent.com/api/linkedin/jobs?keywords=data+engineer&location=Berlin&remote=true" \ -H "X-API-Key: YOUR_API_KEY"
import requests KEY = "YOUR_API_KEY" CALL_RATE = 0.0005 # $0.50 per 1,000 calls, Default tier jobs, page = [], 0 while page < 10: # 10 calls, ~100 postings r = requests.get( "https://apiserpent.com/api/linkedin/jobs", headers={"X-API-Key": KEY}, params={"keywords": "data engineer", "location": "Berlin", "start": page * 10}, ).json() batch = r["data"]["jobs"] if not batch: break # genuinely the end of the result set jobs += batch page += 1 spend = page * CALL_RATE print(len(jobs), "jobs for $", round(spend, 4)) # -> 100 jobs for $ 0.005 (= $0.05 per 1,000 jobs)
const KEY = process.env.SERPENT_KEY; async function enrich(companyUrl) { const res = await fetch( `https://apiserpent.com/api/linkedin/company?url=${encodeURIComponent(companyUrl)}`, { headers: { "X-API-Key": KEY } } ); const { success, data } = await res.json(); if (!success) return null; // Every key is always present. A field the public page did not carry // arrives as null or [], so nothing here ever throws on an absent field. return { name: data.name, industry: data.industry, headcount: data.employee_count, // number, not "1,001-5,000" sizeBand: data.company_size, founded: data.founded_year, country: data.hq.country, website: data.website, hqCity: data.hq.city, }; } console.log(await enrich("https://www.linkedin.com/company/stripe"));
{
"success": true,
"data": {
"name": "Stripe",
"universal_name_id": "stripe",
"industry": "Financial Services",
"company_size": "1,001-5,000 employees",
"employee_count": 8214,
"founded_year": 2010,
"company_type": "Privately Held",
"specialities": ["payments", "developer tools"],
"website": "https://stripe.com",
"hq": {
"city": "South San Francisco",
"state": "California",
"country": "United States",
"line_1": "354 Oyster Point Blvd"
},
"logo_url": "https://media.licdn.com/dms/image/.../stripe.png"
}
}
Every key is always present. A field the public page did not carry arrives as null or [] rather than disappearing, so one parser handles every endpoint and never has to branch on which one produced the object.
Data Fields
Every Field a LinkedIn Call Returns
Named, typed JSON — not HTML you have to select against. employee_count is a number; founded_year is a year.
Profile Fields
- full_name / first_name / last_name
- headline, occupation, summary
- location.city / .state / .country
- current_company.name / .title
- experiences[] / education[]
- languages[] / honors_awards[]
- follower_count / connections
- flags.top_voice
- profile_pic_url / profile_url
Company Fields
- name, tagline, description
- industry, company_type
- employee_count (number)
- company_size (published band)
- founded_year
- specialities[]
- hq.city / .state / .country
- hq.line_1 / .postal_code
- website, logo_url
Job Fields
- job_id, job_url, apply_link
- job_title, company_name
- company_linkedin_url, company_logo
- location, job_posted_date
- job_description (+ _html)
- seniority_level, employment_type
- workplace_type, job_function
- industries[], applicants_count
- salary.min / .max / .currency
Request Parameters
- url (profile or company URL)
- username (profile slug)
- slug (company slug)
- keywords, location (jobs)
- date_posted, job_type, remote
- job_id (single posting)
- name, company, title (search)
- limit (posts depth)
- include_company_details, include_public_web
Why LinkedIn data
The reference LinkedIn API closed. This one is priced per page.
Proxycurl shut down in July 2025. What replaced it mostly bills per record and, in one popular case, wants your own login. Neither is true here.
Proxycurl shut down on 4 July 2025
For years Proxycurl was the reference LinkedIn API — the one the tutorials used and the one most side projects were built against. Its founder announced the closure on the company's own site, following the federal lawsuit LinkedIn filed against it in January 2025.
Everything built on it needed a replacement with the same shape: a URL in, typed JSON out, nothing to connect. If you are migrating, put a thin adapter between your code and whichever vendor you pick, so that the next closure is a one-file change instead of a rewrite.
No cookies, and never your account
These endpoints need no LinkedIn login, no OAuth flow, no developer app and no session cookie. That is not the norm. The curious_coder LinkedIn profile scraper on Apify requires you to paste in your own LinkedIn session cookies, and its own listing warns that 300–400 profiles a day is enough to get that account flagged.
The risk in that model is not a failed request. It is your own LinkedIn account, and the recruiters and sellers who depend on it. Nothing here is ever tied to an account of yours.
A jobs call is a page, not a row
One jobs request returns a whole page of roughly ten postings, and it bills as one call. At $0.50 per 1,000 calls that is about $0.05 per 1,000 jobs, and about $0.035 at the Scale rate.
Every rival we could price bills per job instead: $1.50 per 1,000 job records at Bright Data, $5.00 at Apify's apimaestro jobs scraper, and $0.50 at Coresignal — that last one only on a $5,000-a-month plan. On the same unit that is a 10× to 100× gap.
One-time deposits, never a monthly plan
Growth costs a single $100 deposit and Scale a single $500. They are permanent, they never expire and an account never downgrades out of them. Nothing on this site bills monthly.
That matters because almost every cheapest rate in the table below is attached to a recurring plan: $499 a month at Bright Data, $5,000 at Coresignal, $30,000 at ScrapingDog. A rate you only reach while paying rent on it is not the same product as one you keep.
Price Comparison
Every Vendor's Lowest Rate, Not Their Entry Rate
Our cheapest against their cheapest, on matching units, with what each lowest rate actually requires. Figures come from each vendor's own live pricing page.
Public profile lookup — cost per 1,000 profiles
| Provider | One billable unit is | Cost per 1,000 | What the lowest rate requires | Free tier |
|---|---|---|---|---|
| Serpent (ours) | 1 call = 1 profile | $0.50 → $0.35 | A one-time $500 deposit. No monthly plan. | Free to start |
| Bright Data Profiles | 1 record = 1 profile | $1.50 → $1.30 | Scale plan at $499 every month | 5,000 records a month |
Apify harvestapi profile scraper |
1 profile (no cookies needed) | $4.00 flat | Nothing — no subscription. $10.00/1K with email search. | $5 credit a month |
Apify curious_coder profile scraper |
1 profile | $4.00 flat | Your own LinkedIn session cookies. Its listing warns 300–400 profiles a day flags that account. | $5 credit |
| ScrapingDog | 50 credits a request, 100 if the profile is protected (their LinkedIn profile page) | $10.00 → $1.36 | The $30,000-a-month plan. Entry is the $40-a-month LITE plan. | 200 credits (about 4 profiles) |
| Coresignal Employee Collect | 10 credits a profile | $196.00 → $5.00 | Elite, at $5,000 every month. Entry is the Mini plan at $49 a month. | 7-day trial |
| Bright Data Datasets (not a live API) | a bulk file, refreshed monthly | from $2.50 → about $0.50 | A monthly-refresh subscription, delivered to S3, Snowflake or SFTP. Cannot answer “fetch this profile now”. | — |
| Proxycurl | Shut down on 4 July 2025, after LinkedIn's January 2025 federal lawsuit. No longer sells LinkedIn data. | |||
Job postings — cost per 1,000 jobs
| Provider | One billable unit is | Cost per 1,000 | What the lowest rate requires | Free tier |
|---|---|---|---|---|
| Serpent (ours) | 1 call = a page of about 10 jobs | $0.05 → $0.035 (that is $0.50 → $0.35 per 1,000 calls) | A one-time $500 deposit. No monthly plan. | Free to start |
| Bright Data Jobs | 1 record = 1 job | $1.50 → $1.30 | Scale plan at $499 every month | 5,000 records a month |
Apify apimaestro jobs scraper |
1 job | $5.00 flat | Nothing — no subscription | $5 credit |
| Coresignal Jobs | 1 credit a record | $19.60 → $0.50 | Elite, at $5,000 every month. Entry is the Mini plan at $49 a month. | Trial credits |
| ScrapingDog Jobs | 5 credits a request — jobs per request not published | $1.00 → $0.136 per request, not per job | The $30,000-a-month plan | 200 credits |
How to read this. Every figure is the vendor's own published rate, checked 8 September 2026, and our column shows our lowest rate against theirs rather than against their entry price. ScrapingDog cannot be normalised on jobs: it bills per request and does not publish how many jobs a request returns, so its row is per request and is not comparable to the others. ScrapingDog also states its LinkedIn profile credit cost differently on its profile page (50, or 100 for a protected profile) than in its documentation index (10–100); the figure above is the one from its LinkedIn profile page. The one rate that undercuts our Default is Bright Data's Datasets marketplace at about $0.50 per 1,000, and it is a bulk file on a monthly subscription rather than a live lookup.
Use cases
What Teams Actually Pull LinkedIn Data For
Four jobs that account for most LinkedIn API traffic, and the endpoint each one needs.
CRM and lead enrichment
Company is the richest and most reliable dataset here, and it is what turns a bare domain in your CRM into a scored account: headcount as a number, published size band, industry, founded year, type and the HQ address.
Enrich on write rather than nightly. At $1.00 per 1,000 a full re-enrichment of a 20,000-account CRM costs $20 at Default and $14 at Scale.
Recruiting and talent sourcing
Profile Search takes a name plus a company, title or location and returns up to 10 candidate public profiles; feed the winning URL straight into Profile or Full Profile for the experience and education history.
The pairing matters because most sourcing lists start as names in a spreadsheet, not as LinkedIn URLs, and a name-to-URL step is normally the part you have to build yourself.
Hiring-signal and market intelligence
A jobs feed is the earliest public signal a company is expanding, entering a market or adopting a technology. One call is a page of about ten postings with title, company, location and posted date; the single-posting lookup adds the description, seniority, applicant count and salary range.
Because we bill per page rather than per job, a daily sweep across 200 queries is 200 calls, not 2,000 rows.
Job-board aggregation
Paginate a keyword-and-location search with start to build a board. Each page is one billed call, and a page that comes back empty is genuinely the end of the result set rather than an error.
At the Scale rate, 100,000 postings costs about $3.50 in API spend. Refresh the postings you already hold with the single-job lookup at the same rate.
# One line per company: date, company, how many roles it is advertising today. # One call per company = one page of ~10 postings, so this is 1 billed call each. while IFS= read -r co; do n=$(curl -s -G "https://apiserpent.com/api/linkedin/jobs" \ --data-urlencode "keywords=$co" \ -d "date_posted=past_week" \ -H "X-API-Key: $SERPENT_KEY" \ | jq -r '.data.count // 0') echo "$(date -u +%F),$co,$n" >> hiring-signal.csv done < companies.txt
FAQ
LinkedIn API Questions
curious_coder LinkedIn profile scraper on Apify requires you to paste in your own LinkedIn session cookies, and its own listing warns that 300 to 400 profiles a day is enough to get that account flagged. Nothing here is ever tied to an account of yours.
apimaestro LinkedIn jobs scraper on Apify charges $5.00 per 1,000 jobs, and Coresignal reaches $0.50 per 1,000 job records only on its $5,000-a-month Elite plan. ScrapingDog bills 5 credits a request but does not publish how many jobs a request returns, so its rate cannot be converted to a per-job figure at all.
harvestapi profile scraper on Apify at $4.00, ScrapingDog at $10.00 entry on its $40-a-month LITE plan, and Coresignal at $196.00 entry, reaching $5.00 only on a $5,000-a-month plan. One honest exception belongs in that picture: Bright Data's Datasets marketplace sells LinkedIn profile data from about $0.50 per 1,000 records, which is under our Default rate. It is a bulk file on a monthly-refresh subscription, delivered to S3, Snowflake or SFTP. It cannot answer the question a live API answers, which is fetch this specific profile now.
null or an empty list rather than disappearing, and your parser never has to branch on which endpoint produced the object.
delivery block naming what was requested and what was returned so you can tell a thin profile from a thin answer.
Start using the LinkedIn API
Free to start on eligible endpoints, with the allowance shared across them. No card and no subscription — profiles from $0.50/1K on Default, $0.35 at Scale.
Try for Free

