# HelloWork Scraper — French Jobs, Salaries, CDI/CDD, No Phones (`highbrow_fame/hellowork-jobs`) Actor

French job ads from HelloWork: title, company, city, département, contract (CDI, CDD, intérim, alternance, stage), salary min/max, remote work, date, full ad. No phones.

- **URL**: https://apify.com/highbrow\_fame/hellowork-jobs.md
- **Developed by:** [yestrue](https://apify.com/highbrow_fame) (community)
- **Categories:** Jobs
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$0.90 / 1,000 job delivereds

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/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## HelloWork Scraper — French Jobs, Salaries, CDI/CDD, No Phones

Get job ads from HelloWork, one of France's biggest job boards (over 830,000 jobs): title, company, town, département and region, contract (CDI, CDD, intérim, alternance, stage, freelance), full or part time, remote work, the salary as published with its minimum, maximum and period, HelloWork's salary estimate where the employer gives none, the publication date — and the full ad with the profile wanted, education, experience, sector, skills and whether a temp agency or a recruitment firm posted it. Search by keywords and places, or paste HelloWork search links.

**Why this one**

- 🔗 **Your search, as you set it up.** Paste a search from hellowork.com with all its filters, or a job list page (`…/emploi/metier_comptable.html`). Or type keywords and places here — towns, Paris arrondissements, postcodes, départements, regions — and choose contract, remote work, full or part time, experience, radius, posting date and a minimum salary.
- 📚 **Every job of a search, none twice.** HelloWork's default order repeats some jobs from page to page and skips others. This Actor reads newest first, where every job comes once: 333 of 333 hybrid developer jobs in Paris, 457 of 457 accountant jobs in Lyon, 143 of 143 hybrid sales jobs in Toulouse, and 6,000 France-wide jobs with no duplicate in live runs.
- 💶 **Salaries as data.** Minimum, maximum and period (year, month, day or hour) whenever the employer publishes a salary — 4,652 of 6,000 jobs in a France-wide run — and HelloWork's own estimate, kept apart, when it does not. **Min yearly salary** keeps only jobs whose published pay reaches it.
- 📄 **The full ad.** Exact publication date, the ad text, the profile wanted, the company presentation, education (Bac +2…), experience asked, sector, category and skills — 2,290 jobs with the full ad in under 8 minutes in a live run.
- 🔒 **No phone numbers, no recruiters' names.** Phone numbers and e-mail addresses in the ad texts are replaced with `[phone removed]` / `[e-mail removed]`, and the names of contact persons and recruiters with `[name removed]`; salary figures are kept. Employers are named by their company, and no street address is given.
- 💸 **You pay only for jobs delivered.** A link that is not a HelloWork search, or a place HelloWork does not know, comes back as a free record with the reason.

### What you get

For every job:

| Field | What it is |
|---|---|
| `title`, `jobId`, `url` | the job on HelloWork |
| `company`, `companyUrl`, `companyLogo` | the employer (or the agency that posted the job) and its HelloWork page |
| `location`, `city`, `department`, `postalCode`, `region` | where: "Lyon 3e - 69", Lyon 3e, 69, 69003, Auvergne-Rhône-Alpes |
| `contractType`, `workingTime`, `tags` | CDI, CDD, Intérim, Alternance, Stage, Indépendant, Freelance, Fonctionnaire…; `full-time` or `part-time`; the length or dates of a mission ("6 mois") |
| `remote` | `full`, `partial`, `occasional`, `none` — empty when the ad does not say |
| `salaryText`, `salaryMin`, `salaryMax`, `salaryPeriod`, `salaryCurrency` | the salary the employer publishes ("35 000 - 38 000 € / an"), per `year`, `month`, `day` or `hour` |
| `estimatedSalaryMin`, `estimatedSalaryMax`, `estimatedSalaryPeriod` | HelloWork's estimate, when the employer gives no salary |
| `postedAgo`, `postedAt`, `validThrough` | "il y a 1 heure" from the list; the exact publication date and the closing date from the ad |
| `category`, `sector`, `educationLevel`, `experience`, `experienceMinYears`, `skills` | Comptabilité · Services aux Entreprises · Bac +2 · "Exp. 7 ans min." · the skills HelloWork lists |
| `postedBy` | `Agence d'intérim`, `Cabinet de recrutement`, `ESN`… when an intermediary posted the job; empty for the employer itself |
| `description`, `profile`, `companyDescription` | the ad text: the job, the profile wanted, the company |
| `superRecruiter`, `applicationTracking`, `directApply`, `reference` | HelloWork's badges, apply on HelloWork or on the employer's site, the employer's reference |
| `input`, `place`, `position`, `scrapedAt`, `status`, `error`, `detailsError` | which search it came from, and why a search gave nothing |

Without **Full job ad** a job has the fields of the search list: title, company, place, contract, working time, remote work, salary, `postedAgo` and the badges.

#### Example

A real record from a live run, 25 September 2026 — permanent accountant jobs in Lyon (long texts cut with "…"):

```json
{
  "jobId": 83781043,
  "url": "https://www.hellowork.com/fr-fr/emplois/83781043.html",
  "title": "Collaborateur Comptable Confirmé H/F",
  "company": "Ekko RH",
  "location": "Villeurbanne - 69",
  "city": "Villeurbanne",
  "department": "69",
  "contractType": "CDI",
  "workingTime": "full-time",
  "remote": "partial",
  "salaryText": "35 000 - 38 000 € / an",
  "salaryMin": 35000,
  "salaryMax": 38000,
  "salaryPeriod": "year",
  "salaryCurrency": "EUR",
  "postedAgo": "il y a 1 heure",
  "superRecruiter": true,
  "postalCode": "69100",
  "region": "Auvergne-Rhône-Alpes",
  "postedAt": "2026-09-25T14:58:25Z",
  "validThrough": "2026-10-25T14:58:25Z",
  "category": "Comptabilité",
  "sector": "Services aux Entreprises",
  "educationLevel": "Bac +2",
  "experience": "Exp. 7 ans min.",
  "experienceMinYears": 7,
  "skills": ["Relation client", "Rapprochement bancaire", "Établissement des déclarations fiscales", "Autonomie", "Déclarations sociales", "Sens de l’organisation"],
  "postedBy": "Cabinet de recrutement",
  "directApply": true,
  "companyUrl": "https://www.hellowork.com/fr-fr/entreprises/ekko-rh-91770.html",
  "description": "Notre client, un cabinet d'expertise comptable en pleine expansion, recherche un Collaborateur Comptable Confirmé pour rejoindre son équipe.\nLe cabinet accompagne une cli…",
  "profile": "• Formation : Bac +2 minimum en comptabilité (DCG ou équivalent), idéalement Bac +3/4.\n• Expérience : 2 à 3 ans d'expérience en comptabilité, idéalement en cabinet d'expe…",
  "status": "OK"
}
```

### How to use it

1. Type **Keywords** (comptable, développeur java, infirmier) and **Places** (Lyon, 69003, Gironde, Bretagne), and choose the filters — or paste **Search links** from hellowork.com.
2. Set **Max jobs per search**. **Full job ad** is on; turn it off for a faster list.
3. Press **Start**, and download the results from the **Output** tab as JSON, CSV or Excel.

To follow new jobs, save your input as a task with **Posted within** set to "The last 24 hours" and schedule it daily.

You can also call it from the Apify API, from Make, Zapier or n8n, or from an AI agent through the Apify MCP server.

### Pricing

You are charged **per job delivered** — see the price on this page. The full job ad costs nothing extra, only time. Links that are not HelloWork searches and places HelloWork does not know are free.

### FAQ

**How fast is it?** Without the full ad a live run listed 6,000 jobs in 4 minutes 16 seconds, and 713 jobs of two smaller searches in 26 seconds. With the full ad it reads about 5 jobs a second: 2,290 jobs in 7 minutes 37 seconds. It keeps a steady pace on purpose, because HelloWork turns away visitors who ask too fast.

**How many jobs per search?** All of them, newest first. France as a whole has over 830,000; set **Max jobs per search** as high as you need.

**What does a place match?** What HelloWork makes of it: a town (with 20 km around it unless you set **Radius**), a Paris or Lyon arrondissement, a postcode, a département, a region or a country. A few jobs a little outside a département or region come from HelloWork itself; `department` and `postalCode` say where each one is.

**Why do some jobs have no salary?** The employer does not publish one. HelloWork then often shows its own estimate, which is in the `estimatedSalary…` fields, not in `salaryMin` / `salaryMax`. **Min yearly salary** counts hourly pay × 1,820 and monthly × 12, at the top of the range, as HelloWork does — and leaves out jobs without a published salary.

**Why does a job have `detailsError`?** Its full ad could not be read in this run (a network error after the retries); the record keeps what the job list shows. Ads that were taken down but still appear on HelloWork's job list pages (7 of 1,165 in a live run) are left out and not charged.

**Are recruiters' names or phone numbers in the data?** No. Phone numbers, e-mail addresses and the names of contact persons written into the ads are removed — in a live run of 1,310 ads, 19 names in 15 ads ("Votre contact : \[name removed]") and 3 phone numbers. Apply through the job's `url`.

**Is this affiliated with HelloWork?** No. This is an independent tool that reads the job ads HelloWork publishes.

**Like it?** A short review on the Store page helps other people find this Actor. Something missing or broken? Tell us on the Issues tab — we read every one.

# Actor input Schema

## `searchUrls` (type: `array`):

Set up a search on hellowork.com with all the filters you want and paste the address of the results page (https://www.hellowork.com/fr-fr/emploi/recherche.html?k=…\&l=…). Job list pages such as …/fr-fr/emploi/metier\_comptable.html work too. One per line.

## `keywords` (type: `array`):

Or search here without a link: job titles, skills or company names (comptable, développeur java, infirmier). Each keyword is searched in each place below, or in all of France when there is no place. The filters below apply.

## `locations` (type: `array`):

Towns, Paris arrondissements, postcodes, départements or regions (Lyon, Paris 15e, 69003, Gironde, Bretagne), or a country. A place without keywords gives all its jobs.

## `radiusKm` (type: `integer`):

Optional: include jobs this many km around a town. HelloWork adds 20 km when this is empty; 0 keeps to the town itself.

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

Optional: only jobs of any of these kinds.

## `remote` (type: `array`):

Optional: only jobs with any of these remote policies.

## `workingTime` (type: `string`):

Optional.

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

Optional: only jobs that ask for any of these.

## `postedWithin` (type: `string`):

Optional: only jobs published recently.

## `minYearlySalary` (type: `integer`):

Optional: only jobs that publish a salary reaching this much a year at the top of its range (hourly pay × 1,820, monthly × 12 — as HelloWork counts). Jobs without a published salary are left out.

## `salaryOnly` (type: `boolean`):

Leave out jobs whose employer does not publish a salary.

## `maxListingsPerSearch` (type: `integer`):

Stops each search after this many jobs. Jobs come newest first.

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

Opens every job for the exact publication date, the full ad text, the profile wanted, education, experience, sector, skills and postcode. One more request per job.

## `maxConcurrency` (type: `integer`):

How many searches to work on at the same time.

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

Used only when HelloWork turns a request down: the first try goes out directly.

## Actor input object example

```json
{
  "searchUrls": [
    "https://www.hellowork.com/fr-fr/emploi/recherche.html?k=comptable&l=Lyon&c=CDI"
  ],
  "workingTime": "any",
  "postedWithin": "all",
  "salaryOnly": false,
  "maxListingsPerSearch": 30,
  "includeDetails": true,
  "maxConcurrency": 3,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (type: `string`):

Every result as a JSON record, with a status for each input.

## `resultsCsv` (type: `string`):

The same records as CSV, for a spreadsheet.

# 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 = {
    "searchUrls": [
        "https://www.hellowork.com/fr-fr/emploi/recherche.html?k=comptable&l=Lyon&c=CDI"
    ],
    "maxListingsPerSearch": 30,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("highbrow_fame/hellowork-jobs").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "searchUrls": ["https://www.hellowork.com/fr-fr/emploi/recherche.html?k=comptable&l=Lyon&c=CDI"],
    "maxListingsPerSearch": 30,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("highbrow_fame/hellowork-jobs").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "searchUrls": [
    "https://www.hellowork.com/fr-fr/emploi/recherche.html?k=comptable&l=Lyon&c=CDI"
  ],
  "maxListingsPerSearch": 30,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call highbrow_fame/hellowork-jobs --silent --output-dataset

```

## MCP server setup

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

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/8z2q2Ho4d3MUa4brZ/builds/zjUN2OrZiKutzBGez/openapi.json
