Looking for the overview — what this API returns, what it costs, and a call you can run without a key? See the ZipRecruiter API page →
Jobs & Hiring

ZipRecruiter API & Scraper

The ZipRecruiter API returns live US job listings as clean JSON.

3 actionsLive JSON1,000 free credits$0.67–$1.50 / 1,000 creditsMCP-ready
Get a free keyOpen in playground

🤖 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 search endpoint returns jobs with id, title, company, location, salary (min, max, currency, period), posted date, snippet and URL, and you can pull a job_detail and jobs_by_company. It is built for recruiting tools, labor-market analysts and job boards that need ZipRecruiter data without a scraper. One ReefAPI key, one shared credit pool, the standard envelope.

Reference

Which editions answer, and why the two actions disagree about dates and links

This engine reads ZipRecruiter's European editions. The search action returns what the country site prints on the page, localized strings included, while job_detail reads the posting's own structured data. That is why the same job comes back with different date, link and location formats depending on which action you called. Measured on 'software engineer' in London and 'nurse' in the UK (50 rows), job_detail for 584464834, 583195628, 583691259 and 580259992, and an ie, de, fr and us sweep.

FieldMeasured shapeNote
countrygb serves ziprecruiter.co.uk, ie serves ziprecruiter.ie, de serves ziprecruiter.de. All three returned rows.fr is not in the enum but passed through and returned ziprecruiter.fr rows, so other two-letter codes are worth trying. us returned TARGET_BLOCKED, as the parameter description warns.
job_id9-digit numeric string: '584464834'It is the last segment of ziprecruiter.co.uk/jobs/<id>. job_detail takes it as job_id, or accepts the full URL.
posted_date (search)A localized, year-less string in the site's own language: '20 Aug' on gb, '20. Aug' on de, '28 juil.' on frThis is the page's own label. Do not parse it as a date; it carries no year and its format changes with the edition.
posted_date (job_detail)A real ISO date, '2026-08-26', with valid_through '2026-09-25T20:39:27.148Z'valid_through ran 30 days after posted_date on every job we checked. Both can be null on older postings.
salaryObject {min, max, currency, period, raw, source}source was 'text' on every priced row, so the figures are read out of the posting rather than supplied as structured pay. raw keeps the original string, e.g. '£14.25 - £15.15 per hour'.
salary period and coverage'year' and 'hour', lowercaseAbout half the rows had any salary at all: 10 of 20 in one London search, 8 of 30 in another. A posting quoting a single figure gives min set and max null, so '£39,500 per annum' becomes min 39500, max null.
job bodyjob_detail only, and plain text486 to 4,480 characters with no HTML tags in the jobs we read. Search rows give a snippet of about 150 characters instead. requirements is an extracted list that was empty on three of four jobs and held 11 items on the fourth.
apply_urlDifferent per actionSearch rows point at a long tracking redirect. job_detail returns ziprecruiter.co.uk/applicants/external?apply_to=<job_id>. Both reach the employer's application, but only the second is short enough and stable enough to store.
location'Greater London, ENG, GB' in search; a location_structured object in job_detailjob_detail gives {locality, region, postal_code, country} with spelled-out values ('Bristol', 'England', 'United Kingdom'), and postal_code came back as an empty string rather than null.
employment_type / remote'Full Time' plus a remote boolean, job_detail onlySearch rows carry neither. The remote parameter on search is applied by matching each listing's title and location, so it filters the page rather than the site.

sponsored was true on all 50 gb rows we pulled across two different queries, and false on every ie, de and fr row. On the UK edition it does not separate paid placements from organic ones, so do not build a filter on it.

Live example

Real request and response JSON

Captured from the indexed primary action, search, on .

