# Theladders Jobs Search Scraper (`stealth_mode/theladders-jobs-search-scraper`) Actor

Scrape structured job listings from TheLadders.com including salary bands, remote flags, company info, and location data. Perfect for recruiters, job aggregators, and compensation analysts targeting the $100K+ job market.

- **URL**: https://apify.com/stealth_mode/theladders-jobs-search-scraper.md
- **Developed by:** [Stealth mode](https://apify.com/stealth_mode) (community)
- **Categories:** Automation, Developer tools, Jobs
- **Stats:** 2 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 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.
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

## TheLadders.com Jobs Scraper: Extract High-Salary Job Listings at Scale

***

### What Is TheLadders.com?

TheLadders.com is a premium job platform focused on high-salary professional roles, typically targeting positions in the $100,000+ range. It serves executives, senior engineers, finance professionals, and other experienced candidates across industries. Because listings are curated for high-value roles, the data found here — particularly compensation bands and seniority signals — is especially valuable for market research and talent intelligence work.

Manually collecting this data across hundreds of search pages is impractical. The **TheLadders.com Jobs Scraper** automates extraction from search result pages, returning clean, structured records for each listing.

***

### Overview

The **TheLadders Jobs Scraper** targets job search result pages and extracts up to 28 fields per listing. It is suited for:

- **Recruiters** monitoring the premium job market by industry or location
- **Compensation analysts** benchmarking salary bands across roles
- **Job board developers** aggregating high-salary listings
- **HR researchers** studying remote work trends and hiring patterns in senior roles

***

### Input Format

The Actor supports **two scraping modes** — use only **one at a time**:

1. **Scrape by URLs** — scrape data directly from a list of TheLadders job search result URLs.

```json
{
  "urls": [
    "https://www.theladders.com/jobs/engineering-construction-jobs?sort=ByRelevance&page=2"
  ],
  "ignore_url_failures": true,
  "max_items_per_url": 50
}
```

2. **Scrape by search filters** — scrape data using a keyword and additional filters (location, distance, salary range, industry, etc.) instead of providing URLs.

```json
{
    "keyword": "ai",
    "location": "90001",
    "distance": "80",
    "sort_by": "PUBLICATION_DATE",
    "remote_flag": "Hybrid",
    "published_at": "30",
    "min_salary": "200000",
    "max_salary": "430000",
    "position": "6",
    "industry": "2003",
    "page": 1,
    "max_items_per_url": 200
}

```

There is also a **General settings** group that applies to both modes.

#### 1. Scrape by URLs

Use this mode when you already have specific search result URLs. When this mode is used, all options in the "Scrape by search filters" section will be disabled.

| Field | Type | Default | Description |
|---|---|---|---|
| `urls` | `array` | *(required)* | One or more TheLadders job search result page URLs to scrape. You can paste URLs one by one, or use the Bulk edit section to add a prepared list. You can pre-filter by category, keyword, or sort order directly via URL parameters before passing it to the scraper. |
| `ignore_url_failures` | `boolean` | `true` | If `true`, the scraper skips failed URLs and continues instead of stopping the entire run. Recommended for bulk URL lists. |

> **Tip:** Use TheLadders' built-in filters (industry, location, remote) in the URL before passing it to the scraper to pre-segment your dataset.

#### 2. Scrape by search filters

Use this mode when you want to search using a keyword and additional filter attributes instead of scraping by URLs. If you use this mode, leave the `urls` field above empty.

| Field | Type | Default | Description |
|---|---|---|---|
| `keyword` | `string` | — | The keyword to search for. |
| `location` | `string` | — | The location to search for (City, Postal Code, State). |
| `distance` | `string` (`8`, `16`, `40`, `80`, `160`, `2000`) | — | Search radius: **5 Miles** (`8`), **10 Miles** (`16`), **25 Miles** (`40`), **50 Miles** (`80`), **100 Miles** (`160`), **Anywhere** (`2000`). |
| `sort_by` | `string` (`SCORE`, `PUBLICATION_DATE`) | — | Sort results by **Relevance** (`SCORE`) or **Published date** (`PUBLICATION_DATE`). |
| `remote_flag` | `string` (`In-Person`, `Hybrid`, `Remote`) | — | Filter by work arrangement: In-Person, Hybrid, or Remote. |
| `min_salary` | `string` | — | Minimum salary to search for (range: 0–490,000). |
| `max_salary` | `string` | — | Maximum salary to search for (range: 110,000–500,000). |
| `published_at` | `string` (`""`, `6`, `1`, `3`, `7`, `30`) | — | Filter by publish date: Any (empty), Last 6 hours (`6`), Last 24 hours (`1`), Last 3 days (`3`), Last 7 days (`7`), Last 30 days (`30`). |
| `position` | `string` (`""`, `6`, `1`, `2`, `3`, `4`, `8`) | — | Seniority level: Any (empty), Senior Individual Contributor (`6`), C-Suite (`1`), Vice President (`2`), Director (`3`), Manager (`4`), Junior Individual Contributor (`8`). |
| `industry` | `string` (`2001`–`2022`) | — | Industry category, e.g. Consumer Technology (`2003`), Aerospace & Defense (`2001`), Business Services (`2002`), Education, Government & Non-Profit (`2004`), Energy & Utilities (`2005`), Enterprise Technology (`2006`), Finance & Insurance (`2007`), Food & Beverages (`2008`), Healthcare (`2009`), Hospitality & Recreation (`2010`), Hospitals & Medical Centers (`2011`), Information Technology (`2012`), Legal & Accounting (`2013`), Manufacturing & Automotive (`2014`), Media (`2015`), Pharmaceuticals & Biotech (`2016`), Real Estate & Construction (`2017`), Retail & Consumer Goods (`2018`), Staffing (`2019`), Technical Services (`2020`), Telecommunications & Hardware (`2021`), Transportation (`2022`). |
| `page` | `integer` | — | The page number to start scraping from. |

#### 3. General settings

Applies to both scraping modes above.

| Field | Type | Default | Description |
|---|---|---|---|
| `max_items_per_url` | `integer` | `20` | Maximum number of job records to collect per URL/search. Increase to `50`+ for larger runs. |
----------------------------------------------------------------------------------------------------------------------------------------

### Output Format

**Sample output**

```json
{
  "job_location_id": {
    "id": "86967919",
    "numeric_id": 86967919
  },
  "job_status": "Approved",
  "promoted_label_visible": false,
  "company_name": "Appcast",
  "county": "MARION",
  "years_experience": "5 - 7",
  "posting_date": "May 19, 2026, 1:59:03 AM",
  "title": "Roadway Engineer II",
  "promoted": false,
  "lower_band": 74800,
  "candidate_residency": [],
  "compensation_bonus": "",
  "industry_id": 2022,
  "posted_dates": [
    {
      "posting_date": "May 19, 2026, 1:59:03 AM"
    }
  ],
  "remote_flag": "In-Person",
  "industry_name": "Transportation",
  "is_ladders_estimate": false,
  "compensation_other": "",
  "active": true,
  "recruiter_anonymous": false,
  "short_description": "Empower your career by leading roadway engineering projects, from design to implementation, ensuring quality deliverables. Collaborate with diverse teams and mentor emerging professionals while driving innovative infrastructure solutions.",
  "allow_external_apply": true,
  "salary_is_confidential": false,
  "zipcode": "46227",
  "external_application_url": "https://parsons.wd5.myworkdayjobs.com/Search/job/US---IN-Indianapolis/Roadway-Engineer-II_R180083-1",
  "upper_band": 130900,
  "location": "Indianapolis, IN",
  "locations": [
    {
      "id": "86967919",
      "text": "Indianapolis, IN",
      "seo_slug": "roadway-engineer-ii-appcast-indianapolis-in_86967919",
      "active": true,
      "coords": {
        "latitude": 39.6791,
        "longitude": -86.1278
      },
      "zipcode": "46227",
      "brokers": []
    }
  ]
}
```

Each job listing returns up to 28 structured fields:

#### Identification & Listing Metadata

| Field | Meaning |
|---|---|
| `Job Location ID` | Internal identifier linking the job to a specific location record |
| `Job Status` | Current status of the listing (e.g., active, filled) |
| `Active` | Boolean flag indicating whether the listing is currently live |
| `Posting Date` | Date the job was first published |
| `Posted Dates` | Full date range object, may include creation and update timestamps |
| `Promoted` | Whether the listing is a paid promoted placement |
| `Promoted Label Visible` | Whether the "Promoted" label is shown to candidates on the listing |

#### Job Details

| Field | Meaning |
|---|---|
| `Title` | Job title as displayed on TheLadders |
| `Short Description` | Brief summary or snippet of the job description |
| `Years Experience` | Minimum years of experience required for the role |
| `Industry ID` | Internal identifier for the job's industry category |
| `Industry Name` | Human-readable industry label (e.g., Engineering, Finance) |
| `Remote Flag` | Indicates whether the role is fully remote, hybrid, or on-site |

#### Company & Recruiter

| Field | Meaning |
|---|---|
| `Company Name` | Name of the hiring company |
| `Recruiter Anonymous` | If `true`, the employer has chosen to remain anonymous |

#### Compensation

| Field | Meaning |
|---|---|
| `Lower Band` | Minimum salary figure for the role |
| `Upper Band` | Maximum salary figure for the role |
| `Is Ladders Estimate` | If `true`, salary is estimated by TheLadders, not provided by the employer |
| `Salary Is Confidential` | Employer has explicitly marked salary as confidential |
| `Compensation Bonus` | Bonus or incentive compensation details, if available |
| `Compensation Other` | Other compensation components (e.g., equity, benefits notes) |

#### Location

| Field | Meaning |
|---|---|
| `Location` | Primary job location as a formatted string |
| `Locations` | Full location object(s), may include multiple sites |
| `Zipcode` | ZIP code associated with the primary job location |
| `County` | County or sub-regional area of the listing |
| `Candidate Residency` | Any residency requirements specified by the employer |

#### Application

| Field | Meaning |
|---|---|
| `Allow External Apply` | Whether candidates can apply via an external URL |
| `External Application URL` | Direct link to the employer's own application page, if external |

***

### How to Use

1. **Build your search URL** — Run a search on TheLadders.com with your desired filters (job category, location, remote, sort order). Copy the full URL from your browser.
2. **Configure the input** — Paste one or more URLs into the `urls` array.
3. **Set item limits** — Adjust `max_items_per_url` based on how many results you need. TheLadders typically paginates at ~25 results per page, so combine multiple page URLs for larger datasets.
4. **Run and export** — Start the scraper and download results as JSON, CSV, or Excel.

**Best practices:**

- Paginate manually by incrementing the `page=` parameter across multiple URLs for full category coverage.
- Use `ignore_url_failures: true` whenever running batches to avoid interruptions from occasional 404s or empty pages.
- Cross-reference `Is Ladders Estimate` when using salary data for research — estimated figures may differ from employer-reported ranges.

***

### Use Cases & Business Value

- **Salary benchmarking:** Collect `Lower Band` / `Upper Band` data across industries to build compensation reports
- **Remote work analysis:** Filter by `Remote Flag` to map remote hiring trends in senior roles
- **Recruiter intelligence:** Track which companies are hiring anonymously or promoting listings heavily
- **Job aggregation:** Feed structured TheLadders listings into internal portals or BI dashboards

***

### Conclusion

The **TheLadders.com Jobs Scraper** provides reliable, structured access to one of the most concentrated sources of senior-level job data available online. With compensation fields, remote indicators, and company metadata all captured in a single run, it delivers immediate value for anyone working in talent intelligence, HR analytics, or job market research.

# Actor input Schema

## `urls` (type: `array`):

Add the URLs of the Jobs list urls you want to scrape. You can paste URLs one by one, or use the Bulk edit section to add a prepared list.

## `ignore_url_failures` (type: `boolean`):

If true, the scraper will continue running even if some URLs fail to be scraped.

## `keyword` (type: `string`):

Enter the keyword to search for items

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

Enter the location (City, Postal Code, State) to search for items

## `distance` (type: `string`):

Enter the distance to search for items

## `sort_by` (type: `string`):

Sort items by options

## `remote_flag` (type: `string`):

Enter the remote flag to search for items

## `min_salary` (type: `string`):

Enter the min salary to search for items

## `max_salary` (type: `string`):

Enter the min salary to search for items

## `published_at` (type: `string`):

Enter the published at to search for items

## `position` (type: `string`):

Enter the position to search for items

## `industry` (type: `string`):

Enter the industry to search for items

## `page` (type: `integer`):

Specify the page number to start scraping from

## `max_items_per_url` (type: `integer`):

The maximum number of items to scrape per URL.

## Actor input object example

```json
{
  "urls": [
    "https://www.theladders.com/jobs/engineering-construction-jobs?sort=ByRelevance&page=2"
  ],
  "ignore_url_failures": true,
  "max_items_per_url": 20
}
```

# Actor output Schema

## `results` (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 = {
    "urls": [
        "https://www.theladders.com/jobs/engineering-construction-jobs?sort=ByRelevance&page=2"
    ],
    "ignore_url_failures": true,
    "max_items_per_url": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("stealth_mode/theladders-jobs-search-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 = {
    "urls": ["https://www.theladders.com/jobs/engineering-construction-jobs?sort=ByRelevance&page=2"],
    "ignore_url_failures": True,
    "max_items_per_url": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("stealth_mode/theladders-jobs-search-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 '{
  "urls": [
    "https://www.theladders.com/jobs/engineering-construction-jobs?sort=ByRelevance&page=2"
  ],
  "ignore_url_failures": true,
  "max_items_per_url": 20
}' |
apify call stealth_mode/theladders-jobs-search-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,stealth_mode/theladders-jobs-search-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/EYkWEqbVaqWtZerXg/builds/gaupE00gKPSNyL1WU/openapi.json
