All platforms

WeRecruit Jobs API

Query jobs from WeRecruit boards through one API with ?source=werecruit — plus how WeRecruit's sitemap really behaves.

?source=werecruitsource reference

WeRecruit is a French multi-tenant ATS at careers.werecruit.io, used mostly by French employers and recruitment agencies. (It is not the unrelated UK staffing agency of the same name — different company, no boards.)

It is also the single best-behaved source of one thing that every other platform on this site withholds.

Finding boards is the hard problem, and WeRecruit just answers it#

The instinct is that scraping an ATS is about fetching. It isn't. Fetching is the easy half. The hard half is knowing which boards exist, because almost no platform will tell you: every customer is an isolated subdomain or slug, there is no global index, and a finished, tested adapter with no board list scrapes exactly nothing. We have watched that happen to more than one adapter here.

WeRecruit is the exception. One unauthenticated request enumerates the entire platform:

BASH
curl "https://careers.werecruit.io/sitemap.xml"

Measured 2026-07-15: 25,113 URLs, resolving to 22,653 job offers across 2,460 distinct company boards, each entry carrying a <lastmod>. Not a sample, not a seed list to grow from. The platform.

For scale, what the alternative looks like

The other exceptions in this pool are HireHive's cross-tenant aggregator key and Dover's shared feed. Everywhere else, a board list is assembled: Common Crawl sweeps, Wayback derivation, public dataset imports, and patience. Lever's 4,803 tracked boards took real work, and Lever is a much bigger platform than WeRecruit.

One request against a sitemap is not how this normally goes.

The sitemap is the only route#

The obvious follow-up is to fetch each board page and read its offers. That returns nothing, and it returns nothing at HTTP 200:

  • Board pages are AngularJS-rendered and contain zero offer links in the HTML that arrives.
  • The only JSON-LD on an offer page is an Organization block. There is no JobPosting, so a standard schema.org extractor finds nothing to extract.
  • There is no JSON API. We checked the bundle.

So the shape is fixed: sitemap for discovery and listing, then one HTML fetch per offer. Fetch the sitemap once and cache it — it's 3.8MB, and re-pulling it for each of 2,460 boards would be absurd.

What the adapter reads#

Offer pages are parsed rather than deserialized, and the useful fields are in unusual places:

WhereWhat it holds
<h1>The job title
div.description.rich-textThe body
<title>Contract type, location and employer — the only copy of any of them
sitemap <lastmod>The only date the platform exposes

That <title> is doing a lot of work. It's structured "{title} - {contract} {à|in} {location} | … | {company}" and it is genuinely the only place the contract type, the location and the employer name appear — the page renders them client-side, so there is nothing else to read. Take the last pipe segment as the employer, not the second: some boards insert a marketing segment (Offre d'emploi) in between. Accents arrive as hex entities (&#xE9; for é), and the body is rich HTML with nested divs, so a lazy .*?</div> truncates it at the first one.

Descriptions came back at 100% on the boards tested (broadpeak 2/2, aero-interim 29/29). The <lastmod> is a modification stamp rather than a true publish date, which makes it a freshness signal — WeRecruit re-stamps offers on publish, so it's close, but it is not the same claim.

Or use ours#

The sitemap is pulled once and cached rather than re-fetched per board, the <title> is split from the right so a marketing segment can't be mistaken for the employer, the hex entities are decoded, and the body is taken by walking the div nesting rather than by a regex that stops at the first </div>. <lastmod> is carried as the freshness signal it is and not relabelled as a publish date. Then the usual: dedup and the company join, normalised onto the same schema as every other source.

One thing worth stating plainly, since this page has spent most of its length on discovery: best discovery in the pool is not the same as biggest source in the pool. WeRecruit is complete because its board list is complete, which is a different virtue from being large. 22,653 offers is a good number and it is not SmartRecruiters.

Query it with ?source=werecruit. The keys of /v1/meta.sources are the values ?source= actually accepts, with counts — read that rather than hardcode a list.

Sources & coverage · all platforms · quickstart.

Every source above normalises onto the same schema, with the hiring company already joined onto each posting.

Get an API key