# France Travail Jobs Scraper & API: 37 Fields, Salary (`dododata/francetravail-jobs-scraper`) Actor

France Travail job offers as clean JSON: 37 fields including salary, contract and skills. Monitor returns only the offers you have not had yet. $2 per 1,000.

- **URL**: https://apify.com/dododata/francetravail-jobs-scraper.md
- **Developed by:** [Dodo Data](https://apify.com/dododata) (community)
- **Categories:** Jobs, Automation
- **Stats:** 2 total users, 1 monthly users, 94.7% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.40 / 1,000 job offers

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## France Travail Jobs Scraper & API: 37 Fields, Salary

Get job offers from [France Travail](https://candidat.francetravail.fr/offres/recherche) (formerly Pôle emploi) as clean JSON. **37 fields per offer, 500 rows in 2 to 7 minutes**, with salary as numbers, contract, skills, education and location already separated.

### What you get

The sample rows below show a plain run. A run with a **Monitor name** adds `change_status`, `first_seen_at` and `last_seen_at`, which is what takes the row to 37 fields.

Ten real rows from the run of 2026-09-17 (descriptions shortened here to 160 characters; the dataset carries them in full):

```json
[
  {
    "id": "213ZWZG",
    "title": "Conseiller(e) de vente (H/F)",
    "company": "MS MODE",
    "company_size": "6 à 9 salariés",
    "location": "08 - Charleville-Mézières",
    "department_code": "08",
    "city": "Charleville-Mézières",
    "region": "Grand Est",
    "country": "France",
    "date_posted": "2026-09-17",
    "contract_type": "CDD - 2 Mois",
    "contract_nature": "Contrat travail",
    "employment_type": "PART_TIME",
    "work_hours": "Temps partiel - 8H/semaine · Travail en journée · Travail les week-ends et jours fériés",
    "salary_min": 12.31,
    "salary_max": 12.31,
    "salary_unit": "HOUR",
    "salary_currency": "EUR",
    "salary_text": "Salaire brut : Horaire de 12.31 Euros",
    "benefits": [
      "Primes",
      "Complémentaire santé"
    ],
    "travel": "Jamais",
    "experience": [
      "1 An(s)"
    ],
    "education": [],
    "languages": [],
    "driving_licences": [],
    "skills": [
      "Organiser, aménager un espace de vente",
      "Procédures d'encaissement",
      "Présenter et valoriser un produit ou un service",
      "Techniques de mise en rayon"
    ],
    "soft_skills": [
      "Faire preuve d'autonomie",
      "Faire preuve de réactivité",
      "Avoir le sens du service"
    ],
    "qualification": "Employé non qualifié",
    "industry": "Commerce de détail d'habillement en magasin spécialisé",
    "description": "Au sein d'une boutique de prêt à porter, vos missions seront les suivantes : - Accueillir, conseiller et fidéliser notre clientèle. - Accompagner chaque clie…",
    "source": "France Travail",
    "employer_page_url": "https://recrute.francetravail.fr/page-employeur/msfr-554",
    "url": "https://candidat.francetravail.fr/offres/recherche/detail/213ZWZG",
    "scraped_at": "2026-09-17T12:53:01.377Z"
  },
  {
    "id": "213ZWZB",
    "title": "Technicien itinérant / Technicienne itinérante de maintenance ind (H/F)",
    "company": "ENERIA",
    "company_size": "250 à 499 salariés",
    "location": "13 - Meyreuil",
    "department_code": "13",
    "city": "Meyreuil",
    "region": "Provence-Alpes-Côte d'Azur",
    "country": "France",
    "date_posted": "2026-09-17",
    "contract_type": "CDI",
    "contract_nature": "Contrat travail",
    "employment_type": "FULL_TIME",
    "work_hours": "40H/semaine · Travail en astreinte · Travail en journée · Horaires annuels · Travail durant les vacances scolaires",
    "salary_min": 27000,
    "salary_max": 35000,
    "salary_unit": "YEAR",
    "salary_currency": "EUR",
    "salary_text": "Salaire brut : Annuel de 27000.0 Euros à 35000.0 Euros",
    "benefits": [
      "Primes",
      "Véhicule",
      "Titres restaurant / Prime de panier",
      "CSE",
      "Ordinateur portable"
    ],
    "travel": "Quotidiens Zone départementale",
    "experience": [
      "3 An(s)"
    ],
    "education": [],
    "languages": [],
    "driving_licences": [
      "B - Véhicule léger"
    ],
    "skills": [
      "mécanique",
      "Permis B"
    ],
    "soft_skills": [
      "Avoir l'esprit d'équipe",
      "Faire preuve de persévérance",
      "Faire preuve d'autonomie"
    ],
    "qualification": "Technicien",
    "industry": "Commerce de gros (commerce interentreprises) de fournitures et équipements industriels divers",
    "description": "Rejoignez Eneria, le spécialiste des solutions de motorisation Caterpillar, et participez à la maintenance des moteurs qui équipent les navires professionnel…",
    "source": "France Travail",
    "employer_page_url": "https://recrute.francetravail.fr/page-employeur/eneria-126",
    "url": "https://candidat.francetravail.fr/offres/recherche/detail/213ZWZB",
    "scraped_at": "2026-09-17T12:53:01.411Z"
  },
  {
    "id": "213ZWZD",
    "title": "Charpentier H/F/X",
    "company": "BPS INTERIM SAISONNIER",
    "company_size": "20 à 49 salariés",
    "location": "40 - Parentis-en-Born",
    "department_code": "40",
    "city": "Parentis-en-Born",
    "region": "Nouvelle-Aquitaine",
    "country": "France",
    "date_posted": "2026-09-17",
    "contract_type": "Intérim - 2 Mois",
    "contract_nature": "Contrat travail",
    "employment_type": "FULL_TIME",
    "work_hours": "35H/semaine · Travail en journée",
    "salary_min": 12.31,
    "salary_max": 12.31,
    "salary_unit": "HOUR",
    "salary_currency": "EUR",
    "salary_text": "Salaire brut : Horaire de 12.31 Euros à 12.31 Euros",
    "benefits": [],
    "travel": null,
    "experience": [
      "3 An(s)"
    ],
    "education": [],
    "languages": [],
    "driving_licences": [],
    "skills": [
      "appros",
      "contrat",
      "préfabrication",
      "études"
    ],
    "soft_skills": [],
    "qualification": "Employé qualifié",
    "industry": "Activités des agences de travail temporaire",
    "description": "Vous intégrerez une équipe qualifiée et participerez à la réalisation de travaux de charpente et de couverture sur différents bâtiments et villas. Vos missio…",
    "source": "France Travail",
    "employer_page_url": "https://recrute.francetravail.fr/page-employeur/bps-interim-hossegor-232",
    "url": "https://candidat.francetravail.fr/offres/recherche/detail/213ZWZD",
    "scraped_at": "2026-09-17T12:53:01.566Z"
  },
  {
    "id": "213ZWZH",
    "title": "Auxiliaire de vie - Rillieux - Temps plein ou partiel (H/F)",
    "company": "AGE ET PERSPECTIVES",
    "company_size": "50 à 99 salariés",
    "location": "69 - Rillieux-la-Pape",
    "department_code": "69",
    "city": "Rillieux-la-Pape",
    "region": "Auvergne-Rhône-Alpes",
    "country": "France",
    "date_posted": "2026-09-17",
    "contract_type": "CDI",
    "contract_nature": "Contrat travail",
    "employment_type": "FULL_TIME",
    "work_hours": "35H/semaine · Travail en journée",
    "salary_min": 12.31,
    "salary_max": 12.42,
    "salary_unit": "HOUR",
    "salary_currency": "EUR",
    "salary_text": "Salaire brut : Horaire de 12.31 Euros à 12.42 Euros",
    "benefits": [
      "Titres restaurant / Prime de panier",
      "Complémentaire santé"
    ],
    "travel": null,
    "experience": [
      "Débutant accepté"
    ],
    "education": [],
    "languages": [],
    "driving_licences": [],
    "skills": [
      "Effectuer les courses d'une personne",
      "Normes d'hygiène et de propreté"
    ],
    "soft_skills": [
      "Etre à l'écoute, faire preuve d'empathie",
      "Organiser son travail selon les priorités et les objectifs",
      "Avoir le sens du service"
    ],
    "qualification": "Employé non qualifié",
    "industry": "Aide à domicile",
    "description": "Nous venons de recruter mais nous renforçons encore l'équipe ! Les métiers à vocation humaine vous attirent ? Vous souhaitez vous rendre utile auprès de pers…",
    "source": "France Travail",
    "employer_page_url": null,
    "url": "https://candidat.francetravail.fr/offres/recherche/detail/213ZWZH",
    "scraped_at": "2026-09-17T12:53:01.765Z"
  },
  {
    "id": "213ZWYT",
    "title": "Enseignant Anglais (H/F)-Collège Jules Ferry/Le Thillot/88-L0422",
    "company": "RECTORAT DE L'ACADEMIE DE NANCY-METZ",
    "company_size": "10 000 salariés et plus",
    "location": "88 - Vosges",
    "department_code": "88",
    "city": null,
    "region": "Grand Est",
    "country": "France",
    "date_posted": "2026-09-17",
    "contract_type": "CDD - 1 Mois",
    "contract_nature": "Contrat travail",
    "employment_type": "PART_TIME",
    "work_hours": "Temps partiel - 15H/semaine · Travail en journée",
    "salary_min": 1787,
    "salary_max": 1787,
    "salary_unit": "MONTH",
    "salary_currency": "EUR",
    "salary_text": "Salaire brut : Mensuel de 1787.0 Euros",
    "benefits": [],
    "travel": null,
    "experience": [
      "Débutant accepté"
    ],
    "education": [
      "Bac+3, Bac+4 ou équivalents Langues"
    ],
    "languages": [
      "Français",
      "Anglais"
    ],
    "driving_licences": [],
    "skills": [],
    "soft_skills": [],
    "qualification": "Cadre",
    "industry": "Administration publique (tutelle) de la santé, de la formation, de la culture et des services sociaux, autre que sécurité sociale",
    "description": "L'Académie de Nancy-Metz recrute une enseignante ou un enseignant contractuel en Anglais. Le poste de remplacement à pourvoir : Contrat de ce jour jusqu'au 1…",
    "source": "France Travail",
    "employer_page_url": "https://recrute.francetravail.fr/page-employeur/rectorat-de-l-academie-de-nancy-metz-201",
    "url": "https://candidat.francetravail.fr/offres/recherche/detail/213ZWYT",
    "scraped_at": "2026-09-17T12:53:02.749Z"
  },
  {
    "id": "213ZXGK",
    "title": "Technicien SSI Itinérant (H/F)",
    "company": "TIM",
    "company_size": "20 à 49 salariés",
    "location": "77 - ST THIBAULT DES VIGNES",
    "department_code": "77",
    "city": "Saint-Thibault-des-Vignes",
    "region": "Île-de-France",
    "country": "France",
    "date_posted": "2026-09-17",
    "contract_type": "Intérim - 4 Mois",
    "contract_nature": "Contrat travail",
    "employment_type": "FULL_TIME",
    "work_hours": "37H30/semaine · Travail en journée",
    "salary_min": 2100,
    "salary_max": 2350,
    "salary_unit": "MONTH",
    "salary_currency": "EUR",
    "salary_text": "Salaire brut : Mensuel de 2100.0 Euros à 2350.0 Euros",
    "benefits": [
      "Titres restaurant / Prime de panier",
      "Véhicule",
      "Primes"
    ],
    "travel": "Quotidiens Zone régionale",
    "experience": [
      "1 An(s)"
    ],
    "education": [
      "CAP, BEP et équivalents"
    ],
    "languages": [],
    "driving_licences": [
      "B - Véhicule léger"
    ],
    "skills": [
      "Connecter une boîte de raccordements",
      "Installer l'équipement sur le site et le connecter aux réseaux extérieurs"
    ],
    "soft_skills": [
      "Faire preuve de rigueur et de précision",
      "Faire preuve d'autonomie",
      "Etre ouvert aux changements"
    ],
    "qualification": "Technicien",
    "industry": "Activités des agences de travail temporaire",
    "description": "En tant que technicien vérificateur (H/F/D), vous intervenez sur l'installation, la maintenance, la vérification et le remplacement des systèmes de sécurité…",
    "source": "France Travail",
    "employer_page_url": null,
    "url": "https://candidat.francetravail.fr/offres/recherche/detail/213ZXGK",
    "scraped_at": "2026-09-17T12:53:03.868Z"
  },
  {
    "id": "213ZWYG",
    "title": "Agent de maîtrise - Photographe (H/F)",
    "company": "PSVP",
    "company_size": "6 à 9 salariés",
    "location": "57 - Hattigny",
    "department_code": "57",
    "city": "Hattigny",
    "region": "Grand Est",
    "country": "France",
    "date_posted": "2026-09-17",
    "contract_type": "CDI",
    "contract_nature": "Contrat travail",
    "employment_type": "FULL_TIME",
    "work_hours": "35H/semaine · Travail en journée · Travail les week-ends et jours fériés",
    "salary_min": 2000,
    "salary_max": 2500,
    "salary_unit": "MONTH",
    "salary_currency": "EUR",
    "salary_text": "Salaire brut : Mensuel de 2000.0 Euros à 2500.0 Euros - En fonction de l'expérience",
    "benefits": [
      "Primes",
      "Restauration",
      "En fonction de l'expérience"
    ],
    "travel": "Jamais",
    "experience": [
      "6 Mois"
    ],
    "education": [],
    "languages": [
      "Anglais",
      "Français"
    ],
    "driving_licences": [],
    "skills": [
      "Préparer une prise de vue",
      "Réaliser des prises de vues photographiques",
      "Encadrer",
      "Manager"
    ],
    "soft_skills": [
      "Etre force de proposition",
      "Faire preuve d'autonomie",
      "Faire preuve de leadership"
    ],
    "qualification": "Agent de maîtrise",
    "industry": "Activités photographiques",
    "description": "Nous recherchons notre futur(e) Agent de Maîtrise pour piloter notre activité photo au sein du Center Parcs de Hattigny. Vous aimez le terrain, le contact cl…",
    "source": "France Travail",
    "employer_page_url": "https://recrute.francetravail.fr/page-employeur/psvp-881",
    "url": "https://candidat.francetravail.fr/offres/recherche/detail/213ZWYG",
    "scraped_at": "2026-09-17T12:53:05.487Z"
  },
  {
    "id": "213ZXFV",
    "title": "Approvisionneur (F/H)",
    "company": "RANDSTAD",
    "company_size": "50 à 99 salariés",
    "location": "37 - Saint-Cyr-sur-Loire",
    "department_code": "37",
    "city": "Saint-Cyr-sur-Loire",
    "region": "Centre-Val de Loire",
    "country": "France",
    "date_posted": "2026-09-17",
    "contract_type": "Intérim - 6 Mois",
    "contract_nature": "Contrat travail",
    "employment_type": "FULL_TIME",
    "work_hours": "39H/semaine · Travail en journée",
    "salary_min": 26000,
    "salary_max": 26000,
    "salary_unit": "YEAR",
    "salary_currency": "EUR",
    "salary_text": "Salaire brut : Annuel de 26000.0 Euros",
    "benefits": [],
    "travel": null,
    "experience": [
      "3 An(s)"
    ],
    "education": [
      "Bac ou équivalent Approvisionnement"
    ],
    "languages": [],
    "driving_licences": [],
    "skills": [],
    "soft_skills": [],
    "qualification": "Employé qualifié",
    "industry": "Activités des agences de travail temporaire",
    "description": "Souhaitez-vous optimiser les flux d'approvisionnement en tant qu'Approvisionneur (F/H) ? Vous assurerez l'approvisionnement des matériels, services et sous-t…",
    "source": "France Travail",
    "employer_page_url": "https://recrute.francetravail.fr/page-employeur/randstad-939",
    "url": "https://candidat.francetravail.fr/offres/recherche/detail/213ZXFV",
    "scraped_at": "2026-09-17T12:53:11.967Z"
  },
  {
    "id": "213ZXCN",
    "title": "Gestionnaire financier (H/F)",
    "company": "UNIVERSITE PARIS CITE",
    "company_size": "10 000 salariés et plus",
    "location": "75 - PARIS 06",
    "department_code": "75",
    "city": "Paris",
    "region": "Île-de-France",
    "country": "France",
    "date_posted": "2026-09-17",
    "contract_type": "CDD - 12 Mois",
    "contract_nature": "Contrat travail",
    "employment_type": "FULL_TIME",
    "work_hours": "37H30/semaine · Travail en journée",
    "salary_min": 25000,
    "salary_max": 32000,
    "salary_unit": "YEAR",
    "salary_currency": "EUR",
    "salary_text": "Salaire brut : Annuel de 25000.0 Euros à 32000.0 Euros",
    "benefits": [
      "Complémentaire santé",
      "CSE"
    ],
    "travel": null,
    "experience": [
      "2 An(s)"
    ],
    "education": [],
    "languages": [],
    "driving_licences": [],
    "skills": [
      "Elaborer, suivre et piloter un budget",
      "Fiscalité",
      "Superviser la gestion financière"
    ],
    "soft_skills": [],
    "qualification": "Cadre",
    "industry": "Enseignement supérieur",
    "description": "Ref UPC poste 20348 RÉSUMÉ DU POSTE - Gestion financière et comptable du laboratoire et appui administratif aux activités de recherche en assurant l'interfac…",
    "source": "France Travail",
    "employer_page_url": null,
    "url": "https://candidat.francetravail.fr/offres/recherche/detail/213ZXCN",
    "scraped_at": "2026-09-17T12:53:21.973Z"
  },
  {
    "id": "213ZWKQ",
    "title": "Conseiller/conseillère en location saisonnière polyvalente (H/F)",
    "company": "SQUARE HABITAT",
    "company_size": "1 ou 2 salariés",
    "location": "64 - Station de ski de Gourette",
    "department_code": "64",
    "city": "Eaux-Bonnes",
    "region": "Nouvelle-Aquitaine",
    "country": "France",
    "date_posted": "2026-09-17",
    "contract_type": "Saisonnier - 5 Mois",
    "contract_nature": "Contrat travail",
    "employment_type": "FULL_TIME",
    "work_hours": "35H/semaine · Travail le samedi",
    "salary_min": 1867.02,
    "salary_max": 1867.02,
    "salary_unit": "MONTH",
    "salary_currency": "EUR",
    "salary_text": "Salaire brut : Mensuel de 1867.02 Euros - +13e mois",
    "benefits": [
      "+13e mois"
    ],
    "travel": null,
    "experience": [
      "4 Mois - Ouvert aux débutants"
    ],
    "education": [],
    "languages": [
      "Espagnol"
    ],
    "driving_licences": [
      "B - Véhicule léger"
    ],
    "skills": [
      "Actualiser l'affichage, les informations mises à la disposition d'un public",
      "Espagnol",
      "Etablir un bail immobilier",
      "Gérer des réclamations et litiges",
      "Gérer la trésorerie, le recouvrement",
      "Maitrise outil informatique",
      "Recouvrement des loyers et charges"
    ],
    "soft_skills": [],
    "qualification": "Employé qualifié",
    "industry": "Agences immobilières",
    "description": "*** Prise de poste au 1er novembre 2026 jusqu'au 31 mars 2027 *** **Poste NON LOGE** Après une période de formation ,en binôme au poste de travail, vous sere…",
    "source": "France Travail",
    "employer_page_url": "https://recrute.francetravail.fr/page-employeur/pg-immo-333",
    "url": "https://candidat.francetravail.fr/offres/recherche/detail/213ZWKQ",
    "scraped_at": "2026-09-17T12:53:55.776Z"
  }
]
```

In that run 402 of 500 offers (80%) carried a salary figure, parsed into `salary_min`, `salary_max` and `salary_unit` (HOUR, MONTH or YEAR).

### What people use it for

- **Track salary bands by job and département**. For example, "median hourly rate for home-care assistants in the Rhône versus the Nord, week by week".
- **Feed a job board, a newsletter or an AI agent with fresh French offers**. For example, "every CDI posted in Gironde since yesterday, with skills and contract type as fields rather than prose".
- **Watch who is hiring**. For example, "which employers and temp agencies posted the most offers in Île-de-France this month, and in which sectors".

### Why not build it yourself

Building this yourself: about 10 hours to handle the listing pagination, the offer-page microdata, the salary formats and the empty-page traps, and then it breaks the next time France Travail changes its layout. This Actor: **$2.00 per 1,000 rows**, and when the site changes we fix it within 48 hours. Every Apify account includes $5 of free usage a month, so your first 2,500 rows cost nothing.

**Founding price:** $2.00 per 1,000 rows for the first 100 users. It then rises to $3.00. Users who joined at the founding price keep it.

### Proof

| | |
|---|---|
| Success rate (staging runs on Apify, 17 to 18 Sept 2026) | 100% from 6 runs, 3,036 requests, 0 failed attempts |
| Last verified against the live site | 2026-09-18 |
| Typical run | 500 rows in 2 to 7 minutes (measured 2 min 17 s to 6 min 45 s) |
| Issues answered within | 6 hours |
| Site changes fixed within | 48 hours |

Changelog at the bottom of this page, and every fix is dated.

### Monitoring: only the offers you have not had yet

A daily run on a busy search returns mostly the same offers as yesterday. Give the run a **Monitor name** and turn **Only changes** on:

- an offer already returned by an earlier run under that name is recognised **on the listing page**: its page is not opened again and it is **not billed again**
- every row carries `change_status` (`new`, or `updated` when the offer's title changed) and `first_seen_at`
- measured: two runs of 25 rows a minute apart returned 50 different offers, the second run skipping the 25 the first had delivered

France Travail never lists a search to its end (about 1,100 results deep), so this Actor never claims that an offer was withdrawn: absence from a listing proves nothing here. State is kept in a key-value store on your own Apify account, one per Actor (the same name in another Dodo Data Actor tracks that Actor's sources separately); an offer no run has seen for 45 days is forgotten so the state stays small.

### What we deliberately do not collect

- No personal data. The offer pages carry recruiter e-mail and phone fields: the parser never reads them. E-mail addresses and phone numbers written inside descriptions are replaced with `[email removed]` / `[phone removed]`. When a small employer's name reads as a private person's (sole traders and households post under their own name), `company` is left empty and the offer is kept.
- Public pages only. No logins, no candidate area.
- The site's `robots.txt` is followed. It disallows keyword-search URLs (`motsCles=`), so this Actor never requests them. The **Title keywords** input does the job instead: it reads the normal listing pages and keeps only matching titles before any offer page is opened.
- Rate-limited: at most 5 requests a second, 100 offers per listing request to keep the request count low.
- This Actor declares **limited permissions**: it can only write to its own dataset.

### How to run it

1. Click **Run**. The defaults return the 500 newest offers published by France Travail itself, all of France.
2. Or go to [candidat.francetravail.fr/offres/recherche](https://candidat.francetravail.fr/offres/recherche), set your filters (place, contract type, publication date), and paste the page URL into **Start URLs**. Several URLs are fine, one per département for example.
3. Add `offresPartenaires=true` to a URL to include offers syndicated from partner job boards; the `source` field tells you where each offer came from. Partner offers usually carry fewer fields.
4. Add **Title keywords** (e.g. `développeur`, `infirmier`) to keep only offers whose title contains one of them. Accents and case are ignored, up to 10,000 offers are checked per run (the newest of every département first), and you pay only for the rows that match.
5. Set **Max rows** to cap the run. That is also your spend cap.
6. Download as JSON, CSV or Excel, or call it from the API or from an AI agent through the Apify MCP server.

France Travail shows at most about 1,100 offers per search. For all-of-France runs above 1,000 rows, or with keywords, the Actor splits the search by département automatically (rows then arrive département by département); for your own URLs, narrow by place or date to stay under that depth.

Useful URL parameters: `lieux=75D` (département), `lieux=11R` (region), `lieux=01P` (all of France), `typeContrat=CDI`, `emission=1` (published in the last day; `7` and `31` also work), `tri=1` (newest first).

### Use it from an AI agent (MCP)

Add this Actor as a tool in Claude, Cursor, VS Code or any other MCP client through the hosted Apify MCP server:

```text
https://mcp.apify.com/?tools=actors,docs,dododata/francetravail-jobs-scraper
```

The input is small and typed, and every field in the output is documented in the dataset schema, so an agent can call it without reading this page. The Actor is enabled for Apify's agentic payments ([x402](https://docs.apify.com/platform/integrations/x402), experimental on Apify's side): an agent can pay per run without an Apify account. With a **Monitor name**, an agent that checks a French job search every morning pays only for what changed.

### Input reference

| Field | Default | Meaning |
|---|---|---|
| `startUrls` | all of France, France Travail's own offers, newest first | Search pages (or single offer pages) to start from |
| `keywords` | none | Keep only offers whose title contains one of these words |
| `monitorName` | none | Turns on tracking between runs; use the same name every run |
| `onlyChanges` | false | With a monitor name: skip, and do not bill, offers an earlier run already returned |
| `maxItems` | 500 | Stop after this many rows |
| `maxConcurrency` | 5 | Parallel requests |
| `useProxy` | true | Use Apify proxy (recommended) |

### FAQ

**Does France Travail have an API for job offers?**
France Travail runs an official API programme for registered partners. This Actor needs no registration: it reads the public offer pages, which carry a schema.org JobPosting block, at a polite rate, and respects the site's robots.txt (keyword-search URLs are disallowed there, so keywords are matched on listing titles instead).

**How do I get only today's new offers?**
Schedule the Actor daily with a **Monitor name** and **Only changes**. Offers you already received are skipped before their page is opened.

**Does it collect recruiter names, e-mails or phone numbers?**
No. Those fields are never read, contact details inside descriptions are replaced, and an employer name that looks like a private person is dropped.

**How fresh is the data?**
Every run is live, newest offers first.

### Changelog

- 2026-09-21: monitoring. A monitor name adds `change_status`, `first_seen_at`, `last_seen_at`; **Only changes** skips offers an earlier run already returned, before their page is opened.
- 2026-09-17, v0.1: first release, with title keywords and automatic split by département. Verified against the live site on 17 and 18 September 2026.

# Actor input Schema

## `startUrls` (type: `array`):

Search pages from candidat.francetravail.fr/offres/recherche. Set your filters on the site (place, contract type, date) and paste the URL. Leave empty for all of France, newest first. Keyword URLs (motsCles=) are not crawled because the site's robots.txt disallows them: the keyword is dropped and the other filters are kept.

## `keywords` (type: `array`):

Keep only offers whose title contains one of these words (accents and case ignored), e.g. développeur, infirmier. Filtering happens on the listing pages, before any offer is opened, so you pay only for matching rows. Up to 100 listing pages (10,000 offers, the newest of every département first) are checked per run.

## `monitorName` (type: `string`):

Turns on tracking between runs. Pick any name, for example offres-paris, and use the same name on every run. Each offer then says whether it is new since the previous run under that name, with the date it was first seen. The first run marks everything as new. State is kept in a key-value store on your own account. Leave empty to switch tracking off.

## `onlyChanges` (type: `boolean`):

Needs a monitor name. Offers already returned by an earlier run under that name are skipped before their page is opened: not requested, not billed. A daily run on a busy search returns the day's new offers instead of the same 1,000 again.

## `maxItems` (type: `integer`):

Stop after this many job offers. You pay per row, so this is also your budget cap. The form starts at 100 so a first run finishes in about a minute; raise it for a full pull.

## `maxConcurrency` (type: `integer`):

Parallel requests. 5 is polite and fast enough for most sites.

## `useProxy` (type: `boolean`):

Recommended. Turn off only for testing.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://candidat.francetravail.fr/offres/recherche?lieux=01P&offresPartenaires=false&tri=1"
    }
  ],
  "keywords": [],
  "onlyChanges": false,
  "maxItems": 100,
  "maxConcurrency": 5,
  "useProxy": true
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "startUrls": [
        {
            "url": "https://candidat.francetravail.fr/offres/recherche?lieux=01P&offresPartenaires=false&tri=1"
        }
    ],
    "keywords": [],
    "maxItems": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("dododata/francetravail-jobs-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "startUrls": [{ "url": "https://candidat.francetravail.fr/offres/recherche?lieux=01P&offresPartenaires=false&tri=1" }],
    "keywords": [],
    "maxItems": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("dododata/francetravail-jobs-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "startUrls": [
    {
      "url": "https://candidat.francetravail.fr/offres/recherche?lieux=01P&offresPartenaires=false&tri=1"
    }
  ],
  "keywords": [],
  "maxItems": 100
}' |
apify call dododata/francetravail-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,dododata/francetravail-jobs-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/BVqu1AiKqKPFJYjfT/builds/fCIUCpa16T0goHSay/openapi.json
