LinkedIn Jobs API & Scraper
The LinkedIn Jobs API returns job postings, company and location data as clean JSON.
🤖 Using an AI assistant? Copy this link into ChatGPT / Claude / Cursor — it reads every endpoint and parameter instantly and tells you if this API fits your use case.
The primary jobs/search endpoint returns jobs with id, URL, title, company (name, URL, slug), location, workplace type, posted date, salary and seniority, and you can pull a jobs/detail, a company, jobs by company, similar jobs and a location search. It is built for recruiting tools, labor-market analysts and sales intelligence that need LinkedIn job data without a login or a scraper. One ReefAPI key, one shared credit pool, the standard envelope.
Search filters, their accepted values, and what a bad value does
Every filter below is an enum with a fixed vocabulary, and the two failure modes are not the same. keywords is validated and a missing or empty value is rejected outright. The filters are not: a value outside the list is silently ignored, so a typo in date_posted returns unfiltered results that look correct. Check the values here before you ship a query builder.
| Parameter | Accepted values | Bad value |
|---|---|---|
| keywords | free text (title, skill, keyword) — required | rejected |
| date_posted | 24h · week · month | ignored (query runs unfiltered) |
| experience | internship · entry · associate · mid_senior · director · executive | ignored |
| job_type | fulltime · parttime · contract · temporary · internship · volunteer · other | ignored |
| workplace | onsite · remote · hybrid | ignored |
| geoId | numeric LinkedIn id — get it from locations/search | ignored |
| company | company slug, full company URL, or numeric LinkedIn company id | ignored |
| max_results | 1–1000, default 50 | rejected |
1000 is LinkedIn's own ceiling for a single guest query, not a plan limit — past it the result set stops regardless of paging. To go deeper, split the query by location or date window rather than paging further.
Real request and response JSON
Captured from the indexed primary action, jobs/search, on .
{
"method": "POST",
"url": "https://api.reefapi.com/linkedin-jobs/v1/jobs/search",
"headers": {
"x-api-key": "$REEF_KEY",
"content-type": "application/json"
},
"body": {
"keywords": "python developer",
"location": "United States",
"max_results": 25
}
}{
"ok": true,
"meta": {
"api": "linkedin-jobs",
"endpoint": "jobs/search",
"mode": "live",
"latency_ms": 3804.4,
"record_count": 25,
"bytes": 119505,
"cache_hit": false,
"completeness_pct": 100,
"stop_reason": "max_results",
"requests": 4,
"included_detail": false,
"included_company": false,
"pagination": {
"has_more": true,
"next_cursor": "25"
}
},
"data": {
"jobs": [
{
"job_id": "[redacted-phone]",
"job_url": "https://www.linkedin.com/jobs/view/python-developer-at-open-systems-technologies-[redacted-phone]",
"title": "Python Developer",
"company": {
"name": "[redacted-name]",
"url": "https://www.linkedin.com/company/open-systems-technologies",
"slug": "open-systems-technologies",
"logo": "https://media.licdn.com/dms/image/v2/C4D0BAQHdzu0CEs024A/company-logo_100_100/company-logo_100_100/0/[redacted-phone]/open_systems_technologies_logo?e=[redacted-phone]&v=beta&t=MI3Ojj1GBjmbiIhFGIQ-sgGOIMaYzzgo5636Y351nyc",
"specialties": []
},
"location": "New York, NY",
"posted_date": "[redacted-phone]",
"posted_relative": "4 days ago",
"benefits": [
"Actively Hiring"
],
"search_query": "python developer",
"search_location": "United States"
},
{
"job_id": "[redacted-phone]",
"job_url": "https://www.linkedin.com/jobs/view/middle-backend-developer-at-aml-crypto-[redacted-phone]",
"title": "Middle Backend Developer",
"company": {
"name": "[redacted-name]",
"url": "https://www.linkedin.com/company/aml-crypto",
"slug": "aml-crypto",
"logo": "https://media.licdn.com/dms/image/v2/C4E0BAQHWGUfdl-4noA/company-logo_100_100/company-logo_100_100/0/[redacted-phone]/aml_crypto_logo?e=[redacted-phone]&v=beta&t=Te898WQQzD0Ao6LoVt193x89CNK5Br7Omm7LSpqyw-I",
"specialties": []
},
"location": "Marion County, IN",
"posted_date": "[redacted-phone]",
"posted_relative": "1 day ago",
"benefits": [
"Be an early applicant"
],
"search_query": "python developer",
"search_location": "United States"
},
{
"job_id": "[redacted-phone]",
"job_url": "https://www.linkedin.com/jobs/view/python-developer-at-aci-infotech-[redacted-phone]",
"title": "Python Developer",
"company": {
"name": "[redacted-name]",
"url": "https://www.linkedin.com/company/aciinfotech",
"slug": "aciinfotech",
"logo": "https://media.licdn.com/dms/image/v2/C560BAQF2q-kc4T8Tow/company-logo_100_100/company-logo_100_100/0/[redacted-phone]/aci_infotech_logo?e=[redacted-phone]&v=beta&t=SmlWXghpJi6ZlGJcUrot9cOPK5cxexK03Zk1ux4Vrqs",
"specialties": []
},
"location": "New York, NY",
"posted_date": "[redacted-phone]",
"posted_relative": "2 months ago",
"benefits": [],
"search_query": "python developer",
"search_location": "United States"
}
],
"count": 25,
"pages_fetched": 4,
"stop_reason": "max_results"
}
}What the LinkedIn Jobs API does
| Action | Description | Concrete use case | Key params |
|---|---|---|---|
| jobs/search | Search public LinkedIn job postings by keywords, with optional location and date/seniority/job-type/workplace filters. | Recruiting teams call jobs/search to search public LinkedIn job postings by keywords, with optional location and date/seniority/jo…. | keywords, location, max_results, date_posted, experience, ... |
| jobs/detail | Full posting for one job: description, employment type, seniority, salary, applicant count. | Labor-market analysts call jobs/detail to get full posting for one job. | job_id, include_company |
| company | Company profile: description, website, employee count, industry, HQ, founded year, specialties. | Job boards call company to get company profile. | company |
| jobs/by-company | All public job postings at a specific company — pass a company slug, URL or numeric id; optionally narrow with the same keyword/location/date/seniority/job-type/workplace filters as jobs/search. | Sales intelligence teams call jobs/by-company to get all public job postings at a specific company. | company, keywords, location, max_results, date_posted, ... |
| locations/search | Location typeahead → resolve a place name (city, region, metro area, country) to the LinkedIn numeric geoId used by the `geoId` search param for precise geo-pinned searches. | Recruiting teams call locations/search to get location typeahead → resolve a place name (city, region, metro area, country) to the LinkedIn…. | query |
| jobs/similar | Related job postings for a given job_id. LinkedIn's guest surface exposes no direct similar-jobs feed, so results are a keyword+location re-search seeded from the source job's own title (the seed job is excluded). | Labor-market analysts call jobs/similar to get related job postings for a given job_id. | job_id, keywords, location, max_results, include_detail, ... |
Call jobs/search from your stack
curl -X POST https://api.reefapi.com/linkedin-jobs/v1/jobs/search \
-H "x-api-key: $REEF_KEY" \
-H "content-type: application/json" \
-d '{"keywords":"python developer","location":"United States","max_results":25}'import requests
r = requests.post(
"https://api.reefapi.com/linkedin-jobs/v1/jobs/search",
headers={"x-api-key": REEF_KEY},
json={
"keywords": "python developer",
"location": "United States",
"max_results": 25
},
)
print(r.json()["data"])const res = await fetch("https://api.reefapi.com/linkedin-jobs/v1/jobs/search", {
method: "POST",
headers: {
"x-api-key": process.env.REEF_KEY,
"content-type": "application/json",
},
body: JSON.stringify({
"keywords": "python developer",
"location": "United States",
"max_results": 25
}),
});
const { ok, data, meta, error } = await res.json();Ask your MCP-connected assistant: call reefapi.linkedin-jobs.jobs/search with {"keywords":"python developer","location":"United States","max_results":25}.Who uses this API and why
- Recruiting tools call jobs/search to track open roles by title, location and workplace type.
- Sales-intelligence teams use jobs/by-company to spot hiring and expansion signals at accounts.
- Labor-market analysts use seniority and posted_date to measure demand trends over time.
Questions developers ask before integrating
Which fields only appear when I pass include_detail?
A plain jobs/search result carries job_id, job_url, title, company (name, url, slug, logo), location, posted_date, posted_relative. Everything a hiring analyst actually wants — description_text, description_html, salary, seniority_level, employment_type, job_function, industries, applicant_count_text, apply_url, easy_apply, job_state — only arrives with include_detail set. The cost is one extra request per job: a 2-job search with include_detail measured 3 requests, so pull the list first and hydrate the rows you care about.
Why is salary missing on some LinkedIn jobs even with include_detail?
Because LinkedIn did not publish one. In a measured two-job sample one posting returned salary as an object with text, min_value, max_value and currency; the other had no salary key at all. Treat the field as absent-or-object, never as an empty string, and never infer a range from the seniority label. The same applies to benefits, which comes back as an empty array far more often than a populated one.
What is a LinkedIn geoId, and why does one city name return several?
geoId is LinkedIn's internal numeric id for a place, and it is the only way to pin a search to exactly the geography you mean. locations/search on 'Berlin' returned 10 of them: Berlin, Berlin, Germany (106967730), Berlin Metropolitan Area (90009712), Stadt Berlin (101283667), plus Berlin in Connecticut, Maryland and New Jersey. The free-text location parameter picks one of those for you and will sometimes pick a different one than you expect — resolve the geoId once and reuse it.
What does workplace_type_source mean on a job?
It tells you where the Remote/Hybrid/On-site label came from. A value of facet means the job inherited the label from the filter you searched with, not from a statement in the posting itself. That distinction matters if you are counting remote roles: filtering on workplace=remote and then counting workplace_type=Remote is circular. Only rows whose source is the posting are independent evidence.
Are seniority_level and employment_type reliable?
They are LinkedIn's own labels, copied through unchanged, and employers fill them in carelessly. A measured example: a Cargill posting titled 'Data Engineer' came back with seniority_level 'Not Applicable' and employment_type 'Internship'. We do not correct these — if we normalized them you would have no way to tell a real label from our guess. Filter on them, but expect noise at the tails.
How do I page through more than one screen of results?
meta.pagination returns has_more and next_cursor; pass next_cursor back as cursor to continue. record_count and stop_reason tell you why a page ended — stop_reason 'max_results' means you hit your own cap, not the end of the inventory. The ceiling on any single query is roughly 1000 postings.
Can I get every open role at one company?
Use jobs/by-company with a company slug (the part after linkedin.com/company/), the full company URL or the numeric id. It returns the same job shape plus the resolved company_id, and accepts the same keyword, location, date and seniority filters if you want to narrow within the employer. The separate company action returns the employer profile: description, website, employee_count, industry, headquarters, founded and specialties.
What is the LinkedIn Jobs API?
LinkedIn Jobs API is a ReefAPI endpoint group for public job listings and details. It returns live JSON through POST requests under /linkedin-jobs/v1.
Is the LinkedIn Jobs API free to try?
Yes. ReefAPI starts with 1,000 free credits, no card required. LinkedIn Jobs calls use the same shared credit balance as every other ReefAPI engine.
Do I need a LinkedIn Jobs login or account?
No login to LinkedIn Jobs is needed for the API response. You call ReefAPI with your x-api-key header, and the playground can run live examples before you create a production key.
How fresh is the LinkedIn Jobs data?
The page example is captured from a live jobs/search call, and production requests fetch live data through ReefAPI rather than a static sample.
How many credits does the LinkedIn Jobs API use?
LinkedIn Jobs actions currently cost 1-2 credits per successful call. Failed or blocked calls are free, and all APIs draw from one credit pool.
Can I call LinkedIn Jobs from an AI assistant or MCP client?
Yes. Connect ReefAPI once through MCP and your assistant can call linkedin-jobs actions with the same key, credit pool and JSON envelope used by normal REST requests.
Is the LinkedIn Jobs API a LinkedIn Jobs scraper?
It is the managed alternative to a DIY LinkedIn Jobs scraper. Instead of building and maintaining your own scraper — proxies, headless browsers, captcha and constant breakage — you call one ReefAPI endpoint and get the same public job listings and details back as clean JSON.