NewSearch millions of jobs from your AI agent with MCP
All posts
GuideSearch
Guide·Jun 25, 2026·7 min read

Job search API: how to add job search to your product

A build-it integration guide. Get a key, make your first call, learn the filters that matter (title, country, remote, posted-after), wire it into your app with pagination, and keep results fresh.

Dvir Atias

Dvir Atias

Founder, JobsPipe

Adding job search to a product - a candidate-matching feature, an internal sourcing tool, a market dashboard, an AI agent - sounds like a scraping project and is really an integration project. With a job search API the data layer is one HTTP call; the work is wiring it into your app. This is the build-it guide, from first request to paginated, filtered results in your UI. For the product-level overview of what JobsPipe is, see the jobs API page; this post is the how-to.

What a job search API gives you

One endpoint that returns postings from many sources in a single shape, so your application code never branches per source. You send filters, you get back a page of normalized jobs and a cursor for the next page. No proxies, no parsers, no per-ATS schema handling - the parts that sink a DIY scraper are someone else’s problem.

Step 1: get a key and make your first call

Grab a free key from the dashboard, then POST to https://api.jobspipe.dev/v1/jobs/search with a bearer token. A minimal call:

curl https://api.jobspipe.dev/v1/jobs/search \
  -H "Authorization: Bearer jp_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{ "job_title_or": ["product manager"], "limit": 10 }'

The response has two parts: a metadata block (total results and a paging cursor) and a data array of normalized postings.

Step 2: the filters that matter

Every filter is optional and combined with AND. The ones you reach for most:

  • job_title_or - match any of a list of title phrases, for example ["product manager", "program manager"].
  • job_country_code_or - restrict by ISO country code, for example ["US", "GB", "DE"].
  • remote - a boolean; set true to keep only remote-eligible roles.
  • posted_at_max_age_days - only jobs posted within the last N days, the single most useful freshness control.
  • source_or and company_name_partial_match_or - scope to specific sources or companies when you need to.

Step 3: wire it into your product

A thin typed wrapper plus a loop over the cursor is the whole integration. In TypeScript:

const API = "https://api.jobspipe.dev/v1/jobs/search";

async function searchJobs(filters, cursor) {
  const res = await fetch(API, {
    method: "POST",
    headers: {
      "Authorization": "Bearer jp_live_your_key_here",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ ...filters, limit: 25, cursor }),
  });
  if (!res.ok) throw new Error("search failed: " + res.status);
  return res.json();
}

async function allRemotePMs() {
  const filters = {
    job_title_or: ["product manager"],
    job_country_code_or: ["US", "GB"],
    remote: true,
    posted_at_max_age_days: 7,
  };
  const jobs = [];
  let cursor = undefined;
  do {
    const page = await searchJobs(filters, cursor);
    jobs.push(...page.data);
    cursor = page.metadata.next_cursor;
  } while (cursor);
  return jobs;
}

Each item in page.data has the same fields regardless of source - title, company, normalized location, parsed compensation, seniority, posted_at, and an apply_url - so your rendering code is written once.

Step 4: keep results fresh

For a search feature you query on demand, so freshness is automatic. For a stored index, two options. Poll on a schedule with posted_at_max_age_days set to your interval, or, on higher plans, register a webhook and have new and updated jobs pushed to you with signed, idempotent delivery - covered in the webhooks release notes.

Add job search to your product today - free tier with monthly credits.

Get a free API key

Skip the scraper - try the API right now

Live, normalized postings from 30+ ATS feeds and job boards in one JSON schema. No key, no signup - this sandbox returns sample data in the exact live shape.

Results

Press Test search to see normalized job records rendered here, and the raw JSON on the right.

JSON responsePOST /v1/sandbox/jobs/search
{
  "job_title_or": [
    "software engineer"
  ],
  "limit": 3,
  "remote": true
}
Advanced: edit the raw request, or copy it as curl
curl -X POST https://api.jobspipe.dev/v1/sandbox/jobs/search \
  -H "Content-Type: application/json" \
  -d '{"job_title_or":["software engineer"],"remote":true,"limit":5}'

For live results, get a free key (1,000 jobs/month) and swap /v1/sandbox/jobs/search for /v1/jobs/search with an Authorization: Bearer header - request and response shapes are identical.

FAQs

Frequently Asked Questions

What is a job search API?

A job search API is one endpoint that returns postings from many sources in a single shape, so your application code never branches per source. You send filters and get back a page of normalized jobs plus a cursor for the next page. No proxies, no parsers, and no per-ATS schema handling - the parts that sink a do-it-yourself scraper become someone else's problem, which turns a scraping project into an integration project.

How do I add job search to my product?

Get an API key, POST your filters to the search endpoint with a bearer token, then loop over the paging cursor. The response has a metadata block with total results and the next cursor, plus a data array of normalized postings. A thin typed wrapper around that loop is the whole integration, and every item carries the same fields - title, company, normalized location, parsed compensation, seniority, posted_at, and apply_url - so your rendering code is written once.

What filters does the JobsPipe job search API support?

The filters you reach for most are job_title_or for title phrases, job_country_code_or for ISO country codes, remote as a boolean, and posted_at_max_age_days for freshness. source_or and company_name_partial_match_or scope results to specific sources or companies. Every filter is optional and they combine with AND. To keep a stored index fresh, poll with posted_at_max_age_days set to your interval, or on higher plans register a webhook for signed, idempotent delivery.