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

Welcome to the Jungle Jobs Scraper extracts European job listings with contract type, remote policy, salary range, experience and education level, benefits, offices, sectors and publish date. 🇫🇷 For job aggregation and hiring analysis.

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

## Pricing

from $1.99 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

### 💼 Welcome to the Jungle (WTTJ) Jobs Scraper – Job Listings, Salary & Company Data Export

The **Welcome to the Jungle jobs scraper** extracts job listings from welcometothejungle.com and returns them as structured records containing the role, contract type, salary range, remote policy, required skills, full job description and a detailed company profile. Search by keyword and location, apply the same filters you would use on the site itself — contract type, experience level, remote policy, company size, industry sector, minimum salary — and export the results as clean job data ready for analysis, aggregation or an ATS import.

Welcome to the Jungle is one of the richest job boards in the European market, particularly across France, and its listings carry far more employer context than a typical aggregator. This Welcome to the Jungle jobs scraper preserves that depth. Alongside the usual title, location and contract fields you get the company's employee count, founding year, gender parity figures, average employee age, social profiles, commitments and labels, plus the recruitment process and ATS application questions attached to each posting.

The `includeDetails` switch controls how deep the scraper goes. Left on, it queries each job's details endpoint to pull full descriptions, candidate profile requirements, tools, benefits and key missions. Turned off, it performs an ultra-fast shallow sweep that is ideal for high-volume listing counts and change monitoring.

***

### 📊 What Data Can You Extract with This Welcome to the Jungle Jobs Scraper?

The scraper returns one record per job listing, combining the posting itself with a substantial employer profile.

| Category | Fields | What you get |
|---|---|---|
| 🧾 Job identity | `id`, `reference`, `name`, `url`, `applyUrl`, `publishedAt`, `startDate` | The listing identifier and reference, the job title, its page URL, the direct application link and its publication and start dates |
| 📑 Role classification | `contractType`, `remote`, `language`, `experienceLevel`, `educationLevel`, `category`, `subcategory`, `sectors`, `contractDurationMin`, `contractDurationMax` | Contract type and duration, remote policy, listing language, required experience and education, and the category taxonomy |
| 💰 Compensation | `salaryMin`, `salaryMax`, `salaryCurrency`, `salaryPeriod` | The advertised salary range with its currency and reference period, where the employer discloses it |
| 📝 Job content | `summary`, `description`, `profile`, `keyMissions`, `skills`, `tools`, `benefits`, `team`, `recruitmentProcess` | The short summary and full description, the candidate profile sought, key missions, required skills and tools, benefits, team context and the hiring process |
| 🏢 Company profile | `organizationName`, `organizationSlug`, `organizationLogo`, `organizationDescription`, `companySummary`, `organizationCoverImage`, `organizationIndustry`, `organizationWebsite`, `organizationJobsCount` | The employer's name, identifiers, branding assets, description, industry and how many roles they currently list |
| 📊 Company metrics | `organizationEmployees`, `organizationCreationYear`, `organizationRevenue`, `organizationTurnover`, `organizationAverageAge`, `organizationParityMen`, `organizationParityWomen`, `organizationLabels`, `organizationCommitments`, `organizationHeadquarter` | Headcount, founding year, revenue and turnover figures, workforce demographics, certifications and headquarters |
| 🔗 Employer channels & ATS | `organizationLinkedin`, `organizationTwitter`, `organizationFacebook`, `organizationInstagram`, `organizationHasExternalAts`, `organizationAutomaticEmail`, `organizationGdprSetting`, `atsQuestions`, `applicationFields`, `offices` | Social profiles, ATS configuration, GDPR settings, application questions and office locations |

The most commercially valuable combination here is `salaryMin`, `salaryMax` and `salaryCurrency` alongside `organizationEmployees` and `experienceLevel`. Very few job boards publish structured salary data at all, and having it linked to company size and seniority turns a job feed into a genuine compensation benchmarking dataset.

***

### 🌟 Key Features of the Welcome to the Jungle Jobs Scraper

