APEC Jobs Scraper
Pricing
from $5.00 / 1,000 job scrapeds
APEC Jobs Scraper
Scrape APEC.fr French executive (cadre) job postings — title, company, salary, location, contract type, remote work, apply URL. HTTP-only, no login, MCP-ready.
Pricing
from $5.00 / 1,000 job scrapeds
Rating
0.0
(0)
Developer
Khadin Akbar
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Scrape APEC.fr — France's largest executive (cadre) job board — with one HTTP call per page. No login, no cookies, no DataDome challenge, no Playwright. Returns rich per-offer fields: title, company, salary range (parsed to numeric min/max), location, lat/long, contract type, remote-work policy, posted date, and the public apply URL. 110K+ active offers, MCP-ready.
What you get
| Field | Type | Description |
|---|---|---|
jobId | string | APEC numeric offer ID |
offerNumber | string | APEC public number (used in URL) |
title | string | Job title (French) |
company | string | null | Hiring company; null when offer is confidential |
isConfidential | boolean | True when APEC hides the company |
location | string | null | City + department code (e.g. Paris 13 - 75) |
latitude, longitude | number | null | Geo coordinates |
salaryText | string | null | Salary as posted by employer (French) |
salaryMin, salaryMax | number | null | Parsed annual gross salary (EUR/year) |
contractType | string | null | CDI, CDD, FREELANCE, STAGE, ALTERNANCE, OTHER |
contractDurationMonths | number | null | Duration for fixed-term contracts (0 for CDI) |
remoteWork | string | null | FULL_REMOTE, HYBRID, OCCASIONAL, NONE, UNKNOWN |
descriptionExcerpt | string | null | First ~300 chars of the job description |
publishedAt | string | null | ISO 8601 publication date |
validatedAt | string | null | ISO 8601 validation date |
lowApplicationCount | boolean | null | APEC flag for low-competition offers |
sectorCode, sectorParentCode | number | null | APEC sector IDs |
url | string | Public APEC URL |
When to use
- Recruiters sourcing French cadre candidates by salary band, location, or contract type.
- Salary benchmarking for French executive roles (parsed
salaryMin/salaryMax). - Market research on the French executive job market (sector, location, remote-work distribution).
- Building French job-board aggregators or salary dashboards.
- AI agents (Claude, GPT, Gemini) answering "what executive jobs are open in Paris this week?" via MCP.
When NOT to use: for full job descriptions beyond the ~300-char excerpt — APEC walls the detail page with DataDome. The excerpt is enough for triage; use the public url field to drive a manual browser visit when full text is needed.
Pricing
| Event | Price |
|---|---|
| Actor start | $0.00005 per run (per GB allocated RAM) |
| Job scraped | $0.005 per offer pushed to dataset |
50 jobs ≈ $0.25; 1000 jobs ≈ $5. The actor enforces a hard maxResults cap so cost is bounded up front.
Quick start
Apify Console
- Open the actor and click Try for free.
- Set
searchQueryto e.g.data scientist(or leave empty to browse all offers). - Set
maxResults,postedWithinDays,salaryMin,contractTypes,remoteWork,experienceLevelas needed. - Click Start.
Apify API (Node.js)
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });const run = await client.actor('khadinakbar/apec-jobs-scraper').call({searchQuery: 'développeur python',maxResults: 100,sortBy: 'date_desc',postedWithinDays: 7,salaryMin: 50000,contractTypes: ['CDI'],remoteWork: ['FULL_REMOTE', 'HYBRID'],});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items);
Apify API (Python)
from apify_client import ApifyClientclient = ApifyClient("YOUR_APIFY_TOKEN")run = client.actor("khadinakbar/apec-jobs-scraper").call(run_input={"searchQuery": "directeur financier","maxResults": 200,"sortBy": "date_desc","salaryMin": 80000,"contractTypes": ["CDI"],})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item["title"], "—", item["company"], "—", item["salaryText"])
MCP (Claude / GPT / agent)
Available at https://mcp.apify.com?tools=khadinakbar/apec-jobs-scraper. Tool name: apify--khadinakbar--apec-jobs-scraper. Pass the same searchQuery, maxResults, etc. inputs as above.
Input
| Field | Type | Default | Notes |
|---|---|---|---|
searchQuery | string | data scientist | French keyword(s). Empty = all 110K+ offers. |
maxResults | int | 50 | Hard cap on items pushed (1–1000). |
sortBy | enum | date_desc | relevance, date_desc, date_asc. |
postedWithinDays | int | — | Filter by recency (1, 7, 14, 30, 90…). |
salaryMin | int | — | Minimum annual gross salary in EUR. |
salaryMax | int | — | Maximum annual gross salary in EUR. |
contractTypes | array | — | CDI, CDD, FREELANCE, STAGE, ALTERNANCE. |
remoteWork | array | — | FULL_REMOTE, HYBRID, OCCASIONAL, NONE. |
experienceLevel | array | — | JUNIOR, MID, SENIOR, EXEC. |
proxy | proxy | Apify auto | Datacenter is sufficient (no anti-bot). |
How it works
The actor calls APEC's internal search webservice (POST /cms/webservices/rechercheOffre) directly. This is the same endpoint the apec.fr SPA uses for its search page, but unlike the SPA's HTML pages it is not protected by DataDome — it returns clean JSON with a totalCount and a resultats[] array. Each result includes most useful fields already (title, salary text, geo, contract code, telework code, date). The actor:
- Builds a
RechercheOffreCriteriaDtopayload from your input. - Maps human-readable contract/remote/experience names to APEC's internal Long IDs.
- Pages through results with
pagination.startIndex+pagination.range=20untilmaxResultsortotalCountis reached. - Normalizes each result: parses French salary strings to numeric ranges, decodes contract/remote codes to enums, builds the public URL.
- Charges per result via Apify PPE; respects a triple-guard counter so no charge fires beyond
maxResults.
FAQ
Why not the full description? APEC's individual offer pages (/candidat/recherche-emploi.html/emploi/detail-offre/{id}) are gated by DataDome. The search-results endpoint already includes a 300-char excerpt for each offer — usually enough for triage. Full descriptions would require a headless browser per offer ($0.02 each in proxy + compute), inflating cost 4× for marginal data.
Is salary always present? No. APEC employers can omit salary. When omitted, salaryText, salaryMin, and salaryMax are all null. When present, the parser handles "45 - 49 k€ brut annuel", "A partir de 40 k€", "Jusqu'à 80 k€", and similar French phrasings.
Does APEC return all matching offers? APEC's API exposes a totalCount field, but in practice paging beyond ~1000 results returns empty pages. For large queries, slice by sortBy=date_desc + postedWithinDays to fetch fresh offers, run on a schedule, and dedupe by jobId.
Is this legal? APEC publishes its job offers publicly without a login wall. This actor reads only what's exposed by APEC's own public search endpoint, used by every visitor to apec.fr. Respect APEC's terms of service and your local data-protection laws (RGPD / GDPR) when using the data.
Is there a rate limit? APEC tolerates the request rate this actor uses (one page per ~1 second, default config). If you parallelize many runs, expect the API to throttle — set maxResults low and rely on the actor's built-in retry/backoff.
Disclaimer
This actor scrapes data from publicly accessible pages of apec.fr. It does not bypass authentication, login walls, or anti-scraping defenses. APEC.fr is a registered trademark of L'Association Pour l'Emploi des Cadres; this actor is not affiliated with or endorsed by APEC. Use the data responsibly and in accordance with applicable laws (RGPD / GDPR, APEC ToS).
Related actors by the same author
- LinkedIn Jobs Scraper — salary + skills.
- StepStone Jobs Scraper — Germany.
- Indeed Job Scraper — global.
- Monster Jobs Scraper.
- Visa-Sponsored Jobs Scraper.
- Jobs Scraper — Indeed + LinkedIn + Glassdoor unified.