# Welcome to the Jungle Jobs Scraper — Full Job & Company Data (`teodor_banea/wttj-jobs-scraper`) Actor

Scrape Welcome to the Jungle jobs with full description, recruitment process, skills, tools, salary, remote policy and company data. Filter by keyword, country, city, contract, remote, experience, sector, salary, date. Company and job-URL modes.

- **URL**: https://apify.com/teodor_banea/wttj-jobs-scraper.md
- **Developed by:** [Banea Teodor](https://apify.com/teodor_banea) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 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/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 — Full Descriptions, Salary, Skills & Company Data

### What does Welcome to the Jungle Jobs Scraper do?

Welcome to the Jungle Jobs Scraper extracts job listings from [Welcome to the Jungle](https://www.welcometothejungle.com), the career platform with about **90,000 live jobs**, mostly in France, the United States, the United Kingdom and Canada. Search by keyword and filters, list every open job of the companies you choose, or fetch specific job pages. Each row has the **full job description**, the candidate profile, the **recruitment process**, **skills and tools**, contract type and duration, start date, required experience and education, remote-work policy, **salary**, every office location, benefits, and rich **company data**: website, LinkedIn, size, founding year, headquarters, sectors, labels and gender-equality index. No login, no browser.

### Why use this Actor?

- **Complete rows.** The full description, profile, recruitment process, skills, tools, start date and the employer's own apply link, not just the search card. Every row has the same 69 fields, with `null` or `[]` when the site has no value.
- **Filters that cost nothing.** Keyword, country, city, contract type, remote policy, experience band, education level, company sector, job category, salary (with currency), posting date and company are all applied by the site's own search. You only pay for the jobs you get.
- **Beyond the 1,000-result limit.** The site's search stops at 1,000 results. This Actor returns every match: all 10,000 "data" jobs or all 60,000 jobs in France. With full details it collects about 8 jobs per second, so for more than about 25,000 jobs raise the run timeout above the default hour (Run options → Timeout).
- **Company intelligence.** Website, LinkedIn page, employee count, founding year, headquarters, average employee age, open jobs, certifications (B Corp, Great Place to Work, EcoVadis…) and the French gender-equality index.
- **English or French.** Labels (contract types, sectors, categories, benefits, skills, countries, salary text) and page links come in the language you choose.
- **Built for daily feeds.** Sort by newest and set *Posted within (days)* to match your schedule. See [Scheduling](#scheduling).

### How much does it cost?

You pay **$0.005 per run** plus **$1.50 per 1,000 jobs** returned. Platform usage and proxy are included.

| Run | Jobs | Cost |
|---|---|---|
| 20 "python" jobs (the prefilled input) | 20 | $0.035 |
| Permanent, fully-remote jobs in France | ~560 | ~$0.85 |
| Every open job at 2 companies | ~100 | ~$0.155 |
| All "data" jobs | ~10,000 | ~$15.00 |
| Daily feed for one keyword (posted in the last day) | ~100–200 per day | ~$0.16–0.31 |

### Input

| Field | Description | Example |
|---|---|---|
| `mode` | `search` (keyword + filters, default), `companies` (all open jobs of the listed companies) or `jobUrls` (specific job pages) | `"search"` |
| `query` | Search keywords, as in the site's search box | `"product manager"` |
| `companies` | Company slugs or company page URLs (companies mode) | `["doctolib", "https://www.welcometothejungle.com/en/companies/auchan"]` |
| `jobUrls` | Job page URLs (jobUrls mode). Archived jobs are returned too, flagged `isArchived` | `[{"url": "https://www.welcometothejungle.com/en/companies/shine/jobs/senior-cs-data-analyst"}]` |
| `maxResults` | Jobs to return. 0 = all matches (capped at 10,000 without any keyword, company or filter) | `100` |
| `countries` | ISO country codes of the office | `["FR", "GB"]` |
| `cities` | Office cities as spelled on the site (case and accents ignored) | `["Paris", "Lyon"]` |
| `contractTypes` | `full_time` (permanent), `temporary`, `internship`, `apprenticeship` (work study), `freelance`, `part_time`, `vie`, `graduate_program`, `volunteer`, `idv`, `other` | `["full_time"]` |
| `remote` | `fulltime` (fully remote), `partial` (a few days home), `punctual` (occasional), `no`, `unknown` | `["fulltime", "partial"]` |
| `experienceLevels` | `zero_to_one`, `one_to_three`, `three_to_five`, `five_to_ten`, `more_than_ten` (years) | `["one_to_three"]` |
| `educationLevels` | `no_diploma`, `cap`, `bep`, `bac`, `bac_1` … `bac_5`, `phd` (French system: Bac +N = N years of higher education) | `["bac_5"]` |
| `sectors` | Company sector groups or sectors (pick from the list) | `["tech-1"]` |
| `professions` | Job categories or sub-categories (pick from the list) | `["tech-engineering-3NjUy"]` |
| `onlyWithSalary` | Only jobs that publish a salary | `true` |
| `minYearlySalary` + `salaryCurrency` | Yearly salary from this amount, in this currency (EUR, USD, GBP) | `60000`, `"EUR"` |
| `postedWithinDays` | Published in the last N days | `7` |
| `sortBy` | `relevance` (default) or `newest` | `"newest"` |
| `language` | `en` or `fr`: language of labels and links | `"en"` |
| `includeDescription` | Full job details (default on). Off = lighter rows from the search data only | `false` |

```json
{
    "query": "data engineer",
    "countries": ["FR"],
    "contractTypes": ["full_time"],
    "remote": ["fulltime", "partial"],
    "minYearlySalary": 50000,
    "salaryCurrency": "EUR",
    "maxResults": 200
}
```

### Output

One row per job. Every row has every field, and missing values are `null` or `[]`.

```json
{
    "jobId": "b5b26693-f96a-4656-9b56-89bd35dbe364",
    "jobReference": "AUCHA_93yWeQ8",
    "title": "Equipier de commerce et caisses F/H CDD 1 MOIS",
    "url": "https://www.welcometothejungle.com/en/companies/auchan/jobs/equipier-de-commerce-et-caisses-f-h-cdd-1-mois_billom",
    "slug": "equipier-de-commerce-et-caisses-f-h-cdd-1-mois_billom",
    "companyName": "Auchan",
    "companySlug": "auchan",
    "companyUrl": "https://www.welcometothejungle.com/en/companies/auchan",
    "companyWebsite": "https://auchan-recrute.fr/",
    "companyLinkedinUrl": "https://www.linkedin.com/company/auchan",
    "companyLogoUrl": "https://cdn-images.welcometothejungle.com/16QKdyFt…/rs:auto:400/q:85/czM6Ly93…",
    "companyCoverImageUrl": "https://cdn-images.welcometothejungle.com/65VgMGX9…/rs:auto:2000:450/…",
    "companyEmployees": 59000,
    "companyFoundedYear": 1961,
    "companyHeadquarters": "Villeneuve-D'ascq, France",
    "companyAverageAge": 34,
    "companyOpenJobs": 566,
    "companySummary": "Expérience collective et épanouissante pour améliorer le quotidien.",
    "companyDescription": "L'expérience Auchan est une expérience que nous créons… ensemble !\n\nC'est une expérience collective…",
    "companyLabels": ["top-employer-institute"],
    "companyCommitments": ["commitment-for-employees"],
    "companyEqualityIndex": 91,
    "sectors": ["Mass Distribution", "E-commerce", "Consumer Goods"],
    "sectorParents": ["Distribution", "Food and Beverage"],
    "professionCategory": "Sales & Customer Service",
    "professionSubCategory": "Retail Sales",
    "professionName": "Others",
    "contractType": "temporary",
    "contractTypeText": "Temporary",
    "contractDurationMinMonths": 1,
    "contractDurationMaxMonths": null,
    "startDate": "2026-10-21",
    "experienceLevel": null,
    "experienceYearsMin": null,
    "educationLevel": null,
    "language": "fr",
    "city": "Billom",
    "state": "Auvergne-Rhone-Alpes",
    "district": "Puy-de-Dôme",
    "country": "France",
    "countryCode": "FR",
    "postalCode": "63160",
    "address": "Place Joseph Claussat, 63160 Billom, France",
    "latitude": 45.72448,
    "longitude": 3.34005,
    "locations": ["Billom, France"],
    "remote": "no",
    "remoteText": "No remote",
    "salaryMin": 23910,
    "salaryMax": 24160,
    "salaryCurrency": "EUR",
    "salaryPeriod": "yearly",
    "salaryYearlyMin": 23910,
    "salaryText": "€23,910 – €24,160 / year",
    "summary": "Rejoignez Auchan Retail France, une entreprise de distribution engagée dans la satisfaction client…",
    "keyMissions": ["Orienter et accueillir les clients, les renseigner et les conseiller sur les produits.", "…"],
    "description": "✨Nous sommes…\n\nAuchan Retail France, une entreprise de distribution de plus de 50 000 collaborateurs…",
    "profile": "Chez Auchan, nous sommes convaincus que la diversité fait la richesse d'une entreprise…",
    "recruitmentProcess": null,
    "skills": ["Supply chain management"],
    "tools": [],
    "benefits": ["Between 1-2 days at home", "Unconscious bias training", "Reduction of working time (RTT)", "…"],
    "postedAt": "2026-10-19T15:54:51.000Z",
    "updatedAt": "2026-10-19T15:54:55.932Z",
    "isArchived": false,
    "archivedAt": null,
    "applyUrl": "https://auchan.talentview.io/jobs/bnsxh0?source=wttj",
    "detailsFetched": true,
    "scrapedAt": "2026-10-19T22:30:00.000Z"
}
```

| Field | Notes |
|---|---|
| `jobId` | Unique and stable job id. Use it to deduplicate. `jobReference` is the employer's reference and is shared by re-posts of one vacancy in several cities. |
| `contractType` / `contractTypeText` | Code (`full_time` = permanent / CDI) and the label the site shows in the run language. |
| `remote` / `remoteText` | `fulltime` = fully remote, `partial` = a few days home, `punctual` = occasional remote, `no` = no remote, `unknown` = not specified. |
| `salary*` | Amounts in `salaryCurrency` per `salaryPeriod`. `salaryYearlyMin` is the site's yearly figure (monthly × 12, daily × 218), which is what the minimum-salary filter compares. About a third of jobs publish pay. |
| `experienceLevel` / `experienceYearsMin` | The required band ("2-3 years") and its minimum in years (0.5 = 6 months). |
| `language` | The language the job is written in. Job texts (title, description, summary, key missions) are never translated. The `language` input only changes labels and links. |
| `city` … `longitude` | The job's primary office (the one shown on the job page). `locations` lists every office as "City, Country", the primary office first. |
| `applyUrl` | The employer's own application page (ATS). `null` when candidates apply on the Welcome to the Jungle page (`url`). |
| `description`, `profile`, `recruitmentProcess`, `companyDescription` | Plain text. Paragraphs are on their own lines and list items start with "- ". |
| Fields marked "job details" in the schema | Company website, LinkedIn, headquarters, average age, open jobs, postal code, address, start date, description, recruitment process, skills, tools, `updatedAt` and `applyUrl` need *Include full job details* (on by default). `detailsFetched` tells you whether a row has them. |

Problems are listed in the run's key-value store under `ERRORS` and never mixed into the job rows. They include deleted jobs, URLs that are not job pages, and jobs delivered without details because their details could not be read.

### Tips and tricks

- **Daily feed:** `sortBy: "newest"`, `postedWithinDays: 1`, `maxResults: 0`, scheduled every morning.
- **Salary benchmarks:** set `minYearlySalary` together with `salaryCurrency`. Without a currency, euros, dollars and pounds are compared as plain numbers.
- **Cities:** use the spelling the site uses. Big foreign cities are in English ("Munich", "Brussels"). Case and accents don't matter.
- **Lighter, faster rows:** turn off `includeDescription`. Title, company, location, salary, contract, summary, key missions, benefits, sectors and job category stay, and the run needs one request per 250 jobs instead of one per job (1,000 jobs in about 45 seconds).
- **Company watch:** the companies mode with `sortBy: "newest"` and `postedWithinDays` set to your schedule interval alerts you to every new opening at your target employers.
- **Order:** "Relevance" follows the site's ranking for the first 1,000 jobs. Further matches follow in the site's index order. "Newest first" is strictly by publication time.
- **Long runs and timeouts:** rows are saved as they are collected. If a run hits its timeout, every job collected so far stays in the dataset.

### Scheduling

For a feed of new jobs, schedule the Actor with "Newest first" and set `postedWithinDays` to match the schedule interval: `1` for a daily run, `7` for a weekly run. Rows are unique within a run. Consecutive runs can overlap at the edges, so drop repeats downstream by `jobId`. The Actor keeps no memory between runs and leaves no storage in your account beyond each run's own dataset and key-value store.

### Integrations

Export the dataset as JSON, CSV or Excel, or fetch it by API (`/v2/datasets/{id}/items?view=overview`). Connect the Actor to Google Sheets, Zapier, Make, Slack or a webhook from the **Integrations** tab, or schedule it to keep a job feed, a hiring-signals list or a salary benchmark up to date.

### Disclaimer

The jobs and company profiles are published by Welcome to the Jungle and its customers. The Actor collects no personal data about recruiters or team members. Check the site's terms before reusing the data commercially.

# Changelog

This Actor's version history is a separate document: https://apify.com/teodor_banea/wttj-jobs-scraper/changelog.md

# Actor input Schema

## `mode` (type: `string`):

Choose "Search jobs" to search by keyword and filters, "Company jobs" for all open jobs of the companies you list, or "Job URLs" for specific job pages.

## `query` (type: `string`):

Enter keywords as you would type them in the site's search box (job title, skill, company…), e.g. "python", "product manager". Leave empty to list every job matching the filters.

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

Enter company slugs or Welcome to the Jungle company URLs, e.g. "auchan" or "https://www.welcometothejungle.com/en/companies/doctolib". The slug is the part after /companies/ in the URL. The filters below also apply.

## `jobUrls` (type: `array`):

Enter Welcome to the Jungle job page URLs (https://www.welcometothejungle.com/en/companies/<company>/jobs/<job>). Archived jobs are returned too, flagged with isArchived.

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

Enter how many jobs to return. 0 = all matching jobs (capped at 10,000 when no keyword, company or filter is set).

## `countries` (type: `array`):

Keep jobs with an office in any of these countries. Empty = all countries.

## `cities` (type: `array`):

Keep jobs with an office in any of these cities, spelled as on the site (case and accents are ignored: "montreal" = "Montréal"). Use the English name for big cities ("Munich", "Brussels").

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

Keep jobs with these contract types. Counts are live jobs on 2026-10-19.

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

Keep jobs with these remote-work policies.

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

Keep jobs whose minimum experience falls in these bands (the site's own bands). Jobs that state no experience are left out when this filter is set.

## `educationLevels` (type: `array`):

Keep jobs asking for these education levels (French system: Bac +N = N years of higher education). Only ~20% of jobs state one.

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

Keep jobs at companies in these sectors. Pick a group ("Tech (all)") or single sectors ("Tech › Cyber Security").

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

Keep jobs in these job categories. Pick a category ("Tech & Engineering (all)") or sub-categories ("Tech & Engineering › Software & Web Development").

## `onlyWithSalary` (type: `boolean`):

Keep only jobs that publish a salary (about a third do).

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

Keep jobs whose yearly salary starts at this amount or more (monthly and daily pay are converted to yearly by the site). The amount is in each job's own currency — set "Salary currency" too, or EUR, USD and GBP jobs are mixed.

## `salaryCurrency` (type: `string`):

Keep jobs that publish a salary in this currency.

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

Keep jobs published in the last N days (1 = the last 24 hours). Empty or 0 = any date.

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

Choose the order of the jobs. "Relevance" is the site's ranking for your keywords (beyond the first 1,000 jobs the rest follow in the site's index order); "Newest first" orders every job by publication date.

## `language` (type: `string`):

Choose the language of the labels in each row (contract type, sectors, job category, benefits, skills, countries, salary text) and of the job / company page links. The job text itself stays in the language the company wrote it in (see the language field).

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

Add the full description, recruitment process, skills, tools, start date, apply link, company website and headquarters (one extra request per job). Turn off for lighter, faster rows: title, company, location, salary, contract, summary, key missions, benefits and sectors stay.

## Actor input object example

```json
{
  "mode": "search",
  "query": "python",
  "companies": [
    "doctolib",
    "https://www.welcometothejungle.com/en/companies/auchan"
  ],
  "jobUrls": [
    {
      "url": "https://www.welcometothejungle.com/en/companies/shine/jobs/senior-cs-data-analyst"
    }
  ],
  "maxResults": 20,
  "cities": [
    "Paris",
    "Lyon"
  ],
  "onlyWithSalary": false,
  "minYearlySalary": 50000,
  "postedWithinDays": 7,
  "sortBy": "relevance",
  "language": "en",
  "includeDescription": true
}
```

# Actor output Schema

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

Every job row of the run as JSON.

## `overview` (type: `string`):

Title, company, location, contract, remote policy and salary columns.

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

The same rows as a CSV download.

## `errors` (type: `string`):

Jobs that could not be read (deleted jobs, invalid URLs, jobs delivered without details). Only present when something went wrong.

# 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 = {
    "query": "python",
    "maxResults": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("teodor_banea/wttj-jobs-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 = {
    "query": "python",
    "maxResults": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("teodor_banea/wttj-jobs-scraper").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 '{
  "query": "python",
  "maxResults": 20
}' |
apify call teodor_banea/wttj-jobs-scraper --silent --output-dataset

```

## MCP server setup

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

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/4asGprgNBqZNYwsLr/builds/tce72CasoVTmcrKWI/openapi.json