| Feature | Description |
|---|---|
| 🔍 Keyword and location search | Search by job title or keywords and target a city, country or "Worldwide", with a configurable radius in kilometres |
| 🎛️ Full native filter set | Contract type, remote policy, experience level, company size, job language, industry sector, job category and minimum yearly salary |
| 💰 Structured salary fields | Salary minimum, maximum, currency and period are returned as separate fields rather than buried in free text |
| 🏢 Deep employer profiles | Headcount, founding year, revenue, turnover, parity figures, average age, labels and commitments accompany every listing |
| ⚡ Shallow or deep mode | `includeDetails` toggles between an ultra-fast listing sweep and a full fetch of descriptions, tools, benefits and profiles |
| 🎯 Title-only matching | `searchOnlyInJobTitle` restricts matches strictly to job titles, cutting out roles that merely mention your keyword in the body |
| 🗓️ Recency filtering | `datePosted` narrows results to the past 24 hours, 48 hours, 7 days or 30 days for fresh-listing monitoring |
| 🌐 Language scoping | Filter listings by website country code and by job language across French, English, German, Spanish, Italian, Portuguese, Czech and Dutch |
| 🔗 Direct apply links | `applyUrl` provides the direct application destination, with `organizationHasExternalAts` flagging externally hosted ATS flows |

***

### 🚀 Why Choose This Welcome to the Jungle Jobs Scraper?

**Structured salary data, not a text blob.** Compensation is the hardest field to extract reliably from most job boards because it is usually free text. Here `salaryMin`, `salaryMax`, `salaryCurrency` and `salaryPeriod` arrive as discrete fields, which means salary benchmarking works out of the box rather than requiring a parsing layer.

**Employer intelligence that other scrapers discard.** `organizationEmployees`, `organizationCreationYear`, `organizationParityMen`, `organizationParityWomen`, `organizationAverageAge` and `organizationCommitments` describe what a company is actually like. For recruitment marketing, employer-brand research and candidate-facing tools, this context is often more valuable than the job posting itself.

**A real speed-versus-depth choice.** `includeDetails` is not a cosmetic setting. With it off you get fast, cheap listing sweeps suitable for monitoring thousands of roles daily. With it on you get the full `description`, `profile`, `keyMissions`, `tools` and `benefits` for genuine content analysis. You choose per run.

**Filtering that mirrors the site.** Because the scraper exposes the same filters candidates use — contract type, remote policy, experience level, company size, sector, language, minimum salary — you can reproduce a precise on-site search programmatically instead of collecting everything and filtering afterwards.

***

### 📥 Input

Every field is optional; running with defaults searches broadly with full details enabled.

```json
{
  "query": "React Developer",
  "location": "Paris, France",
  "locationRadius": "20",
  "searchOnlyInJobTitle": false,
  "websiteCountry": "en",
  "sortBy": "relevance",
  "datePosted": "any",
  "contractType": "",
  "remoteWork": "",
  "experienceLevel": "",
  "companySize": "",
  "jobLanguage": "",
  "maxItems": 100,
  "includeDetails": true
}
```

#### 🔧 Welcome to the Jungle Jobs Scraper Input Fields

| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| `query` | string | No | prefilled `React Developer` | Keywords to search for, such as "React Developer" or "Product Designer". Leave blank to search all jobs. |
| `location` | string | No | `Worldwide` | Location to search in, for example "Paris, France" or "London". Use "Worldwide" for global listings. |
| `locationRadius` | string | No | `20` | Distance radius in kilometres around the specified location. |
| `searchOnlyInJobTitle` | boolean | No | `false` | If enabled, restricts search matches strictly to job titles. |
| `websiteCountry` | string | No | `en` | Language or country code used to filter listings, for example `en`, `fr`, `es`, `cs`, `sk`. Use `any` to disable filtering. |
| `sortBy` | string | No | `relevance` | Sort order of job listings. One of `relevance` or `newest`. |
| `datePosted` | string | No | `any` | Time range of job publication. One of `any`, `today`, `yesterday`, `past_week`, `past_month`. |
| `contractType` | string | No | `""` | Narrow results by contract type: `permanent`, `temporary`, `internship`, `work_study`, `freelance`, `icvp`, `other`, `part_time`. |
| `remoteWork` | string | No | `""` | Narrow results by remote policy: `no_remote`, `partial`, `occasional`, `full`, `unknown`. |
| `experienceLevel` | string | No | `""` | Narrow results by experience: `less_than_1_year`, `1_to_3_years`, `3_to_5_years`, `5_to_10_years`, `more_than_10_years`. |
| `minimumYearlySalary` | integer | No | — | Narrow results by minimum yearly salary. |
| `companySize` | string | No | `""` | Narrow results by headcount band: `1_to_15`, `15_to_50`, `50_to_250`, `250_to_2000`, `more_than_2000`. |
| `jobLanguage` | string | No | `""` | Narrow results by job language: `fr`, `en`, `de`, `es`, `it`, `pt`, `cs`, `nl`. |
| `industrySector` | string | No | — | Narrow results by industry sector. |
| `jobCategory` | string | No | — | Narrow results by job category. |
| `maxItems` | integer | No | `100` | Maximum number of job listings to scrape. |
| `includeDetails` | boolean | No | `true` | If enabled, fetches full descriptions, profile texts, tools, benefits and video links from each job's details API. Turn off for ultra-fast, shallow scrapes. |

#### 💡 Input Examples

**Fresh remote engineering roles in France**

```json
{
  "query": "backend engineer",
  "location": "Paris, France",
  "locationRadius": "50",
  "remoteWork": "full",
  "datePosted": "past_week",
  "sortBy": "newest",
  "maxItems": 200
}
```

**Salary benchmarking for senior product roles**

```json
{
  "query": "product manager",
  "location": "Worldwide",
  "experienceLevel": "5_to_10_years",
  "minimumYearlySalary": 60000,
  "contractType": "permanent",
  "maxItems": 500,
  "includeDetails": true
}
```

**Fast shallow sweep for daily monitoring**

```json
{
  "query": "",
  "location": "Lyon, France",
  "companySize": "50_to_250",
  "datePosted": "today",
  "maxItems": 1000,
  "includeDetails": false
}
```

***

### 📤 Output

Each dataset item is one job listing with its employer profile attached. The example below uses the real output field names with representative values, trimmed for readability.

```json
{
  "id": "8f2a1c44-91de-4f0b-b0a7-3c9de2f4a112",
  "reference": "WTTJ-2026-08-4412",
  "name": "Senior React Developer",
  "url": "https://www.welcometothejungle.com/en/companies/example-tech/jobs/senior-react-developer",
  "applyUrl": "https://www.welcometothejungle.com/en/companies/example-tech/jobs/senior-react-developer/apply",
  "contractType": "permanent",
  "remote": "partial",
  "language": "en",
  "salaryMin": 55000,
  "salaryMax": 70000,
  "salaryCurrency": "EUR",
  "salaryPeriod": "yearly",
  "experienceLevel": "3_to_5_years",
  "educationLevel": "master",
  "publishedAt": "2026-08-11T09:24:00Z",
  "startDate": "2026-10-01",
  "category": "Tech",
  "subcategory": "Frontend Development",
  "summary": "Join a product team building a design-system-driven React application used by 40,000 daily users.",
  "skills": ["React", "TypeScript", "GraphQL", "Testing Library"],
  "benefits": ["Meal vouchers", "Health insurance", "Two remote days per week"],
  "organizationName": "Example Tech",
  "organizationEmployees": 180,
  "organizationCreationYear": 2016,
  "organizationWebsite": "https://example-tech.com",
  "organizationJobsCount": 14
}
```

#### 🧾 Welcome to the Jungle Job Output Fields