Captured request
{
  "method": "POST",
  "url": "https://api.reefapi.com/ziprecruiter/v1/search",
  "headers": {
    "x-api-key": "$REEF_KEY",
    "content-type": "application/json"
  },
  "body": {
    "query": "software engineer",
    "location": "London",
    "country": "gb",
    "max_results": 20
  }
}
Captured response
{
  "ok": true,
  "meta": {
    "api": "ziprecruiter",
    "endpoint": "search",
    "mode": "live",
    "latency_ms": 1153.8,
    "record_count": 20,
    "bytes": 86381,
    "cache_hit": false,
    "completeness_pct": 100,
    "country": "gb",
    "total_estimate": null,
    "salary_present": 6,
    "sponsored": 20
  },
  "data": {
    "query": "software engineer",
    "location": "London",
    "country": "gb",
    "total_estimate": null,
    "count": 20,
    "jobs": [
      {
        "job_id": "[redacted-phone]",
        "title": "Software Engineer",
        "company": "SF Partners",
        "location": "Worcester, ENG, GB",
        "salary": null,
        "posted_date": "02 Jul",
        "snippet": "Job Description Software Engineer with key skills across the PHP stack and solid AWS and AI tooling exposure ideally gained in a product/ platform...",
        "url": "https://www.ziprecruiter.co.uk/jobs/[redacted-phone]",
        "apply_url": "https://www.alertsclk.com/ekn/AAINkpS-X1yznxEFbLg1g8PQGPlTXkuVy1bAW9vZGoOWlfWthEGjRUxcFDsSVWuaH6JbPPIJXKjZdvg8TTVKHTKliNa8cFbps_9KbW7sFY9llUgbO69n9k0l-UdxuM45_mqLPYmzu6X8ioL2BTUCLIa34EcXhD3uUNFomkhBAY4A6KnavqIVr1a_IuBcyAHuS4dGpiU9JJdJ_czsNbhdUF45r-sM9GOGOpC1CmqkY1RwqgbA7acJ27SKi3ptnEGk9AKx0x3o7ntqS-Qlj7lcHX8P3GDfBIlw0Y6t-QBr8r1h-srmqQPoVVhBvnvWjzIaNlLCsMZV-2TMqioEmzQyKUYtU5zZqcLcLHIUiJO3Woskn8st35t2BZQKp4yJyMep3gT3xEj23BDNO5JKZcH9jekt1o2PYPgK7RDT1lALpQyvGUlMKnhJeXeho_ZrO4LbNvs2ELR7eaWSGVi7m0OykRSzyEGF4j0qVBjsNjb6kbzOWLZKIN2evt1z2Kh6HZxjUKOCpYiSQhUMKMWXv5TW5oC1irLzEMmpiK45QQ4oOhRKy5RYwWG91Mn_1N",
        "sponsored": true,
        "source": "ziprecruiter.co.uk"
      },
      {
        "job_id": "[redacted-phone]",
        "title": "Software Engineer",
        "company": "Avanti",
        "location": "Marlow, ENG, GB",
        "salary": {
          "min": 40000,
          "max": 50000,
          "currency": "GBP",
          "period": "year",
          "raw": "£40,000 - £50,000",
          "source": "text"
        },
        "posted_date": "02 Jul",
        "snippet": "Job Description Full Stack Software Engineer Hybrid Working | £40,000 - £50,000 + Benefits A growing software company is looking for a Full Stack...",
        "url": "https://www.ziprecruiter.co.uk/jobs/[redacted-phone]",
        "apply_url": "https://www.alertsclk.com/ekn/AAKNQc8eWpOqjx6R3SUxr5CYR4GoK_YjGXHJZar4xG0Nxn1JXbViTH04P3y9Iq5ApOBu9e9BF0PJpGeZdOxRAoBImVxS-UPt2iFCRKgYelyw7eIeZh_QldsJubY2PaLwKyD90TsGU6i0SH_z6lHZ2w3edYsbXDbOM_MgWgW1F-5G6fCxJETf-eEvtuTEQqu-FilCRHFyJhSU_EsGGKagXbnFRqXR9IJgLFYeXteu3JkdKOGOi0bSnRvSHv7hS5VFPewUZqAw9o9GT5gibYjFQrWo6HEgEx-Q4xrqe-X9htMbFmc0IwBd7zTBBpSiVQ-88c7kpYTh4uxBVRMQwDqD8kfj3xxHjumPCc3mNWM8dIBL_vDb4ID2ZPLHLYkZDRAzlGbLYFS0Vc7ec5R5AVOHv7OqKfrJvb3LD44YjXZugkiC6VqiRHVMLkgDwXlHkMhmD1sUI6TWf0ygvawiNcBafzDLtZDB0jmNs4kxXCxhV7DHb_amz5yCoV09ZxJKsW9hkZEu4XdsP6XYjrVCZ3Gl7nqR93hCG5ufz6aCpCf8OUhyyzXqcLWfdPJTQ7",
        "sponsored": true,
        "source": "ziprecruiter.co.uk"
      },
      {
        "job_id": "[redacted-phone]",
        "title": "Software Engineer",
        "company": "Hudson Shribman",
        "location": "London, ENG, GB",
        "salary": {
          "min": 50000,
          "max": null,
          "currency": "GBP",
          "period": "year",
          "raw": "£50k",
          "source": "text"
        },
        "posted_date": "02 Jul",
        "snippet": "Job Description Software Engineer £50k Base + Excellent BenefitsRef: ABJ6539Location: Cambridgeshire | PermanentAre you a Software Engineer who enjoys...",
        "url": "https://www.ziprecruiter.co.uk/jobs/[redacted-phone]",
        "apply_url": "https://www.alertsclk.com/ekn/AAKDCjXcBL5eHb9QQKobKrPymA7yqYj6CWu-0eFs06XmKp2gZSLs1-8Gn7_uOHmfyDyEAZWH4WghfYCbOKW2bpSMKq1h4LW6xw76DCyfpsrFaulZdnUNtW6dShWOOfVw2Qz5n3WZAx5mvj9xA3p13WJnQHUHFCOlRbnCB6CS4p3F2yZ1WCRL8bHUr-pdws69WKzk6r7aM36Bwk2tfNvihBAKP7TITfkmlrXj3BTfqKM7yFy4hMXGMlbF7i4fTgcbd8bZsZNf19vTNGA-_qRtHhT0UFJ1aVJrQWJ1tqbnzr_yidcVMgdqtYTHAjztXy1WRMmdCPmq_oASRzqKVb11XizJKEPuw3T50NBNbA3obIqP8uuBPMJl4jo_cyPkoKENfnV1DXgSZUr7Znu8rQqM4zGZafIGLcjq1zOxXoPdWrZWP1BTL5R9MI87bPD0JyRcNCFNQIAALp8PDZM6rLniqGgiJcgnMt0dNvEfqhD4oWSw9LAZJsxMY9pIMZg0GsuZYEeY6-pBGuTPxbFHaI4slfVyTGU5rQPHDVRjQ82s2wUeRO1aA14ug5Cz0y",
        "sponsored": true,
        "source": "ziprecruiter.co.uk"
      }
    ]
  }
}
Actions

