# Welcome to the Jungle Jobs Scraper (`slxcx_0/wttj-jobs-scraper`) Actor

Search and extract job offers from welcometothejungle.com (90k+ live listings, FR/EN/US/UK). Salary, remote policy, contract type, experience level, skills, full description, apply URL and company data. No browser, fast and cheap.

- **URL**: https://apify.com/slxcx_0/wttj-jobs-scraper.md
- **Developed by:** [Jules Deparis](https://apify.com/slxcx_0) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 job listings

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

Extract job offers from **welcometothejungle.com** — 90,000+ live listings across France, the US, the UK, Germany, Spain and 100+ other countries — as clean, structured JSON/CSV/Excel.

Fast and cheap: no browser, no proxies. **500 fully-detailed jobs in ~20 seconds.** Every record includes salary range, remote policy, contract type, experience level, skills and tools, the full job description, the apply URL and company data (size, sector, founding year, logo).

### What you get for each job

| Field | Example |
| --- | --- |
| `name`, `url`, `applyUrl` | "Développeur Full Stack Java confirmé (H/F)", job page link, direct apply link |
| `companyName`, `companySlug`, `companyUrl`, `companyLogo`, `companyEmployees`, `companyCreationYear`, `sectors`, `companyLabels` | "Viaxoft", 65 employees, 2008, \["Logiciels", "SaaS / Cloud Services"] |
| `city`, `countryCode`, `address`, `latitude`, `longitude`, `allOffices` | Marseille, FR, geocoordinates |
| `contractType`, `contractDurationMinMonths`, `contractDurationMaxMonths` | full_time / temporary / internship / apprenticeship / freelance / part_time / vie |
| `remote` | fulltime / partial / punctual / no |
| `salaryMin`, `salaryMax`, `salaryCurrency`, `salaryPeriod`, `salaryYearlyMin` | 40000 – 56000 EUR yearly |
| `experienceYearsMin`, `educationLevel` | 5, bac_5 |
| `profession`, `professionCategory`, `professionSubCategory` | "Ingénieur de données", "Technologie et ingénierie" |
| `skills`, `tools` | \["Méthode Agile", "Communication"], \["FastAPI", "Django"] |
| `description`, `descriptionHtml`, `candidateProfile`, `recruitmentProcess`, `companyDescription` | Full text (plain + HTML) |
| `benefits`, `keyMissions`, `summary` | Perks and highlights |
| `language`, `publishedAt`, `scrapedAt`, `id`, `reference` | fr / en, ISO timestamps |

### Input

- **Search keywords** — one search per keyword (`"développeur react"`, `"product manager"`, `"data engineer"`). Leave empty to browse everything matching your filters.
- **WTTJ search URLs** — paste URLs copied from the website; query, country, contract and remote filters are read from the URL.
- **Filters** — countries (`FR`, `US`, `GB`...), cities, contract types, remote policy, listing language, min/max experience years, published within the last N days.
- **Fetch full job details** — on by default. Turn off for a cheaper listing-only run (title, company, location, salary, remote, contract, published date).
- **Max jobs** and **Sort by** (newest first or relevance).

Each search returns up to 1,000 jobs (the site's own search limit). To collect more, split by city, contract type, or use several keywords — results are deduplicated across searches.

#### Example input

```json
{
  "queries": ["développeur react", "product manager"],
  "countryCodes": ["FR"],
  "contractTypes": ["full_time"],
  "remote": ["fulltime", "partial"],
  "publishedWithinDays": 7,
  "includeDetails": true,
  "maxItems": 500,
  "sortBy": "newest"
}
```

#### Example output

```json
{
  "name": "Développeur Full Stack Java confirmé (H/F)",
  "url": "https://www.welcometothejungle.com/fr/companies/viaxoft/jobs/developpeur-full-stack-java-confirme-h-f_marseille",
  "companyName": "Viaxoft",
  "companyEmployees": 65,
  "sectors": ["Logiciels", "SaaS / Cloud Services"],
  "city": "Marseille",
  "countryCode": "FR",
  "contractType": "full_time",
  "remote": "partial",
  "experienceYearsMin": 5,
  "salaryMin": 40000,
  "salaryMax": 56000,
  "salaryCurrency": "EUR",
  "salaryPeriod": "yearly",
  "skills": ["Java", "Spring", "Méthode Agile"],
  "tools": ["Spring Boot", "PostgreSQL"],
  "benefits": ["Entre 1-2 jours de télétravail", "RTT / Jour de repos"],
  "publishedAt": "2026-10-14T13:33:33Z",
  "applyUrl": "https://www.welcometothejungle.com/fr/companies/viaxoft/jobs/developpeur-full-stack-java-confirme-h-f_marseille/apply",
  "description": "Rejoins notre équipe en tant que Développeur Full Stack Java confirmé..."
}
```

### Pricing

Pay per event, no subscription:

- **`job-listing`** — one job with title, company, location, salary, remote policy, contract, experience, published date.
- **`job-detail`** — adds the full description, candidate profile, recruitment process, skills, tools and apply URL (only when *Fetch full job details* is on).

No start fee. Platform usage is minimal (no browser), so a 1,000-job run costs a few cents of compute on top of the events.

### Use cases

- **Recruiting & sourcing** — monitor competitors' hiring, build talent-market dashboards.
- **Lead generation** — companies that are hiring are buying; filter by sector, size and city.
- **Salary benchmarking** — 40%+ of listings carry a salary range.
- **Job boards & aggregators** — fresh listings with `publishedWithinDays`, newest-first, and stable `id`s for deduplication.
- **AI agents / MCP** — small, well-typed records that fit in a prompt; use `maxItems` and `includeDetails=false` for cheap scans.

### Scheduling & integrations

Run it on a schedule (e.g. every morning with `publishedWithinDays: 1`) and push results to Google Sheets, Airtable, Slack, a webhook or your own API through Apify integrations. Call it from the Apify API, the Apify MCP server, or the Python/JS clients.

### Notes

- Only publicly visible listings are collected; no login, no personal data.
- `salary*` fields are null when the employer did not publish a range.
- Results are sorted newest first by default so scheduled runs pick up new offers immediately.

# Actor input Schema

## `queries` (type: `array`):

One search per entry, e.g. "développeur react", "product manager", "data engineer". Leave empty to browse all jobs matching the filters.

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

Paste search URLs copied from welcometothejungle.com/fr/jobs?query=... — query, country and contract filters are parsed from the URL.

## `countryCodes` (type: `array`):

ISO country codes of the office location, e.g. FR, US, GB, DE, ES. Empty = all countries.

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

Office city names, e.g. Paris, Lyon, Lille. Empty = all cities.

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

full_time (CDI), temporary (CDD), internship, apprenticeship, freelance, part_time, vie, graduate_program.

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

fulltime = 100% remote, partial = hybrid, punctual = occasional, no = on-site.

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

Language of the listing: fr, en, de, es, it...

## `minExperienceYears` (type: `integer`):

Only jobs requiring at least this many years of experience.

## `maxExperienceYears` (type: `integer`):

Only jobs requiring at most this many years of experience.

## `publishedWithinDays` (type: `integer`):

Only return offers published in the last N days. Leave empty for all.

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

Also fetch each job page: full description, candidate profile, recruitment process, skills/tools, apply URL. Charged as a separate 'job-detail' event.

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

Stop after this many jobs (across all queries). 0 = unlimited.

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

Relevance (default) or newest first.

## Actor input object example

```json
{
  "queries": [
    "développeur react"
  ],
  "startUrls": [],
  "countryCodes": [
    "FR"
  ],
  "cities": [],
  "contractTypes": [],
  "remote": [],
  "languages": [],
  "includeDetails": true,
  "maxItems": 100,
  "sortBy": "newest"
}
```

# Actor output Schema

## `jobs` (type: `string`):

All scraped job offers as JSON. Append ?format=csv or ?format=xlsx for other formats.

## `summary` (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 = {
    "queries": [
        "développeur react"
    ],
    "countryCodes": [
        "FR"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("slxcx_0/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 = {
    "queries": ["développeur react"],
    "countryCodes": ["FR"],
}

# Run the Actor and wait for it to finish
run = client.actor("slxcx_0/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 '{
  "queries": [
    "développeur react"
  ],
  "countryCodes": [
    "FR"
  ]
}' |
apify call slxcx_0/wttj-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,slxcx_0/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/luBva8hMRMgpn4SLE/builds/sNcz5gnMUmeQLEWbG/openapi.json