| Field | Type | Description |
|---|---|---|
| `id` | string | integer | Unique identifier of the job listing. |
| `reference` | — | Reference code of the listing. |
| `name` | string | null | Job title. |
| `url` | string | null | Canonical URL of the scraped listing. |
| `applyUrl` | string | null | URL to apply for this job. |
| `contractType` | string | null | Contract type of the job. |
| `remote` | — | Whether and to what extent the job is remote. |
| `language` | string | null | Language of the listing content. |
| `salaryMin` | — | Lower bound of the advertised salary range. |
| `salaryMax` | — | Upper bound of the advertised salary range. |
| `salaryCurrency` | — | Currency of the advertised salary. |
| `salaryPeriod` | — | Period the salary refers to. |
| `experienceLevel` | — | Required experience level. |
| `educationLevel` | — | Required education level. |
| `contractDurationMin` | — | Minimum contract duration. |
| `contractDurationMax` | — | Maximum contract duration. |
| `publishedAt` | string | null | When the listing was published. |
| `startDate` | string | null | Start date of the role. |
| `category` | string | null | Category of the job. |
| `subcategory` | string | null | Sub-category of the job. |
| `sectors` | — | Sectors associated with the listing. |
| `summary` | string | null | Short summary of the job. |
| `description` | string | null | Long-form job description text. |
| `profile` | string | null | Candidate profile sought for the role. |
| `keyMissions` | — | Key missions of the role. |
| `skills` | array | null | Skills required or listed. |
| `tools` | — | Tools used in the role. |
| `benefits` | array | null | Benefits offered. |
| `team` | — | Team context for the role. |
| `recruitmentProcess` | — | Description of the recruitment process. |
| `offices` | — | Office locations associated with the listing. |
| `atsQuestions` | — | ATS questions attached to the application. |
| `applicationFields` | — | Application fields required by the employer. |

#### 🧾 Company & Employer Output Fields

| Field | Type | Description |
|---|---|---|
| `organizationName` | string | null | Name of the hiring organisation. |
| `organizationSlug` | — | Organisation slug used in URLs. |
| `organizationLogo` | — | Organisation logo asset. |
| `organizationCoverImage` | — | Organisation cover image asset. |
| `organizationDescription` | string | null | Description of the organisation. |
| `companySummary` | — | Short company summary. |
| `organizationIndustry` | — | Industry the organisation operates in. |
| `organizationWebsite` | string | null | Organisation website. |
| `organizationEmployees` | — | Number of employees at the organisation. |
| `organizationCreationYear` | — | Year the organisation was founded. |
| `organizationRevenue` | — | Reported organisation revenue. |
| `organizationTurnover` | — | Reported organisation turnover. |
| `organizationAverageAge` | — | Average age of employees. |
| `organizationParityMen` | — | Reported share of men in the workforce. |
| `organizationParityWomen` | — | Reported share of women in the workforce. |
| `organizationLabels` | — | Labels and certifications held by the organisation. |
| `organizationCommitments` | — | Public commitments made by the organisation. |
| `organizationHeadquarter` | — | Headquarters location. |
| `organizationJobsCount` | integer | null | Number of jobs the organisation currently lists. |
| `organizationLinkedin` | — | Organisation LinkedIn profile. |
| `organizationTwitter` | — | Organisation Twitter/X profile. |
| `organizationFacebook` | — | Organisation Facebook profile. |
| `organizationInstagram` | — | Organisation Instagram profile. |
| `organizationHasExternalAts` | — | Whether the organisation uses an external applicant tracking system. |
| `organizationAutomaticEmail` | — | Whether automatic application emails are configured. |
| `organizationGdprSetting` | — | GDPR setting configured by the organisation. |

***

### 💻 How to Use the Welcome to the Jungle Jobs Scraper (Step by Step)

#### Step 1: Define Your Job Search Query

`query` accepts keywords or a job title such as "React Developer" or "Product Designer". Leaving it blank searches all jobs, which is the right choice when you want complete coverage of a location or company-size band rather than a specific role. If your keyword is a common word that appears in many descriptions — "data", "product", "growth" — consider enabling `searchOnlyInJobTitle` so matches are restricted to titles and you are not swamped by roles that merely mention the term in passing.

