LinkedIn Jobs API

Search public LinkedIn job postings without a LinkedIn account

The LinkedIn Jobs API returns job postings, company and location data as clean JSON.

no credit card1,000 free credits · instant API key · live in 10 seconds
Missing a LinkedIn Jobs endpoint, or need a source we don't have yet?Contact us real people · same-day reply.
L
/linkedin-jobs/v1

6 active endpoints, on 1 and 2 credit tiers.

  • POST/linkedin-jobs/v1/jobs/search
  • POST/linkedin-jobs/v1/jobs/detail
  • POST/linkedin-jobs/v1/company
  • POST/linkedin-jobs/v1/jobs/by-company
  • POST/linkedin-jobs/v1/locations/search
  • POST/linkedin-jobs/v1/jobs/similar

What LinkedIn Jobs endpoints does ReefAPI ship?

6 live read endpoints. Read-only data API: no writes, no account actions, no dashboard access on the target site.

6 endpoints

jobs/search

1 cr

Search public LinkedIn job postings by keywords, with optional location and date/seniority/jo…

required
keywords
optional
location, max_results, date_posted, experience, job_type, workplace, industry, job_function, salary_min, salary_band, company, include_detail, include_company, page, cursor, start, geoId, filters, detail_concurrency

jobs/detail

1 cr

Full posting for one job.

required
job_id
optional
include_company

company

2 cr

Company profile.

required
company
optional

jobs/by-company

1 cr

All public job postings at a specific company.

required
company
optional
keywords, location, max_results, date_posted, experience, job_type, workplace, industry, job_function, salary_min, salary_band, include_detail, include_company, page, cursor, start, geoId, filters, detail_concurrency

locations/search

1 cr

Location typeahead → resolve a place name (city, region, metro area, country) to the LinkedIn…

required
query
optional

jobs/similar

1 cr

Related job postings for a given job_id.

required
job_id
optional
keywords, location, max_results, include_detail, include_company

Every parameter, every allowed value →

LinkedIn Jobs API

3 of 6 endpoints, ready to run

View docs ↗

Public postings by keyword, with LinkedIn's own facets: posting window, seniority, employment type and workplace arrangement.

1 credit1 required · 6 optional
POST/linkedin-jobs/v1/jobs/search
idle
// Press "Try it" and this pane shows exactly what the
// live site returned this second — including an empty
// result, if that is the truth. No key, no account.

How the LinkedIn Jobs API works

LinkedIn Jobs is a normal ReefAPI surface — the same four rules that hold for every other engine on the key.

01
Authenticate
x-api-key header

No OAuth app, no request signing, no per-site account. One key covers all 185 engines.

02
Call
POST /linkedin-jobs/v1/…

Every route is a POST with a JSON body. Parameters are validated against the published schema before anything is charged.

03
Pay
1 or 2 credits per call

Credits, not seats. Failed and blocked calls are never charged, and cache hits cost nothing.

04
Read
{ ok, data, meta, error }

One envelope everywhere. meta carries latency_ms, record_count and the endpoint that answered.

Pin the region first, then walk one query to its floor

Free-text locations resolve to whatever LinkedIn thinks you meant. Resolving the geoId first removes that guess, and it costs one cheap call you can do at build time.

01search
POST/linkedin-jobs/v1/locations/search
{"query": "San Francisco"}

Came back with ten candidates, each with a geoId — the Bay Area metro and the city itself are different ids, and so are the San Franciscos in Mexico, Argentina and the Philippines.

02search
POST/linkedin-jobs/v1/jobs/search
{"keywords": "python developer", "geoId": "90000084", "date_posted": "24h", "max_results": 200}

geoId beats free text, and date_posted genuinely bites — a 24h run returned rows dated only to yesterday and today.

A dated, deduplicated set of public postings for exactly the region you asked for — and a stop_reason telling you whether you reached the end of the query or the end of the surface.

request
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}'
response envelope
{
  "ok": true,
  "data": { … },
  "meta": {
    "api": "linkedin-jobs",
    "endpoint": "jobs/search",
    "mode": "live",
    "latency_ms": …,
    "record_count": …
  },
  "error": null
}

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.

ParameterAccepted valuesBad value
keywordsfree text (title, skill, keyword) — requiredrejected
date_posted24h · week · monthignored (query runs unfiltered)
experienceinternship · entry · associate · mid_senior · director · executiveignored
job_typefulltime · parttime · contract · temporary · internship · volunteer · otherignored
workplaceonsite · remote · hybridignored
geoIdnumeric LinkedIn id — get it from locations/searchignored
companycompany slug, full company URL, or numeric LinkedIn company idignored
max_results1–1000, default 50rejected

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.

The ceiling, the freshness, and the one field that is simply not there

Measured on 2026-08-28 by walking one query to exhaustion and comparing two regions. One of these lines goes against us, and it is a big one.

No LinkedIn account, no cookies, no seat

