# TheLadders.Com Job Scraper (`unfenced-group/theladders-scraper`) Actor

Scrape professional job listings from TheLadders.com — salary ranges, company names, locations, and full descriptions for $80K+ roles. No API key needed.

- **URL**: https://apify.com/unfenced-group/theladders-scraper.md
- **Developed by:** [Unfenced Group](https://apify.com/unfenced-group) (community)
- **Categories:** Jobs, Automation, Developer tools
- **Stats:** 28 total users, 10 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.19 / 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?

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

## The Ladders Scraper

![theladders-scraper](https://api.apify.com/v2/key-value-stores/ClElVyZWvQgPQIuDL/records/theladders-scraper)

Extract professional job listings from [TheLadders.com](https://www.theladders.com) — one of the US's leading job boards for $80K+ roles. Supports keyword search, location filtering, salary data, full descriptions, and cross-run deduplication. No API key or account required.

***

### Why this scraper?

#### 🔍 Keyword + location search built in

Search by job title and filter by city, state, or region directly from the input — no need to construct URLs manually. Location fallback ensures results even when TheLadders hasn't indexed the exact keyword+location combination.

#### 💰 Salary data on every listing

Every result includes the displayed salary range as text plus parsed `salaryMin` / `salaryMax` / `salaryCurrency` — ready for direct comparison and analysis.

#### 🏢 Full company and location data

With detail fetching enabled: company name, city, state, postal code, and GPS coordinates (latitude/longitude) per listing.

#### 📄 Three description formats

Full job descriptions returned as HTML, plain text, and Markdown — compatible with any downstream pipeline.

#### ⚡ Lightweight — 8× cheaper than alternatives

Runs at 512 MB. Competing scrapers require 4 GB browser instances for the same site.

#### 🔄 Cross-run deduplication (90-day memory)

`skipReposts` mode skips jobs already seen in previous runs. All items carry `isRepost`, `originalPublishDate`, and `originalUrl` for full deduplication visibility without filtering.

#### ↗️ Direct apply detection

`directApply` field flags listings where candidates can apply without leaving TheLadders — useful for funnel analysis and outreach targeting.

***

### Input parameters

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `keywords` | string | — | Job search keywords, e.g. `software engineer`, `product manager` |
| `location` | string | — | City, state, or region, e.g. `New York`, `Texas`, `Remote`. Leave empty for all locations. |
| `maxItems` | integer | 100 | Maximum number of job listings to return (up to 500) |
| `maxPages` | integer | 10 | Max search result pages per keyword (25 jobs/page, max 12) |
| `fetchDetails` | boolean | true | Fetch each job's detail page for company name, full description, exact salary, and `directApply` |
| `skipReposts` | boolean | false | Skip jobs already seen in previous runs (90-day memory) |
| `daysOld` | integer | — | Only return jobs posted within this many days. Requires `fetchDetails: true`. |
| `startUrls` | array | — | Specific TheLadders job or search page URLs to scrape directly |

***

### Output schema

#### Always present

| Field | Type | Description |
|-------|------|-------------|
| `id` | string | Unique numeric TheLadders job ID |
| `url` | string | Full URL to the job listing |
| `title` | string | Job title |
| `locationText` | string | Location as displayed on listing card, e.g. `New York, NY (New York County)` |
| `salaryText` | string | Salary range as displayed, e.g. `$150K - $200K *` |
| `remoteType` | string | Work arrangement from listing badge: `In-Person`, `Remote`, or `Hybrid` |
| `experienceLevel` | string | Experience label shown on card, e.g. `Less than 5 years exp.` |
| `industry` | string | Industry category shown on listing card |
| `postedDateRelative` | string | Relative posting date, e.g. `2 days ago`, `Today` |
| `publishDate` | string | Estimated posting date in `YYYY-MM-DD` format |
| `publishDateISO` | string | Posting date as ISO 8601 timestamp |
| `descriptionSnippet` | string | Short description excerpt from listing card |
| `isRepost` | boolean | Whether this job was seen in a previous run |
| `originalPublishDate` | string | First-seen posting date if `isRepost` is true |
| `originalUrl` | string | First-seen URL if `isRepost` is true |
| `contentHash` | string | 16-char MD5 hash of key fields for change detection |
| `source` | string | Always `theladders.com` |
| `scrapedAt` | string | ISO 8601 timestamp of when this record was scraped |

#### With `fetchDetails: true` (additional fields)

| Field | Type | Description |
|-------|------|-------------|
| `companyName` | string | Hiring company name |
| `city` | string | City from job location |
| `state` | string | US state abbreviation, e.g. `NY` |
| `country` | string | Country code, e.g. `US` |
| `postalCode` | string | Postal code |
| `latitude` | number | Latitude coordinate |
| `longitude` | number | Longitude coordinate |
| `salaryMin` | number | Minimum annual salary in USD |
| `salaryMax` | number | Maximum annual salary in USD |
| `salaryCurrency` | string | Always `USD` |
| `salaryPeriod` | string | Always `YEAR` |
| `employmentType` | string | Employment type: `Full Time`, `Part Time`, `Contractor`, `Temporary`, `Intern` |
| `experienceMonths` | number | Minimum experience in months |
| `directApply` | boolean | Whether candidates can apply directly on TheLadders |
| `datePosted` | string | Exact posting date in `YYYY-MM-DD` format |
| `validThrough` | string | Listing expiry date in `YYYY-MM-DD` format |
| `metaDescription` | string | Page meta description — concise salary/company/location summary |
| `descriptionHtml` | string | Full job description as HTML |
| `descriptionText` | string | Full job description as plain text |
| `descriptionMarkdown` | string | Full job description as Markdown |

#### JSON example

```json
{
  "id": "86532672",
  "url": "https://www.theladders.com/job/software-engineer-current-new-york-ny_86532672",
  "title": "Software Engineer",
  "companyName": "Current",
  "locationText": "New York, NY (New York County)",
  "city": "New York",
  "state": "NY",
  "country": "US",
  "postalCode": "10025",
  "latitude": 40.7983,
  "longitude": -73.9632,
  "salaryText": "$150K - $200K *",
  "salaryMin": 150000,
  "salaryMax": 200000,
  "salaryCurrency": "USD",
  "salaryPeriod": "YEAR",
  "employmentType": "Full Time",
  "industry": "Information Technology",
  "remoteType": "In-Person",
  "directApply": false,
  "experienceLevel": "Less than 5 years exp.",
  "experienceMonths": 12,
  "datePosted": "2026-04-17",
  "validThrough": "2027-04-12",
  "publishDate": "2026-04-17",
  "publishDateISO": "2026-04-17T00:00:00+00:00",
  "postedDateRelative": "1 week ago",
  "metaDescription": "Current is hiring a Software Engineer, with an estimated salary of $150,000 - $200,000. This job in Information Technology is in New York, NY.",
  "descriptionSnippet": "Optimize backend architectures and drive impactful feature development...",
  "descriptionHtml": "<div><strong>SOFTWARE ENGINEER</strong><br/>...</div>",
  "descriptionText": "SOFTWARE ENGINEER We are looking for a Software Engineer...",
  "descriptionMarkdown": "**SOFTWARE ENGINEER**\n\nWe are looking for...",
  "isRepost": false,
  "originalPublishDate": null,
  "originalUrl": null,
  "contentHash": "b23fa10849883534",
  "source": "theladders.com",
  "scrapedAt": "2026-05-04T10:30:00.000Z"
}
```

***

### Examples

**Search for software engineering roles in New York:**

```json
{
  "keywords": "software engineer",
  "location": "New York",
  "maxItems": 100,
  "fetchDetails": true
}
```

**Remote executive roles, past 7 days only:**

```json
{
  "keywords": "vice president",
  "location": "Remote",
  "maxItems": 50,
  "fetchDetails": true,
  "daysOld": 7
}
```

**Scrape specific job or search URLs directly:**

```json
{
  "startUrls": [
    { "url": "https://www.theladders.com/job/software-engineer-current-new-york-ny_86532672" },
    { "url": "https://www.theladders.com/jobs/product-manager-jobs" }
  ],
  "fetchDetails": true
}
```

**Daily feed — new listings only (schedule for daily runs):**

```json
{
  "keywords": "data scientist",
  "maxItems": 200,
  "fetchDetails": true,
  "skipReposts": true,
  "daysOld": 1
}
```

***

### 💰 Pricing

**$1.49 per 1,000 results** — pay only for successfully scraped listings.

| Results | Cost |
|---------|------|
| 100 | ~$0.15 |
| 1,000 | ~$1.49 |
| 10,000 | ~$14.90 |

***

### Performance

| Mode | Approx. throughput |
|------|--------------------|
| List only (`fetchDetails: false`) | ~25 items/min |
| With details (`fetchDetails: true`) | ~5 items/min |

Memory usage is 512 MB — 8× less than browser-based alternatives for the same site.

***

### Known limitations

- Location filtering uses TheLadders' pre-built category pages — not all keyword+location combinations have a dedicated page. The actor automatically falls back to keyword-only search in this case.
- Maximum ~300 results per keyword (12 pages × 25 jobs).
- Salary data is TheLadders' estimated range (marked with `*`) — not always employer-disclosed.
- `daysOld` filter requires `fetchDetails: true` for accurate date comparison.

***

### Technical details

- **Source:** theladders.com — US professional job board focused on $80K+ roles
- **Memory:** 512 MB
- **Bot bypass:** curl\_cffi Chrome 136 TLS impersonation + Apify RESIDENTIAL proxy
- **Dedup store:** KeyValueStore `theladders-job-dedup`, 90-day TTL

***

### Additional services

Need a custom actor, additional filters, scheduled runs, or integration support?\
Contact <info@unfencedgroup.nl> — we build on request.

***

### Related scrapers

Other scrapers in our **Jobs — Finance & Specialist** collection:

- [eFinancialCareers Scraper](https://apify.com/unfenced-group/efinancialcareers-scraper)
- [Workday.com Scraper](https://apify.com/unfenced-group/workday-scraper)
- [Freelancer.com Scraper](https://apify.com/unfenced-group/freelancercom-scraper)
- [TheHub.io Scraper](https://apify.com/unfenced-group/thehub-io-scraper)

***

### Run it on a schedule

This actor is built for repeat use. Set it to run daily, weekly, or hourly, and the data keeps flowing without you touching it.

- **Schedule runs** — open the actor, go to Schedules, and pick a cadence. Each run only charges you for the results it returns.
- **Connect it to your stack** — push results straight to Google Sheets, Slack, a webhook, or your database using Apify Integrations. No glue code needed.
- **Pull results via API** — every run writes a clean dataset you can fetch with one API call, ready for whatever you build on top of it.

Set it once and it runs on its own.

***

### Need a custom scraper?

**[Unfenced Group](https://www.unfencedgroup.nl)** builds Apify actors for any website — for free.

If the site you need isn't in our portfolio yet, just ask. We scope, build, and publish it at no cost to you. You only pay for results — we absorb the compute and proxy costs ourselves. Same pay-per-result pricing, same quality, same standards as every actor in this portfolio.

**Get in touch:** [www.unfencedgroup.nl](https://www.unfencedgroup.nl)

# Actor input Schema

## `keywords` (type: `string`):

Job search keywords, e.g. 'software engineer', 'marketing manager', 'data analyst'.

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

City, state, or region to filter results by, e.g. 'New York', 'Chicago', 'Texas'. Leave empty for all locations.

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

Maximum number of job listings to return.

## `maxPages` (type: `integer`):

Maximum number of search result pages to crawl (25 jobs per page, max 12 pages per search).

## `fetchDetails` (type: `boolean`):

ON: fetches full job description, salary, company info, and all details (slower, higher cost). OFF: returns basic listing info only — title, salary range, location, industry, snippet (faster, default).

## `skipReposts` (type: `boolean`):

Skip jobs already seen in previous runs (cross-run deduplication with 90-day memory).

## `daysOld` (type: `integer`):

Only return jobs posted within this many days. Requires fetchDetails to be enabled for accurate filtering.

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

Specific TheLadders.com job or search URLs to scrape directly. Overrides keyword search when provided.

## Actor input object example

```json
{
  "keywords": "software engineer",
  "location": "",
  "maxItems": 100,
  "maxPages": 10,
  "fetchDetails": false,
  "startUrls": []
}
```

# 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 = {
    "keywords": "software engineer",
    "maxItems": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("unfenced-group/theladders-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 = {
    "keywords": "software engineer",
    "maxItems": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("unfenced-group/theladders-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 '{
  "keywords": "software engineer",
  "maxItems": 100
}' |
apify call unfenced-group/theladders-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,unfenced-group/theladders-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/5qDXjvPCXCoFKExTZ/builds/WydNC5yGkza606SFI/openapi.json