#### Step 2: Set Location and Radius

`location` defaults to "Worldwide" and accepts natural strings like "Paris, France" or "London". `locationRadius` controls how far around that point results may fall, in kilometres, defaulting to 20. For a dense metropolitan area, 20 to 30 kilometres captures the practical commuting zone. For regional coverage, widen it to 50 or more. If you are specifically after remote roles, pair a wide radius with `remoteWork` set to `full` rather than relying on geography alone.

#### Step 3: Apply the Filters That Match Your Brief

This is where the scraper earns its keep. `contractType` separates permanent roles from internships, freelance work and work-study contracts. `experienceLevel` bands seniority. `companySize` distinguishes early-stage startups from large enterprises. `minimumYearlySalary` removes listings below your threshold. `jobLanguage` and `websiteCountry` control the linguistic scope, which matters a great deal on a board with strong French and English coverage. Applying these at collection time is far more efficient than scraping everything and filtering afterwards.

#### Step 4: Choose Sort Order and Recency

`sortBy` accepts `relevance` or `newest`. Relevance is the better default for research, where you want the strongest matches. Newest is what you want for monitoring, where the goal is catching listings as they appear. Pair it with `datePosted` — `today` for a daily monitoring job, `past_week` for a weekly digest, `past_month` for a broader recruitment-market snapshot. Using `newest` with `any` returns fresh listings but does not restrict how far back the dataset reaches.

#### Step 5: Decide Between Shallow and Detailed Mode

`includeDetails` defaults to `true`, which fetches each job's details endpoint to populate `description`, `profile`, `keyMissions`, `tools`, `benefits` and related fields. That is what you want for content analysis, skills extraction or building a candidate-facing product. Turn it off when you are running a high-volume sweep for monitoring or counting purposes — the shallow mode is dramatically faster and still returns titles, salaries, contract types and company names.

#### Step 6: Set `maxItems` and Run the Scraper

`maxItems` defaults to 100. Start there to confirm your filters return the roles you expect, then scale. Launch from the Apify Console or through the API and watch the log as listings are collected. If early results are dominated by roles you did not intend to capture, stop the run and tighten `searchOnlyInJobTitle`, `jobCategory` or `contractType` rather than letting a large job complete with the wrong data.

#### Step 7: Analyse and Export the Job Data

Export as CSV or Excel for spreadsheet analysis, or pull JSON through the dataset API into a notebook or database. For salary work, filter to records where `salaryMin` and `salaryMax` are populated and group by `experienceLevel`, `category` or `organizationEmployees`. For skills analysis, explode the `skills` array and count frequencies. For employer research, de-duplicate on `organizationName` and keep the company-level fields as a separate table.

***

### 🔌 API Access & Integrations

Run the Welcome to the Jungle jobs scraper and collect results in one call:

```bash
curl -X POST "https://api.apify.com/v2/acts/scrapers-hub~wttj-jobs-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "React Developer",
    "location": "Paris, France",
    "locationRadius": "30",
    "contractType": "permanent",
    "remoteWork": "partial",
    "datePosted": "past_week",
    "sortBy": "newest",
    "maxItems": 200,
    "includeDetails": true
  }'
```

The same run in Python, producing a quick salary summary:

```python
import statistics
from apify_client import ApifyClient

client = ApifyClient("YOUR_TOKEN")

run_input = {
    "query": "product manager",
    "location": "Worldwide",
    "experienceLevel": "5_to_10_years",
    "contractType": "permanent",
    "maxItems": 500,
    "includeDetails": True,
}

run = client.actor("scrapers-hub/wttj-jobs-scraper").call(run_input=run_input)

salaries = []
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    lo, hi = item.get("salaryMin"), item.get("salaryMax")
    if lo and hi:
        salaries.append((lo + hi) / 2)
    print(item.get("name"), "|", item.get("organizationName"), "|", item.get("contractType"))

if salaries:
    print("Median advertised midpoint:", statistics.median(salaries))
```

