# APEC Scraper - French Executive Job Offers (`studio-amba/apec-scraper`) Actor

Scrape executive (cadre) job offers from APEC (apec.fr), France's job board for managers and professionals. Search by keyword, location, and contract type. Extract titles, companies, salaries, skills, and full descriptions. No login or cookies required.

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

## Pricing

from $8.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 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

## APEC Scraper — French Executive (Cadre) Job Offers

Scrape executive and managerial job offers from [APEC](https://www.apec.fr) (Association pour l'emploi des cadres), France's dedicated job board for cadres and professionals. Search by keyword, location, and contract type, then export clean structured data with salaries, skills, and full descriptions. No login, no cookies.

### Why use this actor?

APEC is where French companies post their higher-skilled roles — management, engineering, finance, IT, sales, and consulting. If you build a jobs aggregator, run salary benchmarks, track hiring demand by sector, or feed a recruitment CRM, this actor turns the APEC search into a structured feed you can query on a schedule.

It reads APEC's own JSON search API directly, so results are fast and complete: every offer already carries its title, hiring company, location, salary range, contract type, and publication date. Turn on full descriptions and each row also gets the complete job text, the required profile, the company description, and the listed skills.

### How to scrape APEC data

1. Open the actor and set a **Search Query** in French — for example `chef de projet`, `développeur`, `comptable`, or `commercial`.
2. Optionally set a **Location** (city, department name, or postal-code prefix such as `Paris`, `Lyon`, `75`, or `69`) and a **Contract Type** (CDI, CDD, Interim, Freelance, Alternance).
3. Set **Max Results** to the number of offers you want.
4. Leave **Fetch Full Descriptions** on for the complete job text and skills, or turn it off for faster listing-only results.
5. Keep the French residential proxy prefill and click **Start**.
6. When the run finishes, export the dataset as JSON, CSV, or Excel, or pull it from the Apify API.

The actor paginates through the APEC search results automatically until it reaches your Max Results or runs out of matching offers.

### Input

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `searchQuery` | String | No | Job search keyword in French (e.g. `chef de projet`, `développeur`). Defaults to `chef de projet` if empty. |
| `location` | String | No | Filter by city, department name, or postal-code prefix (e.g. `Paris`, `Lyon`, `75`). Leave empty for all of France. |
| `contractType` | String | No | `all`, `CDI`, `CDD`, `INTERIM`, `FREELANCE`, or `ALTERNANCE`. |
| `maxResults` | Integer | No | Maximum number of offers to scrape (default: 100). |
| `fetchDetails` | Boolean | No | Fetch each offer's detail page for the full description and skills (default: true). |
| `proxyConfiguration` | Object | No | Proxy settings. French residential proxies recommended. |

### Output

Each result contains:

| Field | Type | Example |
|-------|------|---------|
| `jobTitle` | String | `"Chef de projet F/H"` |
| `company` | String | `"MOMENTI"` |
| `location` | String | `"Paris 15 - 75"` |
| `postalCode` | String | `"75015"` |
| `department` | String | `"75"` |
| `contractType` | String | `"CDI"` |
| `contractTypeCode` | Number | `101888` |
| `salary` | String | `"35 - 45 k€ brut annuel"` |
| `salaryMin` | Number | `35000` |
| `salaryMax` | Number | `45000` |
| `salaryPeriod` | String | `"annual"` |
| `jobDescription` | String | Full job description text |
| `profileWanted` | String | Required profile / candidate section |
| `companyDescription` | String | Description of the hiring company |
| `skills` | Array | `["Esprit d'équipe", "Gestion de projet", ...]` |
| `sector` | String | Sector of activity |
| `positions` | Number | `1` |
| `remote` | Boolean | `true` |
| `latitude` | String | `"48.8566"` |
| `longitude` | String | `"2.3522"` |
| `publishedDate` | String | `"2026-06-24T09:58:28.000+0000"` |
| `offerId` | String | `"178910904W"` |
| `applicationUrl` | String | External application URL (when present) |
| `url` | String | Full URL to the offer on apec.fr |
| `scrapedAt` | String | ISO timestamp of when the row was scraped |

### Example output

```json
{
    "jobTitle": "Chef de projet F/H",
    "company": "MOMENTI",
    "location": "Paris 15 - 75",
    "postalCode": "",
    "department": "75",
    "contractType": "CDI",
    "contractTypeCode": 101888,
    "salary": "35 - 45 k€ brut annuel",
    "salaryMin": 35000,
    "salaryMax": 45000,
    "salaryPeriod": "annual",
    "jobDescription": "Au sein de notre équipe, vous pilotez les projets de bout en bout...",
    "profileWanted": "Vous êtes issu d'une formation Bac +5 avec 3 ans d'expérience...",
    "companyDescription": "Nous sommes un cabinet de conseil spécialisé...",
    "skills": ["Esprit d'équipe", "Gestion de projet", "Reporting"],
    "sector": "",
    "positions": 1,
    "remote": false,
    "latitude": "48.8566",
    "longitude": "2.3522",
    "publishedDate": "2026-06-24T09:58:28.000+0000",
    "offerId": "178910904W",
    "applicationUrl": "https://easyapply.jobs/r/3HS0Rx327HlO231ueINV",
    "url": "https://www.apec.fr/candidat/recherche-emploi/emploi/detail-offre/178910904W",
    "scrapedAt": "2026-07-09T10:00:00.000Z"
}
````

### Salary parsing

APEC publishes salaries as free text (for example `"35 - 45 k€ brut annuel"` or `"A partir de 40 k€ brut annuel"`). The actor keeps the original text in `salary` and also parses it into `salaryMin`, `salaryMax`, and `salaryPeriod` where possible, converting `k€` figures into full euro amounts.

### Cost estimate

APEC exposes a clean JSON API, so runs are cheap. With **Fetch Full Descriptions** on, the actor makes roughly one extra request per offer; with it off, it fetches one page per 100 offers. A typical run of a few hundred offers costs a small fraction of a dollar in Apify compute plus the pay-per-result fee. Turn off `fetchDetails` when you only need titles, companies, locations, salaries, and links.

### Limitations / known issues

- **Executive roles only.** APEC covers cadre and professional roles. It is not a general job board — use it alongside a France Travail scraper for full-market coverage.
- **Location filter is text-based.** The `location` input matches against each offer's location text (city and department). It is not a radius search, so `Paris` will not automatically include the wider Île-de-France region.
- **`postalCode` is often empty.** APEC's listing gives the city and 2-digit department, not always a full 5-digit postal code, so `department` is more reliably populated than `postalCode`.
- **`applicationUrl` is present only for external applications.** Offers that are applied to through APEC's own system leave this field empty; use `url` in that case.
- **French residential proxy recommended.** APEC's detail pages sit behind bot protection. The search and public detail JSON APIs used here work reliably through French residential proxies.

### Related scrapers

- [France Travail Scraper](https://apify.com/studio-amba/france-travail-scraper) — France's national employment agency (Pôle Emploi), full job market.
- [HelloWork / European Job Search](https://apify.com/studio-amba/european-job-search) — multi-source European job aggregation.
- [Jobat Scraper](https://apify.com/studio-amba/jobat-scraper) — Belgian job board.
- [Pracuj Scraper](https://apify.com/studio-amba/pracuj-scraper) — Poland's largest job board.
- [InfoJobs Scraper](https://apify.com/studio-amba/infojobs-scraper) — Spain's largest job board.

### Disclaimer

This actor collects only publicly available job-offer data from apec.fr for legitimate use such as market research and job aggregation. Respect APEC's terms of service and applicable data-protection law when using the output.

# Actor input Schema

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

Job search keyword in French (e.g. 'chef de projet', 'developpeur', 'commercial', 'comptable'). Leave empty to browse the most recent cadre offers.

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

Filter by city, department name, or postal-code prefix (e.g. 'Paris', 'Lyon', '75', '69'). Matches the offer location text. Leave empty for all of France.

## `contractType` (type: `string`):

Filter by contract type.

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

Maximum number of job offers to scrape.

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

Fetch each offer's detail page for the full job description, required profile, company description, and skills. Slower but richer. Turn off for faster, listing-only results.

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

Proxy settings. French residential proxies recommended for reliable access.

## Actor input object example

```json
{
  "searchQuery": "chef de projet",
  "contractType": "all",
  "maxResults": 20,
  "fetchDetails": true,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "FR"
  }
}
```

# 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": "chef de projet",
    "maxResults": 20,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "FR"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("studio-amba/apec-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": "chef de projet",
    "maxResults": 20,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "FR",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("studio-amba/apec-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": "chef de projet",
  "maxResults": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "FR"
  }
}' |
apify call studio-amba/apec-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "APEC Scraper - French Executive Job Offers",
        "description": "Scrape executive (cadre) job offers from APEC (apec.fr), France's job board for managers and professionals. Search by keyword, location, and contract type. Extract titles, companies, salaries, skills, and full descriptions. No login or cookies required.",
        "version": "0.1",
        "x-build-id": "lyI1zS6Au7Ca4VGRG"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/studio-amba~apec-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-studio-amba-apec-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~apec-scraper/runs": {
            "post": {
                "operationId": "runs-sync-studio-amba-apec-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~apec-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-studio-amba-apec-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": "Job search keyword in French (e.g. 'chef de projet', 'developpeur', 'commercial', 'comptable'). Leave empty to browse the most recent cadre offers."
                    },
                    "location": {
                        "title": "Location",
                        "type": "string",
                        "description": "Filter by city, department name, or postal-code prefix (e.g. 'Paris', 'Lyon', '75', '69'). Matches the offer location text. Leave empty for all of France."
                    },
                    "contractType": {
                        "title": "Contract Type",
                        "enum": [
                            "all",
                            "CDI",
                            "CDD",
                            "INTERIM",
                            "FREELANCE",
                            "ALTERNANCE"
                        ],
                        "type": "string",
                        "description": "Filter by contract type.",
                        "default": "all"
                    },
                    "maxResults": {
                        "title": "Max Results",
                        "minimum": 1,
                        "maximum": 5000,
                        "type": "integer",
                        "description": "Maximum number of job offers to scrape.",
                        "default": 100
                    },
                    "fetchDetails": {
                        "title": "Fetch Full Descriptions",
                        "type": "boolean",
                        "description": "Fetch each offer's detail page for the full job description, required profile, company description, and skills. Slower but richer. Turn off for faster, listing-only results.",
                        "default": true
                    },
                    "proxyConfiguration": {
                        "title": "Proxy Configuration",
                        "type": "object",
                        "description": "Proxy settings. French residential proxies recommended for reliable access."
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
