# France Travail Scraper — French National Job Listings (`studio-amba/francetravail-scraper`) Actor

Scrape job listings from francetravail.fr (ex-Pole Emploi) — France's national public job service. Get titles, companies, locations, contract types, and salaries when available across every French region.

- **URL**: https://apify.com/studio-amba/francetravail-scraper.md
- **Developed by:** [Studio Amba](https://apify.com/studio-amba) (community)
- **Categories:** Jobs
- **Stats:** 2 total users, 1 monthly users, 50.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 result scrapeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## France Travail Scraper

Scrape job listings from francetravail.fr — France's national public job service (formerly Pole Emploi), the largest job board in France. No login or cookies required.

### How to scrape France Travail data

1. Go to the [France Travail Scraper](https://apify.com/studio-amba/francetravail-scraper) page on Apify Store.
2. Click "Try for free" to open the actor in Apify Console.
3. Set your search query (French keyword, e.g. `developpeur`, `comptable`, `infirmier`).
4. Optionally narrow to one department (e.g. `75` for Paris) and turn on Fetch Full Details for the complete job description and structured salary.
5. Click "Start" and wait for the run to complete.
6. Download your data as JSON, CSV, or Excel from the Dataset tab.

You can also call this actor via the [Apify API](https://docs.apify.com/api/v2) to integrate France Travail job data into your own applications and workflows.

### Why use this actor?

France Travail is the French state employment agency and runs the country's largest public job board — every registered employer in France is required to post openings there, which means far better structural completeness (salary, contract type, working hours) than most commercial job boards. HR tech companies, recruitment agencies, labor market researchers, and job aggregators use this data to track hiring demand, benchmark salaries, and build France-wide job feeds.

This actor reads the public, server-rendered candidat.francetravail.fr search — no JavaScript rendering needed, just plain HTTP with CheerioCrawler. France Travail also runs an official OAuth2 API (francetravail.io), but it requires every user to register their own client_id/client_secret — this actor uses the public website instead so there is no signup friction.

### Input

| Field | Type | Required | Description |
|-------|------|----------|--------------|
| `searchQuery` | String | No | Search keyword in French (e.g. `developpeur`, `comptable`). Default: `développeur` |
| `department` | String | No | French department code (e.g. `75`, `69`) to narrow results to one region |
| `fetchDetails` | Boolean | No | Visit each job's detail page for the full description and structured salary. Default: `false` |
| `maxResults` | Integer | No | Maximum number of job listings to return (default: 100) |
| `proxyConfiguration` | Object | No | Proxy settings (default Apify proxy works reliably — no anti-bot on this site) |

#### Segmenting by department

France Travail caps each search query at roughly 1,000 results (pagination stops returning new items past that depth). For broad keywords with more openings than that, run the actor multiple times with different `department` codes (e.g. `75`, `69`, `13`, `33`...) to cover the whole country. Department codes follow the standard French INSEE numbering (01–95, plus overseas departments).

#### Fetch Full Details

By default the actor reads only the search results list, which already includes title, company, location, contract type, and a description snippet. Turning on `fetchDetails` visits each job's individual page to pull the complete job description and, when the employer discloses it, a structured salary range parsed from the page's schema.org `JobPosting` microdata. This roughly doubles the number of requests per run (one extra request per job), so large runs with `fetchDetails` on take proportionally longer.

### Output

Each result contains:

| Field | Type | Example |
|-------|------|---------|
| `title` | String | `"Développeur Informatique (H/F)"` |
| `company` | String | `"BRETAGNE SERVICES LOGISTIQUES"` |
| `location` | String | `"35 - BAIN DE BRETAGNE"` |
| `contractType` | String | `"CDD - Temps plein"` |
| `salary` | String | `"3250 - 3500 EUR MONTH"` (only when disclosed) |
| `postedDate` | String | `"Publié il y a 3 jours"` or `"2026-07-10"` with Fetch Full Details |
| `url` | String | Full job listing URL on France Travail |
| `description` | String | Job description (snippet, or full text with Fetch Full Details) |
| `scrapedAt` | String | `"2026-07-13T00:24:55.196Z"` |

### Example output

```json
{
    "title": "Comptable Gestionnaire de paie (H/F)",
    "company": "LYCEE DE BONNEFONT",
    "location": "65 - Bagneres de Bigorre",
    "contractType": "CDI - Temps plein",
    "salary": "1900 - 2300 EUR MONTH",
    "postedDate": "2026-07-09",
    "url": "https://candidat.francetravail.fr/offres/recherche/detail/211CNHZ",
    "description": "Le Lycee de Bonnefont propose un poste a 100% de secretaire comptable et gestion administrative...",
    "scrapedAt": "2026-07-13T00:28:50.993Z"
}
````

### Cost estimate

This actor uses CheerioCrawler (HTTP-only, no browser), making it very cheap to run. Expect approximately **0.5-1 compute units per 100 results** without Fetch Full Details, roughly double that with details on (one extra request per job).

### Tips for best results

- **Use native French keywords** — France Travail is a French site. Search for `developpeur` or `comptable`, not `developer` or `accountant`.
- **Segment by department for large keywords** — the site caps each query around 1,000 results; use the `department` input to cover more ground across multiple runs.
- **Turn on Fetch Full Details for salary data** — list-page cards rarely show pay; salary only appears via the detail page's structured JobPosting microdata.
- **Empty input works** — running with no input at all defaults to searching `développeur` nationwide.

### Limitations

- Data is scraped from the public website and may change without notice if France Travail updates their page structure.
- Salary is only present on the source page when the employer chose to disclose it — most listings omit it, which is normal for the French market, not a scraping gap.
- The public search caps results at roughly 1,000 per query; use department segmentation for full national coverage of broad keywords.
- The official francetravail.io OAuth2 API (which some listings partner data flows through) requires per-user credentials and is not used by this actor — see the site's own developer portal if you need that path instead.

### Use cases

- **Labor market research** — track hiring demand and contract-type mix (CDI vs CDD vs interim) across French regions.
- **Salary benchmarking** — aggregate disclosed salary ranges by role and department.
- **Recruitment agency sourcing** — feed France's largest public job board into a candidate-matching pipeline.
- **Job aggregator feeds** — combine France Travail postings with commercial boards for a complete France-wide job feed.
- **Regional economic monitoring** — compare job posting volume and sector mix department by department.

### Related scrapers

This actor is part of Studio Amba's European jobs fleet. Also see:

- **HelloWork Scraper** — hellowork.com, France's leading commercial job board
- **APEC Scraper** — apec.fr, France's executive/management job board

### Support

Hit a bug or a missing field? Open an issue on the Actor page — we respond fast and ship fixes within 24 hours. Every published scraper in the Studio Amba catalog is monitored daily; broken runs trigger an automatic heal cycle.

# Actor input Schema

## `searchQuery` (type: `string`):

Search for jobs by keyword in French (e.g., 'developpeur', 'comptable', 'infirmier').

## `department` (type: `string`):

Optional French department code to narrow results to one region (e.g., '75' for Paris, '69' for Rhone). France Travail caps each query at ~1,000 results — segment by department to get full national coverage across multiple runs.

## `fetchDetails` (type: `boolean`):

Visit each job's detail page for the full description and structured salary (schema.org JobPosting microdata). Roughly doubles the number of requests per run — leave off for fast list-only scraping.

## `maxResults` (type: `integer`):

Maximum number of job listings to return.

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

Proxy settings. France Travail's public search has no anti-bot protection, so the default Apify proxy works reliably.

## Actor input object example

```json
{
  "searchQuery": "développeur",
  "fetchDetails": false,
  "maxResults": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# 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 = {
    "searchQuery": "développeur",
    "maxResults": 20,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("studio-amba/francetravail-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 = {
    "searchQuery": "développeur",
    "maxResults": 20,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

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

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

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

```

## CLI example

```bash
echo '{
  "searchQuery": "développeur",
  "maxResults": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call studio-amba/francetravail-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=studio-amba/francetravail-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "France Travail Scraper — French National Job Listings",
        "description": "Scrape job listings from francetravail.fr (ex-Pole Emploi) — France's national public job service. Get titles, companies, locations, contract types, and salaries when available across every French region.",
        "version": "0.1",
        "x-build-id": "kL1KjEGGZ7hRofgAY"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/studio-amba~francetravail-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-studio-amba-francetravail-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/studio-amba~francetravail-scraper/runs": {
            "post": {
                "operationId": "runs-sync-studio-amba-francetravail-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/studio-amba~francetravail-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-studio-amba-francetravail-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "searchQuery": {
                        "title": "Search Query",
                        "type": "string",
                        "description": "Search for jobs by keyword in French (e.g., 'developpeur', 'comptable', 'infirmier')."
                    },
                    "department": {
                        "title": "Department Code",
                        "type": "string",
                        "description": "Optional French department code to narrow results to one region (e.g., '75' for Paris, '69' for Rhone). France Travail caps each query at ~1,000 results — segment by department to get full national coverage across multiple runs."
                    },
                    "fetchDetails": {
                        "title": "Fetch Full Details",
                        "type": "boolean",
                        "description": "Visit each job's detail page for the full description and structured salary (schema.org JobPosting microdata). Roughly doubles the number of requests per run — leave off for fast list-only scraping.",
                        "default": false
                    },
                    "maxResults": {
                        "title": "Max Results",
                        "minimum": 1,
                        "maximum": 5000,
                        "type": "integer",
                        "description": "Maximum number of job listings to return.",
                        "default": 100
                    },
                    "proxyConfiguration": {
                        "title": "Proxy Configuration",
                        "type": "object",
                        "description": "Proxy settings. France Travail's public search has no anti-bot protection, so the default Apify proxy works reliably."
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