The Actor also connects to Zapier, Make, Google Sheets, Slack and any custom endpoint via Apify webhooks, so a scheduled run can push new listings into a spreadsheet, an ATS or a hiring channel automatically.

***

### 💡 Best Use Cases for Welcome to the Jungle Jobs Data

#### 💰 Salary Benchmarking and Compensation Research

Because `salaryMin`, `salaryMax`, `salaryCurrency` and `salaryPeriod` are structured fields, you can build genuine compensation benchmarks rather than estimates. Segment by `experienceLevel`, `category` and `organizationEmployees` to see how advertised pay moves with seniority, function and company size across the market.

#### 🧭 Job Board Aggregation and Vertical Search

The combination of `name`, `url`, `applyUrl`, `contractType`, `remote` and `publishedAt` gives you everything needed to populate a niche job board or vertical search product. `organizationHasExternalAts` tells you whether an application will hand off to a third-party ATS, which matters when designing an apply flow.

#### 📈 Hiring Trend and Labour Market Analysis

Scraping on a schedule and tracking listing volume by `category`, `subcategory` and `sectors` over time reveals which functions are expanding and which are contracting. `publishedAt` provides the time axis, and `remote` shows how remote-work policy is shifting across a market.

#### 🛠️ Skills Demand and Curriculum Planning

Exploding the `skills` and `tools` arrays across a large sample produces a frequency ranking of what employers actually ask for. Training providers, bootcamps and internal L\&D teams use exactly this signal to decide what to teach, and `experienceLevel` shows at which career stage each skill becomes a requirement.

#### 🏢 Employer Brand and Competitor Research

`organizationEmployees`, `organizationCreationYear`, `organizationParityMen`, `organizationParityWomen`, `organizationAverageAge`, `organizationLabels` and `organizationCommitments` form a rich employer-brand dataset. Recruitment marketers use it to see how competitors present themselves and which commitments are becoming table stakes in a sector.

#### 🎯 Recruitment Lead Generation

`organizationJobsCount` identifies companies hiring at volume — the best possible prospects for a recruitment agency or HR software vendor. Pair it with `organizationWebsite`, `organizationLinkedin` and `organizationHeadquarter` to build an outreach list of actively growing employers.

#### 🤖 Candidate Matching and Job Alert Products

With `description`, `profile`, `keyMissions`, `skills` and `benefits` populated in detailed mode, each listing becomes a document suitable for semantic matching against candidate profiles. `applyUrl` closes the loop by giving matched candidates a direct route to apply.

***

### ⚙️ Tips for Better Welcome to the Jungle Jobs Scraping Results

- **Turn off `includeDetails` for volume runs.** Shallow mode is far faster and still returns titles, salaries, contract types and company names — plenty for monitoring and counting work.
- **Enable `searchOnlyInJobTitle` for generic keywords.** Terms like "data", "product" or "growth" appear in countless descriptions; restricting to titles sharpens results dramatically.
- **Set `websiteCountry` and `jobLanguage` deliberately.** The board carries strong French and English coverage; leaving language filtering at the default can silently exclude a large part of the market you care about.
- **Pair `sortBy: newest` with a `datePosted` window.** Sorting by newest alone does not bound how far back the dataset reaches; combining it with `today` or `past_week` is what makes a monitoring run efficient.
- **Widen `locationRadius` before broadening `query`.** For regional coverage, increasing the radius keeps role relevance intact, whereas loosening the keyword introduces roles you did not want.
- **Treat salary fields as optional.** Not every employer discloses pay, so filter to records where `salaryMin` and `salaryMax` are populated before running any compensation analysis.

***

### 🛠️ Troubleshooting

**Why are salary fields empty on many listings?**
Employers are not obliged to publish compensation, so `salaryMin`, `salaryMax`, `salaryCurrency` and `salaryPeriod` are only populated when the listing discloses them. For benchmarking, filter to records where they are present rather than treating nulls as zero.

