# France Jobs Scraper ($0.75/1K) (`carabain-digital/france-jobs`) Actor

Search Welcome to the Jungle and France Travail at once for offres d'emploi in France. One keyword, one dataset: merged, deduplicated across both boards, newest first. CDI, CDD, alternance. Optional full descriptions. No proxy needed. JSON, CSV or Excel.

- **URL**: https://apify.com/carabain-digital/france-jobs.md
- **Developed by:** [Carabain Digital](https://apify.com/carabain-digital) (community)
- **Categories:** Jobs, Lead generation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.45 / 1,000 job postings

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

### What is France Jobs Scraper?

**France Jobs Scraper** searches **two job boards in France with one query** (Welcome to the Jungle and France Travail) and returns one clean dataset of offres d'emploi: **merged, deduplicated across sites and sorted newest first**. CDI, CDD, alternance, stage: all contract types. Export as JSON, CSV or Excel. Costs **$0.75 per 1,000 jobs**; full descriptions are an optional add-on at $1 per 1,000. Neither site needs a proxy.

- 🌍 **2 sites, one run**: Welcome to the Jungle and France Travail are searched in parallel (about a second for 60 jobs)
- 🧹 **Cross-site dedup**: the same job on both boards (same title, company and city) appears once, with an `also_on` list of the other site
- 📅 **Newest first** across both sites, with a total **Max jobs** cap and an optional cap per site
- 🎯 **Pick the sites** you want under **Sites**
- 🛡️ **A failing site never fails the run**: it is retried, then skipped and logged; the other still delivers
- 📄 **Optional full details**: description, salary and extra fields, charged only for jobs actually enriched
- 🤖 **Agent friendly**: small flat items, one schema for both sites, works through the Apify MCP server

#### Which sites are included?

| Site | Country | Single-site Actor | Default | Notes |
|---|---|---|---|---|
| [Welcome to the Jungle](https://www.welcometothejungle.com) | France | [welcometothejungle-jobs](https://apify.com/carabain-digital/welcometothejungle-jobs) | yes | Employer-brand board (tech, startups, scale-ups), up to 10,000 jobs per search, exact publication time |
| [France Travail](https://candidat.francetravail.fr) | France | [francetravail-jobs](https://apify.com/carabain-digital/francetravail-jobs) | yes | Ex Pôle emploi, **at most 1,150 jobs per search**; about 80% of its offers are reposts from partner boards (see `origin`); `posted_at` is a day, not a time |

**Results per site are capped by each site, not by this Actor** (France Travail 1,150 per search, Welcome to the Jungle 10,000). Asking for more returns what the site offers.

#### What data can I extract?

<table>
<tr><td>🆔 Stable job ID, source site and URL</td><td>📝 Job title</td></tr>
<tr><td>🏢 Company (and company page)</td><td>📍 Location, city, postcode, department, region, country</td></tr>
<tr><td>📅 Posting date and valid-through date</td><td>🏠 Remote: onsite / hybrid / remote</td></tr>
<tr><td>💶 Salary range (when stated)</td><td>⏱️ Hours per week and employment type (CDI, CDD, alternance ...)</td></tr>
<tr><td>🎓 Education level</td><td>🔁 <code>also_on</code>: other site with the same job</td></tr>
<tr><td>📄 Full description (add-on, see below)</td><td>🔗 Apply link (where the site has one)</td></tr>
</table>

Every site fills what it has; coordinates, postcodes, skills and sectors come from some fields or the add-on only. Missing fields are `null`. Site-specific extras (`origin`, `rome_code`, `skills`, `benefits`, ...) are kept as extra fields.

#### How do I scrape French jobs?

1. [Create a free Apify account](https://console.apify.com/sign-up) and open this Actor.
2. Enter a **keyword** (for example `développeur`) and optionally a **location** and radius. Leave **Sites** on the default or pick one.
3. Set **Max jobs** and optionally **Posted in the last (days)**.
4. Switch on **Full details** if you need descriptions from both boards.
5. Click **Start** and download the jobs from the **Output** tab as JSON, CSV, Excel, XML or HTML.

### How much does it cost to scrape French job boards?

You **pay per job** that ends up in your dataset: **$0.75 per 1,000 unique jobs**, after duplicates are removed. No subscription.

- **Add-on: Full details, $1 per 1,000** jobs, **off by default**. Charged only for jobs whose detail page was actually fetched. Applies to Welcome to the Jungle and France Travail.
- The monthly credit of Apify's free plan covers thousands of jobs.
- You are charged for the jobs in the dataset, not for the (more numerous) jobs fetched before deduplication and the **Max jobs** cut. Set a maximum cost per run in the run options.

### Input

See the **Input** tab for all options. The shared fields are the same as in our single-site job Actors, except the site-specific filters (contract types, partner offers): for those use the single-site Actors.

| Field | Description |
|---|---|
| **Keyword** (`keyword`) | Job title or skill, sent to both sites, e.g. `développeur` |
| **Location** (`location`) | City, department or postcode, sent to both sites, e.g. `Lyon` |
| **Radius (km)** (`radius_km`) | Distance around the location; needs a location |
| **Posted in the last (days)** (`posted_since_days`) | Only jobs posted in the last N days |
| **Sites** (`sites`) | `welcometothejungle`, `francetravail` (default: both) |
| **Max jobs** (`limit`) | Cap on the merged dataset; every site gets a fair share |
| **Max jobs per site** (`limit_per_site`) | Optional cap per site (default: Max jobs) |
| **Full details** (`includeDetails`) | Paid add-on: detail page data |
| **Proxy** (`proxyConfiguration`) | Off by default: neither site needs one |

Example input:

```json
{
    "keyword": "développeur",
    "location": "Lyon",
    "posted_since_days": 7,
    "limit": 100
}
```

#### Location and keyword

The Actor sends your keyword and location to **both sites as is**. Use French terms (`développeur`, `infirmier`, `vendeur`, `alternance marketing`); English words such as `product manager` also work, mostly on Welcome to the Jungle.

- `posted_since_days`, `limit` and the keyword are applied the same way on both sites.
- **France Travail needs a keyword and/or a location**; without either it is skipped.
- Welcome to the Jungle never returns jobs abroad.
- If **every** selected site rejects the input, the run fails so you notice.

### Output

Jobs are stored in the default dataset, one item per unique job. Export them as JSON, CSV, Excel, XML or HTML. Every site uses the same field names (`id` is `<source>:<site id>`). Example (shortened):

```json
{
    "id": "welcometothejungle:example-slug",
    "source": "welcometothejungle",
    "url": "https://www.welcometothejungle.com/fr/companies/example/jobs/example-slug",
    "title": "Développeur Full Stack (H/F)",
    "company": "Exemple SAS",
    "location": "Lyon",
    "city": "Lyon",
    "country": "FR",
    "posted_at": "2026-10-31T08:12:00Z",
    "employment_type": ["CDI"],
    "description": null,
    "scraped_at": "2026-11-01T09:00:01Z",
    "also_on": []
}
```

(shortened; values are illustrative). `employment_type` is always a list of the site's own labels. The list is in the site's own wording: Welcome to the Jungle gives one contract label (CDI, Alternance, Stage ...), France Travail gives the contract and, when known, Temps plein or Temps partiel.

#### How duplicates are removed

Two jobs are the same when title, company and city match (ignoring case and accents) on different sites. The first one is kept (order: Welcome to the Jungle, France Travail) and the other site goes in `also_on`. Two jobs of the same site are never merged.

#### France Travail partner reposts

**About 80% of France Travail offers are republished from partner job boards** (HelloWork, Meteojob, Cadremploi and others); the `origin` field tells you which. They are real offers, but you may know them from other boards already. Filter on `origin` after the run if you only want France Travail's own offers, or use the single-site [francetravail-jobs](https://apify.com/carabain-digital/francetravail-jobs) Actor, which can leave partner offers out.

#### Sorting

With **Max jobs**, every site gets a fair share: jobs are taken in turns from each site (each in its own newest-first order). The result is then sorted newest first by `posted_at`; items without a date keep their site order. France Travail only publishes the **day** of an offer (`YYYY-MM-DD`), Welcome to the Jungle a full time, so on the same day Welcome to the Jungle jobs sort by time and France Travail ones by day.

### What can I do with French job data?

- 📈 **Labour market research**: compare demand for a role across cities and boards
- 🧲 **Recruitment and lead generation**: find companies hiring, and how many roles they have open
- 🔔 **Job alerts**: schedule a daily run with "posted in the last 1 day" and push new offres d'emploi to Slack or e-mail
- 🎓 **Alternance and student jobs**: search `alternance` plus your field
- 🤖 **AI and analysis**: feed real vacancy text into your own models

### Tips for best results

- **Each site has its own ceiling**: France Travail gives at most 1,150 jobs per search. For deeper exports, split by keyword, location or date.
- **Max jobs** keeps the newest jobs over both sites. Use **Max jobs per site** to keep the mix balanced.
- Both sites are fast: 60 jobs take about a second, and the Full details add-on adds little on top.
- For monitoring, schedule a daily run with **Posted in the last (days)** set to `1`.

### Frequently asked questions

#### Can I use France Jobs Scraper with the Apify API?

Yes. Use the [Apify API](https://docs.apify.com/api/v2) or the Apify clients. Python:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("carabain-digital/france-jobs").call(run_input={"keyword": "développeur", "location": "Lyon", "posted_since_days": 7, "limit": 100})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["source"], item["title"])
```

#### Can I use France Jobs Scraper through an MCP server or with AI agents?

Yes. Add the [Apify MCP server](https://mcp.apify.com) to your AI agent (Claude, ChatGPT, Cursor and others) and let it call `carabain-digital/france-jobs` with `call-actor`. The input is small and every field has a description, so an agent can fill it from a request such as "find 20 new développeur jobs in Lyon" (`keyword`, `location`, `limit`). A small run finishes in seconds; the agent then reads the dataset with `get-dataset-items`. Add-ons are off by default, so an agent pays only the base price unless it asks for more.

#### Can I integrate the data with other apps?

Yes: Make, Zapier, Google Sheets, Slack, Airbyte and webhooks, via Apify's [integrations](https://apify.com/integrations).

#### Why are there fewer jobs than Max jobs?

Each site returns what matches your search, duplicates across sites are removed, and a site's own ceiling applies. A narrow search can leave you with fewer.

#### Why does one site return nothing?

Either it has no match for your search, or it failed and was skipped after retries. The run log lists skipped sites. If **all** selected sites fail, the run fails so you notice. Try again later or open an issue.

#### Why do so many France Travail jobs look familiar?

About 80% of France Travail offers are partner reposts (HelloWork, Meteojob, Cadremploi ...), see the `origin` field.

#### Is it legal to scrape job boards?

The Actor only collects publicly visible job ad data. Job ads can contain personal data such as a contact name, and rules such as GDPR may apply to how you store and use it. Check your use case with a lawyer. See also [Is web scraping legal?](https://blog.apify.com/is-web-scraping-legal/)

#### France Jobs Scraper not working? / Feedback

Open an issue in the **Issues** tab of this Actor with the run link and the input you used; I usually answer within a few days.

### Other scrapers by us

The two single-site Actors behind this one are linked in the table above: [welcometothejungle-jobs](https://apify.com/carabain-digital/welcometothejungle-jobs), [francetravail-jobs](https://apify.com/carabain-digital/francetravail-jobs). They are cheaper per job when you need one site only, and have site-specific filters (contract types, partner offers).

⭐ **Does it work well for you?** A review on the Store page helps others find this Actor and helps us keep it maintained.

# Actor input Schema

## `keyword` (type: `string`):

Job title or skill, searched on both sites. French terms work best. Example: `développeur`, `infirmier` or `alternance marketing`. France Travail needs a keyword and/or a location; leave both empty only to browse all of Welcome to the Jungle.

## `location` (type: `string`):

French city, department or postcode, sent to both sites. Example: `Lyon`, `Rhône` or `69003`. Leave empty to search all of France.

## `radius_km` (type: `integer`):

Search radius around the location, in km. Example: `25`. Needs a location.

## `posted_since_days` (type: `integer`):

Only jobs posted in the last N days. Example: `7`. France Travail dates are whole days. Leave empty for all.

## `limit` (type: `integer`):

Maximum number of jobs in the dataset, newest first, after merging and removing duplicates. Example: `200`. France Travail shows at most 1,150 jobs per search; Welcome to the Jungle up to 10,000.

## `limit_per_site` (type: `integer`):

Optional. Fetch at most this many jobs from each site, so one big site cannot crowd out the rest. Example: `30`. Default: the value of Max jobs.

## `sites` (type: `array`):

Which sites to search. Default: all of them. Example: `["welcometothejungle", "francetravail"]`.

## `includeDetails` (type: `boolean`):

Open each job's detail page on Welcome to the Jungle and France Travail to add the full description, salary, skills and more. Adds $1 per 1,000 enriched jobs. Slower.

## `proxyConfiguration` (type: `object`):

Neither Welcome to the Jungle nor France Travail needs a proxy, so it is off by default. Enable one only if runs get blocked.

## Actor input object example

```json
{
  "keyword": "développeur",
  "location": "Lyon",
  "limit": 20,
  "sites": [
    "welcometothejungle",
    "francetravail"
  ],
  "includeDetails": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `jobs` (type: `string`):

All jobs from the selected sites, merged and deduplicated, newest first.

# 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 = {
    "keyword": "développeur",
    "location": "Lyon",
    "limit": 20,
    "sites": [
        "welcometothejungle",
        "francetravail"
    ],
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("carabain-digital/france-jobs").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 = {
    "keyword": "développeur",
    "location": "Lyon",
    "limit": 20,
    "sites": [
        "welcometothejungle",
        "francetravail",
    ],
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("carabain-digital/france-jobs").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 '{
  "keyword": "développeur",
  "location": "Lyon",
  "limit": 20,
  "sites": [
    "welcometothejungle",
    "francetravail"
  ],
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call carabain-digital/france-jobs --silent --output-dataset

```

## MCP server setup

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

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/OqBiTSYFqBFeUrn2h/builds/5g97lDGFVgVe0zUzm/openapi.json
