Careerjet API: a 90-country jobs API built for publishers, not pipelines
Careerjet runs localized job search in over 90 countries and hands out a free, documented search API - rare in this category. But every call must carry the IP and user agent of a real visitor, job links route through tracking redirects, descriptions arrive as sized fragments, and paging stops near result 1,100. Here is how the current v4 API actually works, why the GitHub client libraries no longer match it, and what to reach for when you need data rather than clicks.
Dvir Atias
Founder, JobsPipe
Careerjet is one of the oldest job-search aggregators still running: localized search sites in over 90 countries, interfaces in 28 languages, and more than 58,000 websites scanned every day, by its own published numbers. It also offers something genuinely rare in this category - a documented, self-serve search API. What the documentation is quieter about is who that API is for. Every design decision in it - mandatory end-user parameters, tracking-redirect URLs, a hard paging ceiling - points the same way: this is an affiliate display API for publishers, not a jobs data feed. Here is how it works, where it stops, and what to use past that point.
What Careerjet actually is
Careerjet is a classic feed-plus-crawl aggregator - we place it on the map of the category in the job aggregator breakdown. It references listings from job boards, recruitment agencies and employer career sites, and it monetizes the way most aggregators do: by selling traffic to those listings and sharing revenue with publishers who display them. The API lives inside that publisher program, next to ready-made widgets (JobBox, SearchBox) and XML feeds. You create a publisher account, register the website that will show the results, and get an API key issued against that site.
How the current v4 API works
The current interface is v4: one search endpoint, authenticated with your publisher key over basic auth (the key followed by a colon, base64-encoded):
curl "https://search.api.careerjet.net/v4/query?\
locale_code=en_GB&\
keywords=python%20developer&\
location=london&\
page_size=20&\
user_ip=203.0.113.7&\
user_agent=Mozilla%2F5.0" \
-H "Authorization: Basic $(printf '%s:' "$CAREERJET_API_KEY" | base64)"Two parameters are mandatory on every call: user_ip and user_agent - the IP address and browser user agent of the person whose action triggered the search. Omit either and the API returns a 403. The rest of the surface is compact: locale_code picks the country site (default en_GB; an unsupported code is a 400), contract_type takes single letters for permanent, contract, temporary, internship and volunteering, work_hours switches full-time and part-time, sort accepts relevance, date or salary, page_size goes up to 100, and offset tops out at 999. Responses return jobs with a title, company, date, locations, salary information when present, a description excerpt, and a URL.
The GitHub clients target the old API
Search for the Careerjet API and the first results after the official docs are client libraries: careerjet-api-client-python plus PHP, Ruby and Perl siblings under the official GitHub org. They were written for the older public API: the locale goes into the constructor, and each search passes an affid affiliate ID from a partner account along with user_ip, user_agent and the URL of the page displaying results. That interface is not what the current documentation describes - v4 authenticates with an API key in a basic auth header, not an affid parameter, and the repos have sat unmaintained for years. Treat them as historical reference and integrate against the v4 docs directly; the endpoint is one HTTP call regardless of language.
Four design decisions that tell you what it is for
- Every call must name a real visitor. Mandatory
user_ipanduser_agentmean requests are expected to represent live human searches on your site. A nightly cron filling a database does not have a visitor to name. - Links are tracking redirects. The job URL in each result points at
jobviewtrack.com, Careerjet’s click-tracking service, not at the original posting. The click is the product - it is what publishers are paid on - so there is no canonical source URL to store. - Descriptions are fragments. The
fragment_sizeparameter sizes the description excerpt in characters. An API that measures descriptions in characters is an API for rendering search snippets, not for parsing requirements, skills or salary out of full postings. - Paging stops near 1,100 results. With
offsetcapped at 999 andpage_sizeat 100, no query can walk deeper than roughly its first 1,100 results. There is no bulk export, no webhook, no change feed - comprehensive coverage would mean enumerating thousands of query shapes, and the ceiling still applies to each one.
When Careerjet is the right choice
None of this is a flaw if you are the intended user. If you run a content site with job-seeking traffic and want to monetize it with relevant listings - especially outside the US, where Careerjet’s localized breadth genuinely shows - the API is free, the integration is one endpoint, and the revenue share pays you for clicks you were going to send somewhere anyway. In that same publisher lane, Jooble is the closest comparison with its own free key, and Adzuna adds documented aggregate analytics on top. We compare the whole free tier of this market on the free jobs API page.
When you need a data API instead
The moment job postings are an input to your product rather than content on it - a recruiting tool, a sourcing engine, market analytics, an AI agent - every publisher constraint above inverts into a blocker. You need full descriptions, not sized fragments; the employer’s apply link, not a tracking redirect; and the ability to pull every matching posting, not the first 1,100.
That is the layer JobsPipe operates: reading postings where they are first published - LinkedIn, Indeed, Workday, Greenhouse, Lever, Ashby, SmartRecruiters, Workable and more - and returning full normalized records over one filterable endpoint, across more than 2.4 million live postings as of August 2026:
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": ["python developer"],
"job_country_code_or": ["GB"],
"posted_at_max_age_days": 7
}'Each record carries the complete description, a structured compensation object, a stable id that survives re-crawls, a direct apply_url, and classification you can filter on - skills_or for skills, occupation_code_or for ISCO-08 occupations, isic_division_or for industries. No visitor to name, no per-website key, no paging ceiling. The free tier includes 1,000 jobs per month.
A fair split, same as with Jooble: Careerjet to monetize job traffic you already have; a data API to build the product that attracts it.
Full postings and direct apply links, not tracking redirects - free tier included.
Get a free API key