**Why is `description` empty even though the job clearly has one?**
`includeDetails` was almost certainly set to `false`. Shallow mode deliberately skips the per-job details request, which is what makes it fast. Re-run with `includeDetails` enabled to populate `description`, `profile`, `keyMissions`, `tools` and `benefits`.

**The run returned fewer listings than `maxItems`.**
Your filters have narrowed the result set below that number. Combining a narrow `query`, a tight `locationRadius`, a specific `contractType` and a `datePosted` window can easily leave only a handful of matching roles. Relax one filter at a time to see which is the binding constraint.

**My results include roles that do not match my keyword.**
The search matches across listing content by default. Set `searchOnlyInJobTitle` to `true` to restrict matching strictly to job titles, and consider using `jobCategory` to constrain the functional area as well.

**Runs with details enabled are slow on large `maxItems` values.**
Detailed mode issues an additional request per listing, so runtime scales with listing count. Either reduce `maxItems`, or split the work into several narrower runs by location or category so results become available incrementally.

***

### ❓ Frequently Asked Questions About Welcome to the Jungle Jobs Scraping

**What does the Welcome to the Jungle jobs scraper do?**
It searches welcometothejungle.com for job listings matching your query and filters, then returns each listing as a structured record with role details, salary fields, skills, description and a full company profile.

**Do I need a Welcome to the Jungle account?**
No. The scraper works with publicly accessible job listings and does not require login credentials.

**Can I search all jobs without a keyword?**
Yes. Leave `query` blank and the scraper searches all jobs, which is the right approach when your filter is geographic, sector-based or company-size-based rather than role-based.

**How do I search a specific city?**
Set `location` to a natural string such as "Paris, France" and adjust `locationRadius` to control how far around it results may fall. Use "Worldwide" for global coverage.

**Which contract types can I filter by?**
Permanent, temporary, internship, work-study, freelance, international corporate volunteer programme, part-time and other.

**Can I filter for remote jobs?**
Yes. `remoteWork` accepts no remote work, partial, occasional, fully remote and unknown, and the resulting policy is returned in the `remote` output field.

**Does the scraper return salary information?**
Yes, where the employer publishes it. Salary arrives as four separate fields — `salaryMin`, `salaryMax`, `salaryCurrency` and `salaryPeriod` — rather than embedded in free text.

**Can I set a minimum salary threshold?**
Yes. `minimumYearlySalary` filters out listings advertising below the value you specify.

**What is the difference between shallow and detailed mode?**
With `includeDetails` off, the scraper collects listing-level data quickly. With it on, it additionally queries each job's details API for full descriptions, candidate profiles, tools, benefits and video links.

**What company information is included with each job?**
A substantial profile: name, website, industry, headcount, founding year, revenue and turnover, average employee age, gender parity figures, labels, commitments, headquarters, social profiles and current jobs count.

**Can I filter by company size?**
Yes. `companySize` accepts bands of 1-15, 15-50, 50-250, 250-2000 and 2000+ employees.

**How do I get only recently posted jobs?**
Set `datePosted` to `today`, `yesterday`, `past_week` or `past_month`, and pair it with `sortBy: newest` for monitoring workflows.

**Which languages are supported for filtering?**
`jobLanguage` covers French, English, German, Spanish, Italian, Portuguese, Czech and Dutch, while `websiteCountry` filters listings by language or country code and accepts `any` to disable filtering.

**Can I schedule the Welcome to the Jungle jobs scraper?**
Yes. Apify Schedules run it on a cron expression, which is the standard setup for daily new-listing monitoring and weekly hiring-trend snapshots.

**What export formats are available?**
Apify datasets export as JSON, JSONL, CSV, Excel, XML and RSS from the Console, and are also accessible through the dataset API for direct integration.

***

### 🆘 Support & Feedback

Something not behaving as expected? Report it on the **Issues** tab of the Actor page, including your input configuration and the run ID so the problem can be reproduced quickly.

