# Welcome to the Jungle Jobs Scraper - Daily New Job Alerts (`scrapewise/welcome-to-the-jungle-jobs`) Actor

Scrape Welcome to the Jungle jobs in France, Europe and the US: title, company, salary, remote, contract (CDI, CDD, internship, alternance), description and apply link. Search by keyword, city or company. Schedule it daily: only new jobs. Error rows are free.

- **URL**: https://apify.com/scrapewise/welcome-to-the-jungle-jobs.md
- **Developed by:** [Scrapewise Data](https://apify.com/scrapewise) (community)
- **Categories:** Jobs, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.68 / 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.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## Welcome to the Jungle Jobs Scraper: daily new job alerts from France, Europe and the US

Scrape [Welcome to the Jungle](https://www.welcometothejungle.com), the job board of French and European tech,
startups and big employers, **without an account, cookies or a browser**. Search by keyword, city, region or country,
contract (CDI, CDD, freelance, internship, alternance), remote policy, experience, job category, company sector, job
language, salary and posting date, or paste a search URL straight from your browser. Every job comes with the
company (name, sector, size, logo), location, remote policy, contract, **salary when published**, experience,
summary, key missions, candidate profile, benefits and the publication date.

Built for **daily monitoring**: schedule the same search every morning and get **only the jobs published since the
last run**. A quiet day costs nothing.

### At a glance

- **Price per 1,000 jobs:** US$ 0.80 (down to US$ 0.68 on Gold and above)
- **Full job description (optional):** US$ 0.40 per 1,000, on top
- **Company profile rows (optional):** US$ 0.80 per 1,000
- **Fee per run start:** None
- **Search by keyword + filters, by company, or by pasted URL:** Yes
- **Only new jobs since the last run (`onlyNew`):** Yes, free when nothing is new
- **More than 1,000 results per search:** Yes, in newest-first order (the site itself stops at 1,000)
- **City names in English, French or local spelling, any case:** Yes (London or Londres, Munich or München)
- **Recruiter names or contact data:** Never (see below)
- **Error rows (bad URL, unknown value, no results):** Free, with an `errorCode`

### One real row

From a test run on 2026-10-06 (search "product manager", location "Paris", job category "Product Management", full
description on), shortened:

```json
{
  "type": "job",
  "id": "5f917b01-59c6-4ceb-bc23-decaa6d44eec",
  "title": "Product Manager – Module Agricole bobbee (H/F)",
  "url": "https://www.welcometothejungle.com/en/companies/isagri/jobs/product-manager-module-agricole-bobbee-h-f_paris-2e-arrondissement",
  "applyUrl": "https://app.beetween.com/WeaselWeb/p/#/apply/job/za6czw4jss5q/product-manager-module-agricole-bobbee-h-f",
  "companyName": "ISAGRI",
  "companySectors": ["Accounting", "Specialised Engineering", "Software"],
  "companyIndustry": "Consulting / Audit",
  "companyEmployees": 3000,
  "companyFoundedYear": 1983,
  "location": "Paris, France",
  "city": "Paris",
  "region": "Ile-de-France",
  "countryCode": "FR",
  "remote": "occasional",
  "contractType": "full_time",
  "salaryMin": 75000,
  "salaryMax": 90000,
  "salaryCurrency": "EUR",
  "salaryPeriod": "yearly",
  "experienceMinYears": 5,
  "educationLevel": "bac_3",
  "profession": "Product Manager",
  "professionCategory": "Project / Product Management",
  "professionSubcategory": "Product Management",
  "language": "fr",
  "keyMissions": ["Contribuer à la définition et au portage de la vision et de la stratégie produit du module agricole."],
  "benefits": ["Between 1-2 days at home", "Food service or stocked kitchen", "Reduction of working time (RTT)"],
  "publishedAt": "2026-10-06T13:59:20Z",
  "hasDescription": true,
  "description": "Fort de son expertise et de sa position de leader sur le marché des éditeurs comptables...",
  "skills": ["Teamwork", "Stakeholder management", "Team management"],
  "startDate": "2026-10-05T22:00:00Z",
  "isExternalApply": true
}
```

### What you can do with it

- **Job seekers and job alert services:** a daily feed of new Python, data or product jobs in Paris, London or Berlin,
  or fully remote, straight into Slack, e-mail, Notion or Google Sheets.
- **Recruiters and staffing agencies:** see which companies are hiring for which roles, every morning, and reach them
  first (company website, size and sector come with each job).
- **Sales and lead generation:** companies that are hiring are companies that are growing. Filter by sector, size and
  city, and turn new job posts into warm leads.
- **Salary and labour market research:** published salary ranges by role, city, contract and experience, remote
  share by sector, hiring volume over time.
- **Datasets and AI:** clean, typed rows (numbers as numbers, dates as ISO) with descriptions in Markdown, ready for
  RAG, classification and matching models.

### Input

| Field | What it does |
|---|---|
| `startUrls` | Search URLs from welcometothejungle.com (every filter in the URL is kept), company URLs or job URLs (returned with the full description) |
| `searchTerms` | Keywords (`python`, `product manager`, `data`); one search each |
| `locations` | Cities, regions or countries (`Paris`, `London`, `Berlin`, `Ile-de-France`, `France`, `Germany`), combined into one search; `remote` for fully remote jobs |
| `companies` | Company names or company URLs: that company's open jobs |
| `contractTypes` | `fullTime` (CDI), `temporary` (CDD), `freelance`, `internship`, `apprenticeship` (alternance), `partTime`, `vie`, `graduateProgram`, `volunteer`, `other` |
| `remote` | `fullRemote`, `hybrid`, `occasional`, `onSite`, `unknown` |
| `experienceLevels` | `lessThan6Months`, `6MonthsTo1Year`, `1To3Years`, `3To5Years`, `5To10Years`, `moreThan10Years` |
| `professions` | Job categories or subcategories (`Tech & Engineering`, `Data & Business Intelligence`, `Product Management`) |
| `sectors` | Company industries (`Software`, `Artificial Intelligence`, `Fintech`) |
| `languages` | Job language: `en`, `fr`, `de`, `es`, `it`, `pt`, `nl` |
| `minSalary` | Minimum yearly salary, in the job's own currency |
| `postedWithinDays` | Only jobs published in the last N days |
| `sortBy` | `newest` (default) or `relevance` |
| `maxItems` | Jobs per search, default 50. 0 = up to 5,000 |
| `includeDescription` | Also read each job page: full description, recruitment process, skills, tools, start date, external apply link (separate event) |
| `descriptionFormat` | `markdown` (default), `text` or `html` |
| `includeCompanies` | One extra row per company (separate event) |
| `onlyNew` | Deliver only jobs published since the last run of the same search |
| `proxyConfiguration` | Default Apify Proxy (datacenter) |

Example: new senior data jobs in Paris or London, permanent contract, hybrid, every morning:

```json
{
  "searchTerms": ["data engineer"],
  "locations": ["Paris", "London"],
  "contractTypes": ["fullTime"],
  "remote": ["hybrid"],
  "experienceLevels": ["5To10Years"],
  "maxItems": 100,
  "onlyNew": true
}
```

Fully remote Python jobs in English, with the full description:

```json
{
  "searchTerms": ["python"],
  "locations": ["remote"],
  "languages": ["en"],
  "includeDescription": true
}
```

Or paste the search from your browser:

```json
{
  "startUrls": ["https://www.welcometothejungle.com/en/jobs?query=product%20manager&refinementList%5Boffices.country_code%5D%5B%5D=FR&sortBy=mostRecent"],
  "maxItems": 200
}
```

Every open job of a few companies, with a company row each:

```json
{
  "companies": ["Doctolib", "https://www.welcometothejungle.com/en/companies/back-market"],
  "maxItems": 0,
  "includeCompanies": true
}
```

### How daily monitoring works

With `onlyNew`, the Actor remembers each search (same terms, locations and filters, in any order or spelling) in a
named key-value store in your own account, `welcome-to-the-jungle-jobs-state`: the jobs already delivered and the
publication time of the newest job read.

- The first run delivers up to `maxItems` and marks what it read as seen.
- Later runs read the newest jobs first, deliver only jobs never delivered before and published since the last run,
  and stop as soon as they reach older jobs. A day with nothing new delivers nothing and costs nothing.
- If a run is cut by `maxItems`, the spending limit or the timeout, the jobs it did not reach stay "new" and come
  in the next run.
- Delete the key-value store to start over.

### Output

Every job row: `id`, `jobReference`, `title`, `url`, `applyUrl`, `companyName`, `companySlug`, `companyUrl`,
`companyLogo`, `companySectors`, `companyIndustry`, `companyEmployees`, `companyFoundedYear`, `companySummary`,
`location`, `city`, `region`, `country`, `countryCode`, `offices` (every office of a multi-location job),
`latitude`, `longitude`, `remote` (`fullRemote`, `hybrid`, `occasional`, `onSite`), `isFullyRemote`, `contractType`
(`full_time`, `temporary`, `internship`, `apprenticeship`, `freelance`, `part_time`, `vie`, `graduate_program`...),
`contractDurationMinMonths`, `contractDurationMaxMonths`, `salaryMin`, `salaryMax`, `salaryCurrency`,
`salaryPeriod` (`yearly`, `monthly`, `daily`, `hourly`), `salaryYearlyMin`, `experienceMinYears`, `educationLevel`,
`profession`, `professionCategory`, `professionSubcategory`, `language`, `summary`, `keyMissions`, `profile`
(candidate profile), `benefits`, `isSponsored`, `publishedAt`, `hasDescription`, `position`, `searchInput`,
`scrapedAt`.

With `includeDescription` (`hasDescription: true`): `description`, `recruitmentProcess`, `skills`, `tools`,
`startDate`, `updatedAt`, and `applyUrl` becomes the employer's own application page when the job uses one
(`isExternalApply: true`). If a job page cannot be read, the row still comes with `hasDescription: false` and
`descriptionError`, and only the job is charged.

Company rows (`type: "company"`): `id`, `name`, `slug`, `url`, `website`, `logo`, `coverImage`, `employees`,
`foundedYear`, `summary`, `sectors`, `industry`, `headquarters`, `offices`, `labels`, `profileType`.

**No personal data, by design.** Job posts on the site can show the recruiter, team members and employee videos.
None of that is returned: no recruiter name, no employee name, no team, no contact form fields. E-mail addresses and
phone numbers inside the description, profile and recruitment process are replaced with `[contact removed]`. Use the
job `url` or `applyUrl` to apply.

### Error codes (never charged)

| `errorCode` | Meaning |
|---|---|
| `INVALID_INPUT` | A value the Actor does not understand (unknown contract type, a URL that is not from welcometothejungle.com, a job category that does not exist) |
| `NOT_FOUND` | The company or the job does not exist (or the job is closed) |
| `NO_RESULTS` | No open job for this search and filters, or no open job in this place right now |
| `BLOCKED` | The site refused every attempt on new IPs; run again or use the RESIDENTIAL proxy group |
| `NOT_REACHED` | The run timeout arrived before this search or job |
| `TIMEOUT_TOO_SHORT` | The run timeout is too short to read even one page; raise it |
| `UNEXPECTED` | A job came in a shape we did not expect; the rest of the run goes on |

### Pricing

| Event | Per 1,000 |
|---|---|
| Job delivered | US$ 0.80 |
| Full job description (only with `includeDescription` or job URLs) | US$ 0.40 |
| Company row (only with `includeCompanies`) | US$ 0.80 |

A daily `onlyNew` run on "python" in Paris that finds 25 new jobs costs US$ 0.02; with full descriptions, US$ 0.03.
Error rows, duplicates and jobs already delivered are free, and there is no start fee.

### Limitations

- In relevance order the site returns at most 1,000 jobs per search. Newest-first order (the default) goes past that.
- Salary is returned only when the employer publishes it. `minSalary` compares the yearly minimum in the job's own
  currency.
- Job texts are in the language the employer wrote them (often French); labels such as benefits and categories are
  in English.
- A location matches the job's office city, region or country. Jobs with several offices match any of them.
- This Actor reads public pages and the site's public search only.

### FAQ

**Do I need a Welcome to the Jungle account?** No. No login, no cookies, and the default datacenter proxy works.

**Can I paste a search from my browser?** Yes, from the English or French site. Keyword, filters (country, contract,
remote, category...), place and sort in the URL are kept.

**What do CDI, CDD and alternance map to?** `fullTime`, `temporary` and `apprenticeship`. You can also type CDI, CDD,
stage or alternance through the API.

**Can I use it from n8n, Make, Zapier or an AI agent?** Yes, through the Apify app or the Apify MCP server. Error
rows are free, so an agent can explore cheaply.

**What if a run is cut by its timeout?** The Actor stops shortly before the limit and ends successfully with what it
delivered, telling you in the status message how to get the rest.

### Changelog

- **0.1 (2026-10-07):** first version. Search by keyword, location, company or pasted URL with contract, remote,
  experience, job category, sector, language, salary and date filters; newest-first past the 1,000-results cap;
  optional full descriptions and company rows; `onlyNew` for daily schedules; free error rows.

# Actor input Schema

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

Welcome to the Jungle links, one per line: search URLs copied from your browser after setting the filters on welcometothejungle.com (for example https://www.welcometothejungle.com/en/jobs?query=python\&sortBy=mostRecent), company URLs (https://www.welcometothejungle.com/en/companies/<name>) or job URLs. Every filter in a search URL is kept. Job URLs come back with the full description. Leave empty to search with the fields below. Also accepts 'searchUrls' or 'urls'.

## `searchTerms` (type: `array`):

Keywords, one per line (for example python, product manager, data). Each term is a separate search with the locations and filters below, and every row keeps its term. Leave empty for every job matching the filters. Also accepts 'queries', 'query' or 'keywords'.

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

Cities, regions or countries, one per line (for example Paris, London, Berlin, Ile-de-France, France, Germany). English, French or local names work, in any case and with or without accents (London or Londres, Munich or München). Several locations are combined into one search. Use 'remote' for fully remote jobs. Leave empty for every location. Also accepts 'location', 'cities' or 'city'.

## `companies` (type: `array`):

Company names or Welcome to the Jungle company URLs, one per line (for example doctolib or https://www.welcometothejungle.com/en/companies/<name>). Returns that company's open jobs, with the search terms, locations and filters applied when given. Also accepts 'companyUrls' or 'company'.

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

Only these contract types (permanent, fixed-term, freelance, internship, apprenticeship, part time and more). Pick one or more; empty means any. Through the API, French values such as CDI, CDD, stage or alternance also work. Also accepts 'contractType' or 'contract'.

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

Only jobs with these remote policies: fully remote, hybrid (partial remote), occasional remote, on site or not specified. Pick one or more; empty means any. Also accepts 'remoteTypes'.

## `experienceLevels` (type: `array`):

Minimum experience the job asks for (less than 6 months, 6 months to 1 year, 1 to 3 years, 3 to 5 years, 5 to 10 years, more than 10 years). Pick one or more; empty means any. Through the API, junior, mid, senior and expert also work. Also accepts 'experienceLevel' or 'seniority'.

## `professions` (type: `array`):

Welcome to the Jungle job categories or subcategories, one per line (for example Tech & Engineering, Data & Business Intelligence, Product Management, Sales). Close names match too. Empty means any. Also accepts 'jobCategories' or 'profession'.

## `sectors` (type: `array`):

Company industries, one per line (for example Tech, Software, Artificial Intelligence, Banking, Fintech). Close names match too. Empty means any. Also accepts 'industries' or 'sector'.

## `languages` (type: `array`):

Only jobs written in these languages (for example English, French, German, Spanish). Pick one or more; empty means any. Useful to find English-language jobs in France. Also accepts 'language'.

## `minSalary` (type: `integer`):

Only jobs that publish a salary with a yearly minimum at or above this amount, in the job's own currency (EUR, GBP or USD), for example 50000. Jobs without a published salary are left out when this is set. Leave empty for no salary filter. Also accepts 'minYearlySalary'.

## `postedWithinDays` (type: `integer`):

Only jobs published in the last N days (for example 7). Empty means any date. Also accepts 'maxAgeDays'.

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

Newest (default) reads newest first and goes past Welcome to the Jungle's 1,000-results cap per search. Relevance uses the site's ranking but stops at 1,000 results per search. 'Only new jobs' always reads newest first. Also accepts 'sort'.

## `maxItems` (type: `integer`):

Maximum jobs for each search term, company or URL (default 50). 0 means up to 5,000. You pay per job delivered, so with 3 terms and 50 here a run delivers up to 150 jobs. Also accepts 'maxItemsPerSearch', 'maxResults' or 'limit'.

## `includeDescription` (type: `boolean`):

Reads each job's own page for the full description, recruitment process, skills, tools, start date and the external apply link (ATS). Charged as a separate 'Full job description' event per job, and the run is slower. Every row already has the summary, key missions and candidate profile without it. Off by default. Also accepts 'includeDetails'.

## `descriptionFormat` (type: `string`):

Format of the description, recruitment process and candidate profile fields: Markdown (default, keeps headings and lists), plain text, or the original HTML.

## `includeCompanies` (type: `boolean`):

Adds one company row per company found (website, employee count, sectors, headquarters and offices, labels), charged as a separate 'Company profile' event, once per company per run however many of its jobs are delivered. Off by default. Also accepts 'includeCompanyDetails'.

## `onlyNew` (type: `boolean`):

For scheduled runs. Remembers which jobs each search (same terms, locations and filters) already returned, in a named key-value store in your account ('welcome-to-the-jungle-jobs-state'), and delivers only jobs published since. The first run delivers up to the limit and marks what it read as seen. Seen jobs are not delivered and not charged. Forces newest first. Delete the store to start over. Also accepts 'onlyNewJobs'.

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

The default Apify Proxy (datacenter) works. Refused IPs are dropped and replaced; if the datacenter keeps being refused, the Actor moves to the residential group by itself when your account has it. Keep the default.

## Actor input object example

```json
{
  "searchTerms": [
    "python"
  ],
  "locations": [
    "Paris"
  ],
  "sortBy": "newest",
  "maxItems": 50,
  "includeDescription": false,
  "descriptionFormat": "markdown",
  "includeCompanies": false,
  "onlyNew": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

No description

## `resultsCsv` (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 = {
    "searchTerms": [
        "python"
    ],
    "locations": [
        "Paris"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapewise/welcome-to-the-jungle-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 = {
    "searchTerms": ["python"],
    "locations": ["Paris"],
}

# Run the Actor and wait for it to finish
run = client.actor("scrapewise/welcome-to-the-jungle-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 '{
  "searchTerms": [
    "python"
  ],
  "locations": [
    "Paris"
  ]
}' |
apify call scrapewise/welcome-to-the-jungle-jobs --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapewise/welcome-to-the-jungle-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/mvSNA7R5H2B7ulKGG/builds/D4jLtQQ4mrmsLoFga/openapi.json
