France Travail Scraper $1💰 Jobs, Salaries & Apply Links
Pricing
from $1.00 / 1,000 results
France Travail Scraper $1💰 Jobs, Salaries & Apply Links
Scrape job offers from France Travail with titles, companies, locations, salaries, contracts, descriptions, skills, employer details, and apply links. Search by keyword, location, contract, sector, salary, sort options, or paste job/search URLs.
Pricing
from $1.00 / 1,000 results
Rating
0.0
(0)
Developer
Abot API
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
3 days ago
Last modified
Categories
Share
France Travail Scraper: Job Listings, Salaries and Employer Details
France Travail Scraper turns France Travail (formerly Pole emploi), France's national employment agency job board, into structured job data. Search by keyword plus filters such as location, contract type, working time, professional domain, salary floor, experience and qualification level, or paste France Travail search links directly. Each job comes back with employer, location, contract type, salary range, the full description, required skills and apply links. Export the results to JSON, CSV or Excel, or pull them straight into your app through the API.
Why This Scraper?
- Two ways to find jobs. Search by keyword plus filters, or paste France Travail search links and let the actor walk them forward page by page.
- Full job records, not just the search card. Turn on detail fetching to add the full description, salary range, required skills, soft skills, employer block and apply/contact links to every result.
- Location resolved the way the site itself resolves it. A typed city, department or region name is looked up against France Travail's own location autocomplete and sent as the matching area code, instead of a free-text value the server can silently ignore.
- Granular filters. Contract type, working time, professional domain, salary floor, experience level, qualification level, and disability-inclusive or adapted-company employer badges.
- One cap to think about. Max listings is the single run cap; Max pages defaults to unlimited and simply stops once Max listings is reached.
- Built for schedules. Incremental mode returns only new, updated and reappeared jobs on recurring runs, with expired-job detection once a run completes a full scan of the tracked search.
- Resume support. Continue an interrupted large pull without re-scraping, or re-paying for, jobs a previous run already collected.
Use Cases
- Labor-market research: track hiring volume, salary ranges and contract mix across regions, professional domains and time windows.
- Recruiting intelligence: benchmark an employer's or a sector's hiring patterns, contract mix and pay bands over time.
- Data engineering and BI: feed structured job records into a warehouse, dashboard, alerting tool or a search/matching engine.
- Lead generation: identify employers and recruiters actively hiring, with role-level context for outreach.
- Workforce monitoring: schedule the actor against a saved search and get notified only of new or changed postings.
Data You Get
Sample shape: values are illustrative placeholders, not from a live record.
| Field | Example |
|---|---|
type | "job" |
id | "123XYZA" |
url | France Travail link to the job detail page |
title | "Développeur web" |
company | "Sample Recruiter SARL" |
location | "75 - Paris" |
postalCode | "75015" |
contractType | "CDI" |
workTime | "Temps plein" |
publishedAt | "2026-01-15" |
description | full job description text (when detail fetching is on) |
salaryText | "35 - 45 k€ brut annuel" |
salaryMin / salaryMax | 35000 / 45000 |
salaryUnit | "YEAR" |
experienceRequirements | ["De 1 à 3 ans"] (when detail fetching is on) |
skills / softSkills | ["JavaScript", "SQL"] / ["Autonomie"] (when detail fetching is on) |
romeCodes | ["M1805"] (when detail fetching is on) |
recruiterName | "Sample Recruiter SARL" |
employerPageUrl / applyActionUrl | France Travail links (when detail fetching is on) |
industry / qualification | "Informatique" / "Non cadre" (when detail fetching is on) |
inclusiveEmployer / adaptedCompany | false / false |
scrapedAt | "2026-01-15T09:00:00.000Z" |
Every record also carries seedId, seedType and seedValue (which search produced it) and pageIndex; address fields addressLocality, addressRegion, addressCountry and mapUrl; employer fields companySize, recruiterDescription, employerLogoUrl, employerPhone, employerEmail and contactActionUrl; and additionalInformation, jobLabels, employmentType, workHours and validThrough. In incremental mode, records also carry changeType, changedFields, firstSeenAt and lastSeenAt.
How to Use
- Pick a mode:
search(keywords plus filters) orurl(paste France Travail search links). - For search mode, fill in your keywords and any filters (location, contract type, salary, professional domain, and so on). For url mode, paste one or more search URLs instead.
- Set Max listings (the run cap) and, if you want a hard per-search page limit, Max pages, then click Start.
- Download the dataset as JSON, CSV or Excel, or read it through the API.
Query-driven run:
{"mode": "search","queries": ["data analyst", "business analyst"],"location": "Paris","publishedDate": "Last Week","contractType": ["Permanent contract (CDI) | CDI"],"maxItems": 50}
Targeted domain and salary floor:
{"mode": "search","queries": ["cariste"],"location": "Lille","jobCategory": ["Logistics | Transport, Logistique"],"contractDuration": ["Full-time | Temps plein"],"minSalary": 2000,"maxItems": 30}
Paste a search URL:
{"mode": "url","urls": ["https://candidat.francetravail.fr/offres/recherche?motsCles=developpeur&lieux=75D"],"maxItems": 40}
Run it from your code
Python:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("abotapi/francetravail-fr-scraper").call(run_input={"mode": "search", "queries": ["developpeur"], "location": "Paris"})for job in client.dataset(run["defaultDatasetId"]).iterate_items():print(job["title"], job["company"], job["salaryText"])
JavaScript:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('abotapi/francetravail-fr-scraper').call({ mode: 'search', queries: ['developpeur'], location: 'Paris' });const { items } = await client.dataset(run.defaultDatasetId).listItems();
Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.
The one cap rule
Max listings (maxItems) is the single global cap on how many jobs the run returns, across every search. With several keywords or URLs, the cap is shared out evenly: each search returns at most Max listings divided by the number of searches (rounded up), and a search that finds fewer jobs does not pass its unused share to the others. For example, maxItems: 50 with two keywords returns up to 25 jobs per keyword. Max pages (maxPages) defaults to unlimited and simply stops once Max listings is reached; set it only when you also want a hard per-search page limit (20 jobs per page) regardless of Max listings.
Resume and recurring updates
- Resume (
resumeFromRunId) continues one interrupted run: paste its run or dataset ID and the actor reads every job id it already saved there, then appends only new jobs, so you do not pay twice. - Incremental mode (
incrementalMode) is for scheduled runs over the same search. Each job is classifiedNEW,UPDATED(withchangedFields),UNCHANGED(suppressed and not billed unlessemitUnchangedis on),REAPPEARED, orEXPIRED(only after a run that scanned this search's full scope end to end, and only withemitExpiredon). If you useemitExpired, set Max listings comfortably above the total number of jobs your searches return: when Max listings is smaller than a results page, the jobs beyond it on that page are skipped without being checked, and can be reported asEXPIREDeven though they are still online.stateKeynames or shares the stored state; leaving it empty derives a key automatically from the mode, queries, filters or URLs, and the detail-fetch setting, so differently configured searches never mix state. With incremental mode off, output is exactly as before.
Send results into your apps (MCP connectors)
Optionally pipe the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step after the dataset push has finished: the Apify dataset is never changed.
What gets written to the connector: a condensed, human-readable summary of each job, not the full JSON. Each item becomes one entry with a title and its key fields flattened to plain text. The complete record always stays in the Apify dataset.
- Authorize a connector once under Apify > Settings > Integrations (Notion, Linear, Airtable, or Apify).
- Select it in the "Pipe results into your apps" input field. (If the picker is empty, you haven't authorized a connector yet.)
- For Notion, also set
notionParentPageUrlto the page under which job pages should be created. This field is required only for the Notion connector; if it's missing, the actor logs a warning and skips the Notion export instead of failing the run. - Use
maxNotifyListingsto cap how many items are written to each connector per run. It never affects how many items land in the dataset.
The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave the field empty to skip.
Input Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
mode | string | search | search (keywords plus filters) or url (paste France Travail search links). |
queries | array | ["developpeur"] | Search keywords, one per line. Each line runs its own search. |
location | string | Paris | City, department code, region, or postal area, applied to every search. Free text is resolved to the site's own area code through its autocomplete; unresolved text is sent as is. Leave empty to search across all of France. |
radius | integer | 10 | Search radius in kilometres around the location. 0 means no radius. |
publishedDate | string | Last Week | Keep only jobs posted within this window: Last 24 hours, Last 3 Days, Last Week, Last 2 Weeks, or Last Month. |
contractType | array | ["Permanent contract (CDI) | CDI"] | Contract types to include (CDI, CDD, Intérim, apprenticeship and more). |
contractDuration | array | ["Full-time | Temps plein"] | Working time. Use the full labels exactly: Full-time | Temps plein, Part-time | Temps partiel, Not specified | Non renseignée; other spellings are ignored. |
jobCategory | array | ["IT | Informatique, Télécommunication"] | Professional domains to include (IT, healthcare, logistics, hospitality and more). |
minSalary | integer | 0 | Drop listings below this minimum monthly gross salary in EUR. 0 keeps all. |
experience | array | (none) | Experience levels to include, matched by keywords in the job detail page's experience text, so it needs Fetch full job details on. Use the full labels exactly: Entry-level | Moins de 1 an, Mid-level | De 1 à 3 ans, Senior | Plus de 3 ans, Not specified | Non renseignée. Matching is approximate: neighbouring levels can overlap. |
seniority | array | (none) | Qualification level. Use the full labels exactly: Executive | Cadre, Non-executive | Non cadre; other spellings are ignored. |
onlyFranceTravail | boolean | false | Keep only offers published directly on France Travail, excluding partner offers. |
inclusiveEmployer | boolean | false | Keep only offers from employers showing the disability-inclusive commitment badge. |
adaptedCompany | boolean | false | Keep only offers from adapted companies. |
sortBy | string | Newest | Date | Sort by relevance or by publication date. |
urls | array | sample URL | France Travail search URLs (url mode). |
maxItems | integer | 20 | The run cap: stop after this many jobs across all searches, shared evenly between searches. |
maxPages | integer | 0 | Per-search page limit (20 jobs per page). 0 means unlimited, stops at Max listings. |
fetchDetails | boolean | true | Open each job page for the full description, salary, skills, employer block and apply links, billed as a detail-enrichment surcharge per enriched job returned. |
resumeFromRunId | string | (none) | Continue one interrupted run without re-scraping, or re-paying for, jobs it already collected. |
incrementalMode | boolean | false | Return only new, updated and reappeared jobs on repeated scheduled runs of the same search. |
stateKey | string | (none) | Name or share an incremental-mode monitoring campaign. |
emitUnchanged | boolean | false | Also return (and bill) jobs that have not changed since the last run. |
emitExpired | boolean | false | Also return (and bill) jobs no longer found, once a run completes a full scan. |
proxy | object | Apify Residential proxy | Connection settings. |
mcpConnectors | array | (none) | Optional: send a summary of each job to apps you authorized under Integrations. |
notionParentPageUrl | string | (none) | Notion connector only: page under which job pages are created. |
maxNotifyListings | integer | 50 | Cap on items written to each connector per run. Does not affect the dataset. |
Output Example
Sample shape: values are illustrative placeholders, not from a live record.
{"type": "job","id": "123XYZA","url": "https://candidat.francetravail.fr/offres/recherche/detail/123XYZA","title": "Développeur web","seedId": "a1b2c3d4e5f6","seedType": "query","seedValue": "developpeur","pageIndex": 1,"company": "Sample Recruiter SARL","location": "75 - Paris","postalCode": "75015","addressLocality": "Paris","addressRegion": null,"addressCountry": "France","mapUrl": null,"contractType": "CDI","workTime": "Temps plein","publishedAt": "2026-01-15","validThrough": null,"description": "Sample job description text describing the role, responsibilities and required profile.","salary": 45000,"salaryCurrency": "EUR","salaryMin": 35000,"salaryMax": 45000,"salaryUnit": "YEAR","salaryText": "35 - 45 k€ brut annuel","employmentType": "FULL_TIME","workHours": "Temps plein","experienceRequirements": ["De 1 à 3 ans"],"skills": ["JavaScript", "SQL"],"softSkills": ["Autonomie"],"additionalInformation": [],"companySize": "50 à 99 salariés","recruiterName": "Sample Recruiter SARL","recruiterDescription": null,"employerPageUrl": "https://recrute.francetravail.fr/page-employeur/sample-recruiter-000","employerLogoUrl": null,"employerPhone": null,"employerEmail": null,"applyActionUrl": "https://candidat.francetravail.fr/offres/recherche/detail.detailstandalone.postuler.contact:chargercontact?t:ac=123XYZA","contactActionUrl": "https://candidat.francetravail.fr/offres/recherche/detail.detailstandalone.postuler.contact:chargercontact?t:ac=123XYZA","industry": "Informatique","qualification": "Non cadre","jobLabels": [],"romeCodes": ["M1805"],"inclusiveEmployer": false,"adaptedCompany": false,"scrapedAt": "2026-01-15T09:00:00.000Z"}
Plan Requirement
You pay per job returned, plus a small detail-enrichment charge for each returned job whose full details were fetched (only when Fetch full job details is on; jobs dropped by a filter or suppressed as unchanged are not charged), and a one-time Actor Start charge per run. The Pricing tab shows the current rates. Use Max listings to cap the cost of any run.
The default Connection setting (Residential) works out of the box and gives the highest reliability; the actor also rotates to fresh connections automatically when one is refused. For large or frequent runs, keep Residential selected under Connection rather than switching to a narrower proxy group.
FAQ
How much does it cost?
You pay per job returned, with the optional detail-enrichment surcharge billed only when you switch on Fetch full job details. The Pricing tab shows the current rates. Use Max listings to cap the cost of any run.
Is it legal to scrape France Travail?
This actor collects only publicly available job-posting information from France Travail. You are responsible for how you use it: follow France Travail's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution.
Why isn't my location filter narrowing the results?
Location is resolved against France Travail's own autocomplete before the search runs, so a typed city or department name is normally matched to the site's own area code. When the autocomplete offers suggestions but none closely matches your text, the actor takes the site's top suggestion, as the search box would. Only when the autocomplete returns nothing at all (or the lookup fails) does the actor send your text verbatim, and France Travail then ignores an unrecognized value and returns nationwide results instead of erroring. Check the run log: it states which code and place name your location was resolved to, or that it was sent as is. Typing a precise name, or a site code such as 75D, avoids surprises.
Can I get only new or changed jobs on a schedule?
Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Each run then returns only new, updated and reappeared jobs, and unchanged ones are not billed unless you also turn on Emit unchanged.
Why did a run return zero jobs, and why did some runs fail instead?
Most rejected requests are retried automatically and simply narrow what a search returns; if every attempt for a search still fails, that search's log line says so and the run continues with the next search, so a hard connection issue usually shows up as fewer or zero jobs rather than a failed run. A run fails outright only in a few specific cases: no working connection at all could be set up, a pasted Resume run or dataset ID could not be read, or Incremental mode already has saved state for this exact search and you also passed a Resume run ID (a conflicting combination). The run's status message always explains which one applies.
Can I use it with AI agents or MCP?
Yes. Call it from any Apify integration or MCP client, and use the connector field to push results into Notion, Linear or Airtable.
🔗 Want more jobs data?
Pair this actor with these related scrapers from the same team:
| 💼 IrishJobs.ie Scraper Scrape job listings from IrishJobs.ie by keyword, location, job type, salary, recency, or... | 💼 HH.ru Jobs Scraper From $1/1K. Scrape HH.ru job listings with 50+ structured fields. Search by filters or... |
| 💼 Jora Jobs Scraper Scrape Jora.com job listings across supported countries by keyword, filters, or URL... | 💼 Jobs.cz Scrape Czech job listings from Jobs.cz. Search builder (keyword, location, field, salary... |
| 💼 Reed.co.uk Scraper Scrape Reed.co.uk jobs, companies, courses and reviews by keyword, location, filters or... | 🏷️ FINN.no Jobs Scraper Scrape active FINN.no job listings by search filters or URL. Extract 30+ fields including... |
💬 Support
- 🐞 Found a bug or a missing field? Open a ticket on the Issues tab. We usually reply within hours.
- 🛠️ Need another site, extra fields or a private build? Email contact@abotapi.com.
- ⭐ Enjoying it? A quick review on the actor page helps other users find it.