# Monster.com Multi-City Job Scraper (`axlymxp/monster-multi-scraper`) Actor

Search one job keyword across many US cities on Monster.com in a single run. Jobs found in several areas are returned once, each tagged with its search city: title, company, GPS, salary when listed, remote flag, posting date and apply URL. No login.

- **URL**: https://apify.com/axlymxp/monster-multi-scraper.md
- **Developed by:** [axly](https://apify.com/axlymxp) (community)
- **Categories:** Jobs, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 dataset items

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?

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

## Monster.com Multi-City Job Scraper

Search one job keyword across many US cities on Monster.com in a single run. Give it a keyword and a list of cities; get back one deduplicated dataset where every job is tagged with the city that found it. No login, no cookies, no browser.

Built for recruiters and staffing agencies tracking open roles nationwide, HR and compensation teams comparing demand between metro areas, and job boards or labour-market researchers who want a clean multi-city export instead of stitching together many single-city runs.

If you only need one city, the single-location [Monster.com Job Scraper](https://apify.com/axlymxp/monster-scraper) fits better. This Actor is for several cities at once: nearby cities overlap (New York and Newark share many jobs), so jobs are deduplicated across locations and you are not charged for repeats.

### What you get

Each row starts with easy flat columns, followed by Monster's complete record.

| Field | Description |
| --- | --- |
| `jobId` | Monster's unique job id |
| `searchLocation`, `searchQuery` | The city query that returned the job, and the keyword |
| `title`, `company` | Job title and hiring company |
| `city`, `state`, `postalCode` | Job location (postal code only when Monster provides it) |
| `latitude`, `longitude` | GPS of the job location |
| `remote` | Monster's remote flag |
| `salaryMin`, `salaryMax`, `salaryUnit`, `salaryCurrency` | Salary, only when the employer lists one (a minority of jobs) |
| `employmentType` | For example FULL_TIME, CONTRACTOR, when available |
| `datePosted`, `dateRecency`, `formattedDate` | Posting date and Monster's "6 days ago" text |
| `monsterUrl`, `applyUrl` | Job page on monster.com and the apply link |
| `jobPosting` | Full posting object including the HTML job description and hiring organization details |
| `enrichments`, `apply`, `derivedProperties` | Monster's normalized locations, apply type and flags |

### Use cases

- **Nationwide hiring analysis:** the same role across 20 metros in one export.
- **Salary benchmarking:** collect `salaryMin` / `salaryMax` where listed, per city.
- **Recruiting and lead lists:** companies hiring for a role, with apply links.
- **Job board feeds:** schedule daily runs with `postedWithinDays`.

### Input

| Field | Description |
| --- | --- |
| `query` | Job title or keywords, e.g. `Software Engineer` |
| `locations` | List of cities written `City, ST` (up to 100) |
| `radius` | Search radius around each city, in miles (default 30) |
| `postedWithinDays` | `any`, 1, 3, 7, 14 or 30. Older jobs are skipped and not charged |
| `maxPerLocation` | Jobs to collect per city (default 100, max 501) |
| `maxTotal` | Hard cap on jobs saved in the whole run, also your cost ceiling |
| `deduplicate` | Return a job once even if several cities find it (default on) |
| `concurrency` | Cities searched in parallel, 1-5 |

```json
{
  "query": "Software Engineer",
  "locations": ["New York, NY", "Chicago, IL", "Austin, TX"],
  "radius": 30,
  "maxPerLocation": 10,
  "maxTotal": 30,
  "deduplicate": true
}
```

### Good to know

- **US only.** Monster's mobile data returns jobs for US searches only; other countries came back empty, so only `US` is accepted.
- **501 results per search.** Monster serves at most the first 501 results for a keyword and city. For deeper coverage use more specific keywords or add neighbouring cities.
- **Ranked by relevance, not date.** With `postedWithinDays` set to a short window only some jobs on each page qualify; raise `maxPerLocation` to scan deeper.
- **Salary is sparse.** Most Monster postings do not list pay; those rows have `null` salary fields.
- Listing data is public job-posting information. You are responsible for using it in line with applicable laws and Monster's terms.

### Scheduling and integrations

Run it on a schedule from the Apify Console (for example daily with `postedWithinDays: "1"`) and send new results to Google Sheets, Slack, a webhook or your database through Apify integrations. Results export as JSON, CSV, Excel or via the API. Runs that stop before finishing (for example after a platform migration) resume from where they were when started again with the same input.

### Use from code or AI agents

```python
from apify_client import ApifyClient

client = ApifyClient("<APIFY_TOKEN>")
run = client.actor("axlymxp/monster-multi-scraper").call(run_input={
    "query": "registered nurse",
    "locations": ["Boston, MA", "Denver, CO", "Miami, FL"],
    "maxPerLocation": 50,
    "postedWithinDays": "7",
})
for job in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(job["searchLocation"], job["title"], job["company"], job["salaryMin"])
```

Because it is a plain Apify Actor, it can also be called from AI agents through the Apify MCP server.

### FAQ

**Why did a city return fewer jobs than I asked for?** Either Monster has fewer matches within the radius, the postedWithinDays window removed older ones, or the jobs were already returned for an earlier city (deduplication).

**Which city is shown for a job found by several?** The first one that returned it, in `searchLocation`. The job's own city and state are in `city` and `state`.

**Does it need a login or proxy?** No.

**Something looks wrong or is missing.** Open an issue on the Actor page with the run link.

# Actor input Schema

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

What to search for, for example 'Software Engineer' or 'registered nurse'.

## `locations` (type: `array`):

Cities to search, one per entry, written 'City, ST' (for example 'Austin, TX'). Up to 100 per run.

## `radius` (type: `integer`):

Search radius around each location.

## `postedWithinDays` (type: `string`):

Keep only jobs posted within this window, judged by Monster's posting date. Monster ranks by relevance, so a short window keeps only a fraction of each page; raise 'Max jobs per location' to compensate. Older jobs are skipped and not charged.

## `country` (type: `string`):

Monster's app data only returns US listings, so only US is accepted.

## `maxPerLocation` (type: `integer`):

Stop paging a location after this many jobs. Monster serves at most 501 results per search.

## `maxTotal` (type: `integer`):

Hard cap on jobs saved across all locations (this is also your cost ceiling).

## `deduplicate` (type: `boolean`):

Return a job once even when several of your locations (for example nearby cities) find it. The job is tagged with the first location that found it.

## `concurrency` (type: `integer`):

How many locations are searched at the same time (1-5).

## `pageSize` (type: `integer`):

Jobs fetched per API request (1-20).

## Actor input object example

```json
{
  "query": "Software Engineer",
  "locations": [
    "New York, NY",
    "Chicago, IL"
  ],
  "radius": 30,
  "postedWithinDays": "any",
  "country": "US",
  "maxPerLocation": 10,
  "maxTotal": 20,
  "deduplicate": true,
  "concurrency": 3,
  "pageSize": 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 = {
    "query": "Software Engineer",
    "locations": [
        "New York, NY",
        "Chicago, IL"
    ],
    "maxPerLocation": 10,
    "maxTotal": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("axlymxp/monster-multi-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": "Software Engineer",
    "locations": [
        "New York, NY",
        "Chicago, IL",
    ],
    "maxPerLocation": 10,
    "maxTotal": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("axlymxp/monster-multi-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": "Software Engineer",
  "locations": [
    "New York, NY",
    "Chicago, IL"
  ],
  "maxPerLocation": 10,
  "maxTotal": 20
}' |
apify call axlymxp/monster-multi-scraper --silent --output-dataset

```

## MCP server setup

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