Need a custom build? For extra fields, different filter behaviour, higher-volume scheduling or direct integration with your ATS or data warehouse, get in touch at **scraperhubapi@gmail.com** with a short description of what you need.

If the Welcome to the Jungle jobs scraper is useful to you, please leave a review on the Apify Store. Reviews help other recruiters and analysts find the tool and guide what gets improved next.

***

### ⚖️ Disclaimer

This Welcome to the Jungle jobs scraper collects publicly available job listings and the company information published alongside them. It does not access private candidate data, log into accounts, or bypass any authentication or access control.

You are responsible for how the collected job data is used. While job listings are largely corporate rather than personal information, records may still include named contacts, recruiter details or other personal data. Where that applies, obligations arise under the GDPR, the CCPA and comparable privacy regimes: establish a lawful basis, minimise what you retain, secure it appropriately and delete it when it is no longer needed.

Respect the terms of service of welcometothejungle.com and any employer site you follow through to, along with applicable rate limits. Job descriptions and employer branding assets remain the intellectual property of their owners; republishing them verbatim may require permission, and using the data to spam employers or candidates is not acceptable.

If you would like data relating to you or your organisation removed from a dataset produced by this Actor, contact **scraperhubapi@gmail.com** and the request will be handled promptly.

# Actor input Schema

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

Keywords to search for (e.g. 'React Developer', 'Product Designer'). Leave blank to search all jobs.

## `location` (type: `string`):

Location to search in (e.g. 'Paris, France', 'London'). Use 'Worldwide' for global listings.

## `locationRadius` (type: `string`):

Distance radius in kilometers around the specified location.

## `searchOnlyInJobTitle` (type: `boolean`):

If enabled, restricts search matches strictly to job titles.

## `websiteCountry` (type: `string`):

Language/country to filter listings (e.g. 'en', 'fr', 'es', 'cs', 'sk'). Use 'any' to disable filtering.

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

Sort order of job listings.

## `datePosted` (type: `string`):

Time range of job publication.

## `contractType` (type: `string`):

Narrow down results by contract type.

## `remoteWork` (type: `string`):

Narrow down results by remote policy.

## `experienceLevel` (type: `string`):

Narrow down results by experience level.

## `minimumYearlySalary` (type: `integer`):

Narrow down results by minimum yearly salary.

## `companySize` (type: `string`):

Narrow down results by company size.

## `jobLanguage` (type: `string`):

Narrow down results by job language.

## `industrySector` (type: `string`):

Narrow down results by industry sector.

## `jobCategory` (type: `string`):

Narrow down results by job category.

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

Maximum number of job listings to scrape.

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

If enabled, fetches full descriptions, profile texts, tools, benefits, and video links by querying each job's details API. Turn off for ultra-fast, shallow scrapes.

## Actor input object example

```json
{
  "query": "React Developer",
  "location": "Paris, France",
  "locationRadius": "20",
  "searchOnlyInJobTitle": false,
  "websiteCountry": "en",
  "sortBy": "relevance",
  "datePosted": "any",
  "contractType": "",
  "remoteWork": "",
  "experienceLevel": "",
  "companySize": "",
  "jobLanguage": "",
  "maxItems": 100,
  "includeDetails": true
}
```

# Actor output Schema

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

Records scraped by Welcome to the Jungle (WTTJ) Jobs Scraper, stored in the run's default dataset.

# 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": "React Developer",
    "location": "Paris, France",
    "locationRadius": "20",
    "websiteCountry": "en",
    "maxItems": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapers-hub/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": "React Developer",
    "location": "Paris, France",
    "locationRadius": "20",
    "websiteCountry": "en",
    "maxItems": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("scrapers-hub/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": "React Developer",
  "location": "Paris, France",
  "locationRadius": "20",
  "websiteCountry": "en",
  "maxItems": 100
}' |
apify call scrapers-hub/wttj-jobs-scraper --silent --output-dataset

```

## MCP server setup

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