# FranceTravail.fr France Travail Scraper (`unfenced-group/france-travail-scraper`) Actor

Scrape francetravail.fr — France's official government job board with 450,000+ listings. Structured output: title, company, salary, GPS coordinates, ROME occupational codes & full descriptions in HTML, text and Markdown. Contract type & location filters. No API key required.

- **URL**: https://apify.com/unfenced-group/france-travail-scraper.md
- **Developed by:** [Unfenced Group](https://apify.com/unfenced-group) (community)
- **Categories:** Jobs, Automation, Developer tools
- **Stats:** 4 total users, 3 monthly users, 90.3% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 results

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 a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.md):

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

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.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/platform/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

Extract structured job listings from **francetravail.fr** (formerly Pôle Emploi) — France's national employment platform with over 900,000 active listings across all sectors and regions. No API key required. Search by city name (e.g. "Paris", "Lyon") with an optional radius, or filter by department, region, contract type, and experience.

![France Travail Scraper](https://i.imgur.com/X0oMgIn.png)

---

### Why use this scraper?

| Feature | Details |
|---|---|
| **Scale** | 900,000+ active listings across all French departments and regions |
| **Rich data** | Title, company, salary range, location with GPS coordinates, full job description in HTML, plain text and Markdown |
| **Precise filtering** | City name + radius, keywords, departments, regions, contract type (CDI/CDD/Intérim), experience level, full-time/part-time, telework, alternance |
| **Deduplication** | Cross-run repost detection with a 90-day fingerprint window — incremental pipelines only receive new listings |
| **Three description formats** | HTML, plain text and Markdown — ready for any downstream processing or storage |
| **Labour market intelligence** | ROME occupation codes, sector codes, GPS coordinates, salary data and experience requirements for every listing |

---

### Input parameters

| Parameter | Type | Default | Description |
|---|---|---|---|
| `keywords` | String | `""` | Job title, skill, or sector keywords |
| `city` | String | `""` | City name to search in (e.g. `"Paris"`, `"Lyon"`, `"Bordeaux"`). Automatically resolved to the correct department. Combine with `radius` to expand to nearby areas. |
| `radius` | Integer | `0` | When `city` is set, expand to departments within this radius in km. `0` = city's own department only. Example: `city="Lyon", radius=50` covers Rhône, Ain, Isère and Loire. |
| `departments` | Array | `[]` | French department codes (e.g. `["75", "69", "13"]`) |
| `regions` | Array | `[]` | French region codes (e.g. `["11"]` for Île-de-France) |
| `contractTypes` | Array | `[]` | CDI, CDD, Interim / Temporary, Freelance / Liberal, Seasonal, Franchise, Commercial contract |
| `experience` | Array | `[]` | No experience required, 1-3 years, 3-5 years, 5+ years |
| `fullTimeOnly` | Boolean | `false` | Full-time positions only |
| `partTimeOnly` | Boolean | `false` | Part-time positions only |
| `teleworkOnly` | Boolean | `false` | Telework / remote positions only |
| `handicapFriendly` | Boolean | `false` | Disability-inclusive employers only |
| `alternanceOnly` | Boolean | `false` | Apprenticeship / work-study contracts only |
| `sortBy` | String | `pertinence` | `pertinence` (relevance) or `date` (most recent first) |
| `maxResults` | Integer | `100` | Maximum number of listings to save |
| `daysOld` | Integer | `0` | Maximum listing age in days (0 = no limit) |
| `skipReposts` | Boolean | `false` | Skip listings already seen in a previous run |
| `startUrls` | Array | `[]` | Specific France Travail offer URLs to scrape directly |

#### Department and region codes

**Common departments:** `75` Paris · `69` Rhône · `13` Bouches-du-Rhône · `31` Haute-Garonne · `33` Gironde · `59` Nord · `67` Bas-Rhin · `92` Hauts-de-Seine · `93` Seine-Saint-Denis · `94` Val-de-Marne

**Common regions:** `11` Île-de-France · `84` Auvergne-Rhône-Alpes · `75` Nouvelle-Aquitaine · `76` Occitanie · `32` Hauts-de-France · `44` Grand Est · `52` Pays de la Loire · `53` Bretagne · `93` Provence-Alpes-Côte d'Azur

> **Note:** Department and region codes follow the official French administrative system (INSEE). Both can be combined in the same run.

---

### Output schema

Each result is a JSON object with the following fields:

| Field | Type | Description |
|---|---|---|
| `id` | String | Unique France Travail offer ID (e.g. `206CYPD`) |
| `title` | String | Job title |
| `url` | String | Direct URL to the listing on candidat.francetravail.fr |
| `companyName` | String | Employer name |
| `companyDescription` | String \| null | Employer description text |
| `companyUrl` | String \| null | Employer website |
| `companyLogo` | String \| null | Employer logo URL |
| `description` | String | Full job description (HTML) |
| `descriptionText` | String | Full job description (plain text) |
| `descriptionMarkdown` | String | Full job description (Markdown) |
| `contractType` | String | Contract type label (e.g. `Contrat à durée indéterminée`) |
| `contractCode` | String | Contract type code (e.g. `CDI`, `CDD`, `MIS`) |
| `workSchedule` | String \| null | Working hours label (e.g. `35H Travail en journée`) |
| `isFullTime` | Boolean \| null | `true` = full-time, `false` = part-time |
| `isAlternance` | Boolean | Whether this is an alternance / work-study contract |
| `isHandicapFriendly` | Boolean | Whether the employer is RQTH/disability-inclusive |
| `location` | String \| null | Location label (e.g. `75 - Paris`) |
| `city` | String \| null | City name |
| `department` | String \| null | Department name |
| `departmentCode` | String \| null | Department code (e.g. `75`) |
| `region` | String \| null | Region name |
| `regionCode` | String \| null | Region code (e.g. `11`) |
| `postalCode` | String \| null | Postal code |
| `latitude` | Number \| null | GPS latitude |
| `longitude` | Number \| null | GPS longitude |
| `salaryMin` | Number \| null | Minimum salary (currency per `salaryPeriod`) |
| `salaryMax` | Number \| null | Maximum salary |
| `salaryPeriod` | String \| null | Pay frequency (`Mensuel`, `Annuel`, `Horaire`) |
| `salaryCurrency` | String \| null | Currency code (`EUR`) |
| `salaryText` | String \| null | Full salary description as posted |
| `salaryBenefits` | Array | Additional compensation items (e.g. meal vouchers, mutual insurance) |
| `salaryMonths` | Number \| null | Number of salary months per year (e.g. `13`) |
| `publishDateISO` | String | Listing creation date (ISO 8601) |
| `updatedDateISO` | String \| null | Last update date (ISO 8601) |
| `experienceRequired` | String \| null | Experience requirement label |
| `experienceCode` | String \| null | Experience code (`D`, `1`, `2`, `3`) |
| `sector` | String \| null | Sector label |
| `sectorCode` | String \| null | Sector code |
| `romeCode` | String \| null | ROME occupation classification code |
| `romeLabel` | String \| null | ROME occupation label |
| `qualification` | String \| null | Qualification level |
| `skills` | Array | Required skills and competencies |
| `formations` | Array | Required training or education |
| `languages` | Array | Required languages |
| `drivingLicenses` | Array | Required driving licenses |
| `nbPositions` | Number \| null | Number of open positions |
| `applyUrl` | String \| null | Direct application URL (when available) |
| `source` | String | Always `francetravail.fr` |
| `scrapedAt` | String | Scrape timestamp (ISO 8601) |
| `contentHash` | String | MD5 fingerprint for deduplication |
| `isRepost` | Boolean | `true` if this listing was seen in a previous run |
| `originalPublishDate` | String \| null | First time this listing was seen (repost detection) |

#### Example output

```json
{
    "id": "206CYPD",
    "title": "Développeur Full Stack Node.js / React H/F",
    "url": "https://candidat.francetravail.fr/offres/recherche/detail/206CYPD",
    "companyName": "Digital Solutions SAS",
    "description": "<div class=\"job-description\"><p>Nous recherchons un développeur...</p></div>",
    "descriptionText": "Nous recherchons un développeur...",
    "contractType": "Contrat à durée indéterminée",
    "contractCode": "CDI",
    "isFullTime": true,
    "isAlternance": false,
    "city": "Paris",
    "department": "Paris",
    "departmentCode": "75",
    "region": "Île-de-France",
    "regionCode": "11",
    "latitude": 48.8566,
    "longitude": 2.3522,
    "salaryMin": 40000,
    "salaryMax": 55000,
    "salaryPeriod": "Annuel",
    "salaryCurrency": "EUR",
    "salaryText": "Annuel de 40000 Euros à 55000 Euros sur 12 mois",
    "salaryBenefits": ["Tickets restaurant", "Mutuelle"],
    "publishDateISO": "2026-03-28T08:00:00Z",
    "romeCode": "M1805",
    "romeLabel": "Études et développement informatique",
    "skills": ["Node.js", "React", "TypeScript", "PostgreSQL"],
    "source": "francetravail.fr",
    "scrapedAt": "2026-03-30T09:15:00Z",
    "contentHash": "a3f8c1d2e4b7...",
    "isRepost": false,
    "originalPublishDate": null
}
````

***

### Pricing

This actor uses **Pay-Per-Result** pricing — you only pay for the job listings actually saved to your dataset.

| Volume | Cost |
|---|---|
| 1,000 results | **$1.50** |
| 10,000 results | **$15.00** |
| 100,000 results | **$150.00** |

**Compared to manual data collection:** At $1.50 per 1,000 results, extracting 10,000 France Travail listings costs the same as roughly 15 minutes of a data analyst's time — without the setup, maintenance, or compliance overhead.

> Pricing is charged per saved result. Filtering, retries, and skipped reposts do not count toward your bill.

***

### Performance

| Scenario | Throughput | Approximate cost |
|---|---|---|
| 1,000 results, no filter | ~2 minutes | $1.50 |
| 10,000 results, keyword + department | ~15 minutes | $15.00 |
| Full catalogue snapshot (900k+) | ~4-6 hours | ~$1,350 |

Memory usage is consistently low — the actor runs in **256 MB** and does not require a browser.

***

### Typical use cases

- **Recruitment platforms** — aggregate France Travail listings alongside private-sector boards for a comprehensive French job market view
- **Labour market research** — track vacancy trends by ROME code, region, sector, or contract type over time
- **HR technology** — feed job data into matching engines, skills taxonomies, or salary benchmarking tools
- **Competitive intelligence** — monitor hiring activity within specific companies, departments, or sectors

***

### Known limitations

- **Location filtering reduces throughput.** City, department and region filters are applied after fetching results — the scraper scans the full catalogue and keeps only matching listings. For narrow geographic filters (e.g. a single city), expect to scrape more results than `maxResults` to fill the quota. Combine with `keywords` to improve yield. A wider `radius` increases both coverage and throughput.
- **Salary data is absent for ~60% of listings.** Many employers post without salary information. The `salaryText` field contains the raw salary label when present.
- **`applyUrl` is null for some listings.** Application links are only available when employers include an external redirect. In all other cases the application is managed through the France Travail platform.
- **Maximum 10,000 results per search query.** France Travail's search engine returns up to 10,000 results per filter combination. To collect more, use multiple targeted runs with different keyword combinations.
- **`isHandicapFriendly` reflects listing metadata.** When filtering with `handicapFriendly=true`, the API applies its own internal handicap accessibility index. The output field `isHandicapFriendly` reflects the listing's explicit metadata fields (`topAccesTH`, `employeurHandiEngage`) which may differ from the API's internal filter criterion.

***

### Technical details

| Property | Value |
|---|---|
| Actor type | Stateless scraper |
| Default memory | 256 MB |
| Default timeout | 60 minutes |
| Deduplication TTL | 90 days |
| Output formats | JSON (default), CSV, XML, XLSX via Apify |

***

### Additional services

Need a custom scraper, extended field mapping, or a dedicated data pipeline for France Travail or other European job boards? Contact us at **info@unfencedgroup.nl** — we build and maintain bespoke data infrastructure for HR tech teams and recruitment platforms.

***

*Built and maintained by [unfenced-group](https://apify.com/unfenced-group) · Specialists in European job board data infrastructure*

# Actor input Schema

## `keywords` (type: `string`):

Job title, skill, or sector keywords. Leave empty to retrieve all recent listings.

## `city` (type: `string`):

Search by city name (e.g. 'Paris', 'Lyon', 'Bordeaux'). Resolves automatically to the correct department. Combine with Radius to expand to nearby areas. Cannot be used together with Departments.

## `radius` (type: `integer`):

When City is set, expand the search to all departments whose centroid falls within this radius in kilometres. Set to 0 to restrict to the city's own department only. Example: city='Lyon', radius=50 covers Rhône, Ain, Isère and Loire.

## `departments` (type: `array`):

Filter by French department codes (e.g. '75' for Paris, '69' for Rhône). Leave empty to search all departments.

## `regions` (type: `array`):

Filter by French region codes (e.g. '11' for Île-de-France, '84' for Auvergne-Rhône-Alpes). Leave empty for all regions.

## `contractTypes` (type: `array`):

Filter by contract type. Leave empty to include all types.

## `experience` (type: `array`):

Filter by required experience level. Leave empty to include all levels.

## `fullTimeOnly` (type: `boolean`):

Return only full-time positions.

## `partTimeOnly` (type: `boolean`):

Return only part-time positions.

## `teleworkOnly` (type: `boolean`):

Return only positions that include telework options.

## `handicapFriendly` (type: `boolean`):

Return only listings from disability-inclusive employers.

## `alternanceOnly` (type: `boolean`):

Return only apprenticeship and work-study contracts.

## `sortBy` (type: `string`):

'pertinence' sorts by relevance. 'date' sorts by most recently posted first (recommended with daysOld).

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

Maximum number of job listings to save.

## `daysOld` (type: `integer`):

Only return listings posted within the last N days. Set to 0 to disable.

## `skipReposts` (type: `boolean`):

Skip listings already seen in a previous run. Requires at least one prior successful run.

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

Specific France Travail offer URLs to scrape directly. When provided, keyword and filter settings are ignored.

## Actor input object example

```json
{
  "keywords": "développeur",
  "radius": 0,
  "departments": [
    "75"
  ],
  "regions": [],
  "contractTypes": [],
  "experience": [],
  "fullTimeOnly": false,
  "partTimeOnly": false,
  "teleworkOnly": false,
  "handicapFriendly": false,
  "alternanceOnly": false,
  "sortBy": "pertinence",
  "maxResults": 100,
  "daysOld": 0,
  "skipReposts": false,
  "startUrls": []
}
```

# 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 = {
    "keywords": "développeur",
    "city": "",
    "radius": 0,
    "departments": [
        "75"
    ],
    "regions": [],
    "contractTypes": [],
    "experience": [],
    "sortBy": "pertinence",
    "maxResults": 100,
    "daysOld": 0,
    "startUrls": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("unfenced-group/france-travail-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 = {
    "keywords": "développeur",
    "city": "",
    "radius": 0,
    "departments": ["75"],
    "regions": [],
    "contractTypes": [],
    "experience": [],
    "sortBy": "pertinence",
    "maxResults": 100,
    "daysOld": 0,
    "startUrls": [],
}

# Run the Actor and wait for it to finish
run = client.actor("unfenced-group/france-travail-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 '{
  "keywords": "développeur",
  "city": "",
  "radius": 0,
  "departments": [
    "75"
  ],
  "regions": [],
  "contractTypes": [],
  "experience": [],
  "sortBy": "pertinence",
  "maxResults": 100,
  "daysOld": 0,
  "startUrls": []
}' |
apify call unfenced-group/france-travail-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "FranceTravail.fr France Travail Scraper",
        "description": "Scrape francetravail.fr — France's official government job board with 450,000+ listings. Structured output: title, company, salary, GPS coordinates, ROME occupational codes & full descriptions in HTML, text and Markdown. Contract type & location filters. No API key required.",
        "version": "1.0",
        "x-build-id": "GDdfTjJo2VR55fwkq"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/unfenced-group~france-travail-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-unfenced-group-france-travail-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/unfenced-group~france-travail-scraper/runs": {
            "post": {
                "operationId": "runs-sync-unfenced-group-france-travail-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/unfenced-group~france-travail-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-unfenced-group-france-travail-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": {
                    "keywords": {
                        "title": "Keywords",
                        "type": "string",
                        "description": "Job title, skill, or sector keywords. Leave empty to retrieve all recent listings."
                    },
                    "city": {
                        "title": "City",
                        "type": "string",
                        "description": "Search by city name (e.g. 'Paris', 'Lyon', 'Bordeaux'). Resolves automatically to the correct department. Combine with Radius to expand to nearby areas. Cannot be used together with Departments."
                    },
                    "radius": {
                        "title": "Search Radius (km)",
                        "minimum": 0,
                        "maximum": 500,
                        "type": "integer",
                        "description": "When City is set, expand the search to all departments whose centroid falls within this radius in kilometres. Set to 0 to restrict to the city's own department only. Example: city='Lyon', radius=50 covers Rhône, Ain, Isère and Loire.",
                        "default": 0
                    },
                    "departments": {
                        "title": "Departments",
                        "type": "array",
                        "description": "Filter by French department codes (e.g. '75' for Paris, '69' for Rhône). Leave empty to search all departments.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "regions": {
                        "title": "Regions",
                        "type": "array",
                        "description": "Filter by French region codes (e.g. '11' for Île-de-France, '84' for Auvergne-Rhône-Alpes). Leave empty for all regions.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "contractTypes": {
                        "title": "Contract Types",
                        "type": "array",
                        "description": "Filter by contract type. Leave empty to include all types.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "CDI",
                                "CDD",
                                "Interim / Temporary",
                                "Freelance / Liberal",
                                "Seasonal",
                                "Franchise",
                                "Commercial contract"
                            ]
                        }
                    },
                    "experience": {
                        "title": "Experience Level",
                        "type": "array",
                        "description": "Filter by required experience level. Leave empty to include all levels.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "No experience required",
                                "1-3 years",
                                "3-5 years",
                                "5+ years"
                            ]
                        }
                    },
                    "fullTimeOnly": {
                        "title": "Full-time Only",
                        "type": "boolean",
                        "description": "Return only full-time positions.",
                        "default": false
                    },
                    "partTimeOnly": {
                        "title": "Part-time Only",
                        "type": "boolean",
                        "description": "Return only part-time positions.",
                        "default": false
                    },
                    "teleworkOnly": {
                        "title": "Telework / Remote Only",
                        "type": "boolean",
                        "description": "Return only positions that include telework options.",
                        "default": false
                    },
                    "handicapFriendly": {
                        "title": "Disability-Friendly Employers Only",
                        "type": "boolean",
                        "description": "Return only listings from disability-inclusive employers.",
                        "default": false
                    },
                    "alternanceOnly": {
                        "title": "Alternance / Apprenticeship Only",
                        "type": "boolean",
                        "description": "Return only apprenticeship and work-study contracts.",
                        "default": false
                    },
                    "sortBy": {
                        "title": "Sort By",
                        "enum": [
                            "pertinence",
                            "date"
                        ],
                        "type": "string",
                        "description": "'pertinence' sorts by relevance. 'date' sorts by most recently posted first (recommended with daysOld).",
                        "default": "pertinence"
                    },
                    "maxResults": {
                        "title": "Max Results",
                        "minimum": 1,
                        "maximum": 100000,
                        "type": "integer",
                        "description": "Maximum number of job listings to save.",
                        "default": 100
                    },
                    "daysOld": {
                        "title": "Maximum Age (Days)",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Only return listings posted within the last N days. Set to 0 to disable.",
                        "default": 0
                    },
                    "skipReposts": {
                        "title": "Skip Reposts",
                        "type": "boolean",
                        "description": "Skip listings already seen in a previous run. Requires at least one prior successful run.",
                        "default": false
                    },
                    "startUrls": {
                        "title": "Start URLs",
                        "type": "array",
                        "description": "Specific France Travail offer URLs to scrape directly. When provided, keyword and filter settings are ignored.",
                        "items": {
                            "type": "object",
                            "required": [
                                "url"
                            ],
                            "properties": {
                                "url": {
                                    "type": "string",
                                    "title": "URL of a web page",
                                    "format": "uri"
                                }
                            }
                        }
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