What the ZipRecruiter API does

ActionDescriptionConcrete use caseKey params
searchSearch live ZipRecruiter job listings by keyword and location, with pagination and an optional remote-only filter. Each result includes the title, company, location, salary (when posted), posting date, a snippet, the on-site job URL and the apply link. Covers the United Kingdom (ziprecruiter.co.uk), Ireland (ziprecruiter.ie) and Germany (ziprecruiter.de).Recruiting teams call search to search live ZipRecruiter job listings by keyword and location, with pagination and an optiona….query, location, country, page, max_results, ...
job_detailFull ZipRecruiter job posting by job ID (or URL): title, company, location, salary range, employment type, remote flag, posting & expiry dates, the full description, an extracted requirements list and the apply link.Labor-market analysts call job_detail to get full ZipRecruiter job posting by job ID (or URL).job_id, url, country
jobs_by_companyList a specific employer's open jobs on ZipRecruiter. Pass a company name; the engine searches and keeps only listings whose employer matches (ZipRecruiter's country sites have no dedicated company page, so this is a best-effort name match over the search results). Optionally narrow by location.Job boards call jobs_by_company to list a specific employer's open jobs on ZipRecruiter.company, location, country, page, max_results
Code samples

Call search from your stack

curl -X POST https://api.reefapi.com/ziprecruiter/v1/search \
  -H "x-api-key: $REEF_KEY" \
  -H "content-type: application/json" \
  -d '{"query":"software engineer","location":"London","country":"gb","max_results":20}'
MCP one-liner
Ask your MCP-connected assistant: call reefapi.ziprecruiter.search with {"query":"software engineer","location":"London","country":"gb","max_results":20}.
Use cases

Who uses this API and why

  • Job boards call search to aggregate fresh ZipRecruiter listings with salary data.
  • Compensation tools use the salary range to benchmark pay for a role and location.
  • Sales-intelligence teams use jobs_by_company to detect hiring signals at target accounts.
FAQ

Questions developers ask before integrating

Why is posted_date '20 Aug' with no year?

Search results carry the label ZipRecruiter prints on its own listing page, and that label is localized and year-less. We saw '20 Aug' on the UK edition, '20. Aug' on the German one and '28 juil.' on the French one for comparable rows. If you need a real date, call job_detail on that job_id, which returns posted_date as '2026-08-26' and valid_through as a full ISO timestamp.

Is the salary structured, or scraped out of the text?

It is a structured object, but derived from text. Every priced row carries salary{min, max, currency, period, raw, source}, and source was 'text' on all of them, meaning the engine parsed the figures out of the posting body. raw keeps the original string so you can check the parse yourself. Period values are lowercase 'year' and 'hour'.

Half of my results have salary: null. Is that a failure?

No, that is the market. UK listings often do not quote pay, and we measured 10 of 20 priced in one London search and 8 of 30 in another. A null salary means the posting did not state one in a form the parser recognized, not that the call failed. Note also that a posting quoting a single figure comes back as min with max null, even when the wording is 'up to'.