This reads the public guest surface. You do not connect a LinkedIn account, you do not hand over a session cookie, and there is no Sales Navigator or Recruiter seat involved — so there is no account of yours that can be restricted for using it. That is also why the ceiling below is what it is: the public surface is genuinely smaller than a logged-in one, and we would rather tell you the number than pretend otherwise.

One query bottoms out at roughly 450 unique postings

Asking for 1,000 returned 451 rows, all 451 unique, in 54 seconds across 52 upstream requests — and the response said so plainly: stop_reason complete, has_more false, next_cursor null. Pushing the raw offset agreed: start 900 returned 10 rows and start 975 returned none. Roughly 450 per query is the real number, and the way past it is more queries, not deeper paging — split by city, by seniority, by workplace type or by posting window.

🔴 There is no salary field, at any depth

Against us, and worth knowing before you plan around it. salary, salary_min and salary_max were absent on every row, and turning on include_detail did not add them — the detailed rows carried description, employment type, seniority, industries and job function, and still no pay. The salary_min search filter exists and does narrow the result set, but the number it filtered on never comes back in the payload. If you need pay figures, this is the wrong engine; use indeed's estimated_salary, levels-fyi or reed.

Dates are on every row, and the window filter is honest

posted_date came back as an ISO date on 25 of 25 rows in every run, next to a human posted_relative. date_posted 24h returned only rows stamped yesterday or today. Without that filter the feed is not fresh-only: an unfiltered United States search reached back to 2025-10-10 and a Berlin one to 2025-01-20, and the 451-row exhaustive pull spanned sixteen months.

include_detail is what turns a row into a posting

The default row is deliberately thin: title, company, location, url, date. With include_detail on, the same rows came back with description_text and description_html 10 of 10, employment_type 10 of 10, seniority_level 10 of 10, industries 10 of 10, job_function 9 of 10, a job_state of active — and applicant_count_text on 10 of 10, which is the competition signal nothing else in this batch carries. It costs an upstream request per row, so it is slower.

Location is free text until you make it an id

The same keyword against "United States" and against "Berlin" returned different feeds with different date ranges, which is expected — but free text is resolved by LinkedIn, not by you. locations/search returned ten distinct geoIds for "San Francisco", including the Bay Area metro, the city, the county, and four San Franciscos outside the United States. Resolve once, then pass geoId.

🔴 This is a postings engine. It is not a profile engine.

What comes back is the posting and the employer: title, company name and slug, location, dates, description, employment type, seniority, applicant count band. What does not come back, from any action here, is a candidate profile, an employee list, a connection graph or anyone's personal contact details. We do not sell people data and this engine does not collect it — if that is what you need, this is not the product, and we would rather say so on the page than in a support ticket.

The company action is firmographics, not a roster

One slug returns the company's description, website, employee count, size band, industry, headquarters, founding year and organisation type. A count of employees, not a list of them.

jobs/similar is a re-search, and says so

LinkedIn's guest surface has no similar-jobs feed, so this action reads the seed posting's title and location and runs the search again. It is useful and it is honest about what it is; do not read it as LinkedIn's own recommendation model.

What people build with LinkedIn Jobs

The jobs this data is most often used for.

6

endpoints

1/2

credits per call

01

Recruiting tools call jobs/search to track open roles by title, location and workplace type.

02

Sales-intelligence teams use jobs/by-company to spot hiring and expansion signals at accounts.

03

Labor-market analysts use seniority and posted_date to measure demand trends over time.

What LinkedIn Jobs data costs

The cheapest call here is 1 credit, so $15/mo (Pro) buys 10,000 of them — $1.50 per 1,000 credits. Credits roll over and never expire, and failed or blocked calls are not charged.

Full pricing →
$0.67–$1.50 / 1,000 credits
  • 1,000 free credits on signup, no card
  • One key, all 185 APIs, one credit pool
  • Failed and blocked calls are never charged
  • Credits roll over and never expire

Call it in two lines

Sign up, get 1,000 credits and one key that works on every engine. Then this is the whole protocol.

curl
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}'
python
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"])
FAQ

Have a question? We got answers.

The questions people actually ask before wiring up LinkedIn Jobs.

Get a free key →
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.

15 Jobs & Hiring APIs on the same key

One key, one credit pool, one response envelope. If you are pulling LinkedIn Jobs, you are one call away from the rest of the category — no second contract, no second integration.

Need something this API does not do?

Name the endpoint, the field, or a source we do not carry yet. We ship new APIs every week and you would be first to get the key. Real people read every message and reply the same day.

0/4000

No account needed · we reply from [email protected]

Try it on your own data before you pay anything

The call above is the real endpoint, not a recording. A free key gives you 1,000 credits, the other 184 APIs, and the same envelope everywhere.

Endpoints, parameters and credit costs on this page are read from the live catalog and cannot drift from what the API accepts. Field notes were captured on 2026-08-28.