Is the job description HTML or plain text?

Plain text, and only from job_detail. The four postings we pulled ran from 486 to 4,480 characters with no HTML tags at all, starting with a literal 'Job Description' heading. Search rows do not include the body; they give you a snippet field of roughly 150 characters. There is an extracted requirements array too, though it was empty on three of the four jobs we checked.

Which countries work, and can I use a code that is not in the list?

gb, ie and de are the supported editions and all three returned rows. us is documented as unavailable and returns a clear TARGET_BLOCKED rather than an empty list. Other two-letter codes are passed through as-is, which does sometimes work: fr is not in the enum but returned five ziprecruiter.fr rows, with French date labels.

Why does apply_url change between search and job_detail?

They are taken from different places on the site. Search rows expose the tracked outbound link, a long redirect with an opaque token, while job_detail returns ZipRecruiter's own ziprecruiter.co.uk/applicants/external?apply_to=<job_id> form. If you are storing links, store the job url and the job_detail apply_url; the tracked search links are long and not durable.

Can I trust the sponsored flag?

Not on the UK edition. It came back true on all 50 gb rows we pulled across two unrelated queries, and false on every ie, de and fr row, so on gb it describes the whole page rather than individual paid placements. Treat it as metadata about how the page was served, not as an ad label.

What does jobs_by_company actually match on?

The country sites have no employer profile page, so the action runs a search and keeps rows whose employer name matches what you passed. That match is loose: asking for 'NHS' returned jobs from 'NHS Professionals' and 'NHS Shared Business Services'. It is useful for grouping an employer family, but check the company field on each row if you need one exact legal entity.

What is the ZipRecruiter API?

ZipRecruiter API is a ReefAPI endpoint group for job listings with full details. It returns live JSON through POST requests under /ziprecruiter/v1.

Is the ZipRecruiter API free to try?

Yes. ReefAPI starts with 1,000 free credits, no card required. ZipRecruiter calls use the same shared credit balance as every other ReefAPI engine.

Do I need a ZipRecruiter login or account?

No login to ZipRecruiter 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 ZipRecruiter data?

The page example is captured from a live search call, and production requests fetch live data through ReefAPI rather than a static sample.

How many credits does the ZipRecruiter API use?

ZipRecruiter actions currently cost 1 credit per successful call. Failed or blocked calls are free, and all APIs draw from one credit pool.

Can I call ZipRecruiter from an AI assistant or MCP client?

Yes. Connect ReefAPI once through MCP and your assistant can call ziprecruiter actions with the same key, credit pool and JSON envelope used by normal REST requests.

docs / ziprecruiter

ZipRecruiter

Job listings with full details.

base /ziprecruiter/v13 endpoints
post/ziprecruiter/v1/job_detail1 credit

Full ZipRecruiter job posting by job ID (or URL): title, company, location, salary range, employment type, remote flag, posting & expiry dates, the full description, an extracted requirements list and the apply link.

ParameterAllowed / rangeDescription
job_idrequiredZipRecruiter numeric job ID — the `job_id` returned by the search action (or the number in a ziprecruiter.co.uk/jobs/<id> URL). Provide job_id OR url.
urloptionalFull ZipRecruiter job URL — alternative to job_id (the ID is extracted automatically).
country = gboptionalgb · ie · de · usZipRecruiter country edition to search. gb (United Kingdom), ie (Ireland) and de (Germany) are fully live. us (United States) is not served by this endpoint yet — a us call returns a clear TARGET_BLOCKED rather than an empty list. Other two-letter codes are passed through as-is.
Try in playground →
post/ziprecruiter/v1/jobs_by_company1 credit

List a specific employer's open jobs on ZipRecruiter. Pass a company name; the engine searches and keeps only listings whose employer matches (ZipRecruiter's country sites have no dedicated company page, so this is a best-effort name match over the search results). Optionally narrow by location.

ParameterAllowed / rangeDescription
companyrequiredEmployer name to list open jobs for (e.g. 'Amazon', 'NHS', 'Deloitte').
locationoptionalCity or region to search in (e.g. 'London', 'Dublin', 'Berlin'). Leave empty to search the whole country.
country = gboptionalgb · ie · de · usZipRecruiter country edition to search. gb (United Kingdom), ie (Ireland) and de (Germany) are fully live. us (United States) is not served by this endpoint yet — a us call returns a clear TARGET_BLOCKED rather than an empty list. Other two-letter codes are passed through as-is.
page = 1optional1–Result page to start from, beginning at 1 (20 jobs per page). Use this to page through results — it is the single pagination control.
max_results = 20optional1–200How many job listings to return, paging internally from `page` (1–200).
Try in playground →