# Dice Job Scraper - US Tech Jobs, Salaries & Skills (`webdata_labs/dice-job-scraper`) Actor

Scrape US tech jobs from Dice.com with parsed salary ranges, the full job description and the skills list Dice tags each posting with. Filter by keyword, location, radius, employment type, remote, Easy Apply and visa sponsorship. No login, no API key.

- **URL**: https://apify.com/webdata\_labs/dice-job-scraper.md
- **Developed by:** [WebData Labs](https://apify.com/webdata_labs) (community)
- **Categories:** Jobs, Lead generation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.20 / 1,000 job scrapeds

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

## Dice Job Scraper

Scrapes US tech jobs from [Dice.com](https://www.dice.com) — the board recruiters actually
use to fill engineering, data and infrastructure roles.

Most Dice scrapers hand you the search listing: a title, a company, a location and a summary
cut off mid-sentence. This one also opens each job's own page, so you get the **complete
description**, the **skills Dice tagged the posting with**, and a **salary parsed into
numbers** instead of a string you have to clean up yourself.

No login, no API key, no proxy configuration to think about.

### What you get per job

```json
{
  "jobId": "1d79deed-7860-4d5c-8a3a-1e7db2ab62c6",
  "legacyJobId": "3ccd3a6aa0957abf546a91b7c14e0405",
  "title": "Machine Learning Engineer / UNICORN / Hybrid in SF",
  "companyName": "Motion Recruitment Partners, LLC",
  "companyId": "10105282",
  "companyUrl": "https://www.dice.com/company/10105282",
  "companyLogoUrl": "https://d3qscgr6xsioh.cloudfront.net/mYivInZASxip5W4N3Dhp_transformed.png?format=webp",
  "location": "San Francisco, California, USA",
  "city": "San Francisco",
  "state": "California",
  "stateCode": "CA",
  "country": "USA",
  "postalCode": "94120",
  "workFromHome": false,
  "employmentType": "Full-time",
  "employerType": "Recruiter",
  "easyApply": true,
  "willingToSponsor": false,
  "salaryText": "$200000 - $300000",
  "salaryMin": 200000.0,
  "salaryMax": 300000.0,
  "salaryCurrency": "USD",
  "salaryPeriod": "year",
  "postedDate": "2026-08-20T00:03:43Z",
  "modifiedDate": "2026-09-06T00:07:40Z",
  "expiresAt": "2026-10-07T00:07:40.000Z",
  "skills": ["Salesforce.com", "Research and Development", "Roadmaps", "Innovation", "Python", "TensorFlow", "PyTorch", "Time Series", "..."],
  "summary": "A health technology company at the top of their industry is seeking a Machine Le ...",
  "descriptionText": "A health technology company at the top of their industry is seeking a Machine Learning Engineer to join its re ...",
  "descriptionHtml": "A health technology company at the top of their industry is ...",
  "url": "https://www.dice.com/job-detail/1d79deed-7860-4d5c-8a3a-1e7db2ab62c6",
  "searchTerm": "machine learning",
  "scrapedAt": "2026-09-06T10:06:40Z"
}
```

`skills`, `descriptionText`, `descriptionHtml`, `expiresAt` and `postalCode` are filled only
when **Include full description and skills** is on. Everything else comes back on every run.

### Input

| Field | Type | Default | What it does |
|---|---|---|---|
| `searchTerms` | array | `[]` | Keywords, one search per term. **Leave empty to scrape the whole board** — Dice serves about 104,000 live US jobs with no keyword at all. |
| `location` | string | — | Free text, geocoded by Dice: `New York, NY, USA`, `Texas, USA`, `94105`, or `Remote`. Empty searches the whole United States. |
| `radiusMiles` | integer | `30` | How far from `location` to search. Ignored when no location is set. |
| `postedWithinDays` | select | any time | `1`, `3` or `7`. See the note below on why there is no 30-day option. |
| `employmentType` | select | any | Full-time, Part-time, Contract, Third party. |
| `employerType` | select | any | Direct hire (the employer posted it) or Recruiter (a staffing agency did). |
| `remoteOnly` | boolean | `false` | Dice's own Remote workplace filter. |
| `easyApplyOnly` | boolean | `false` | Jobs you can apply to inside Dice. |
| `willingToSponsorOnly` | boolean | `false` | Employers who marked the posting as willing to sponsor a visa. |
| `sortBy` | select | relevance | `relevance` or `datePosted` (newest first). |
| `includeDescription` | boolean | `false` | Also opens each job's page for the full description and the skills list. One extra request per job. |
| `maxResults` | integer | `200` | Stop after this many jobs. |
| `onlyNewJobs` | boolean | `false` | Return only jobs no previous run has delivered. |

### Watch out for these (they are Dice's limits, not ours)

**One search stops at 10,000 jobs.** Dice refuses to page past its 10,000th result for any
single query — and it reports that refusal as an HTTP 429 with a message about crawling,
which looks like a rate limit but is a fixed ceiling. To go deeper, split the work: several
`searchTerms`, or the same term across several `location` values. A run that hits the
ceiling says so in the run summary rather than failing.

**Dice only offers 1, 3 and 7 day windows.** There is no 14- or 30-day filter on Dice, and
sending one makes Dice quietly return the *unfiltered* board instead of erroring. That is
why `postedWithinDays` has three options: a fourth would be a lie. The same goes for the
other filters — anything Dice would silently swallow is rejected here with a warning in the
log, so a filtered run is really filtered.

**`workFromHome` is not the same thing as `remoteOnly`.** Dice keeps two separate concepts:
the Remote *workplace type* that `remoteOnly` filters on, and a per-posting
work-from-home flag. Of 200 jobs Dice returned for its own Remote filter, 195 carried the
work-from-home flag as false. We report the raw flag under its own name rather than
pretending they are one field.

**Salary is not always a number.** Roughly two thirds of Dice postings carry a salary, and
some of those say `Depends on Experience` or `To define` rather than a figure. Those rows
keep `salaryText` and leave `salaryMin`/`salaryMax` null instead of inventing a number.

**Dice is a United States board.** For the same query it serves about 104,000 US jobs, 95
Canadian and 1 British. There is no country input because there is nothing outside the US
worth offering.

### Monitoring a search

Turn on `onlyNewJobs` and put the Actor on a schedule. It remembers every job it has
delivered and returns only the ones it has not, then stops as soon as a page holds nothing
new — so a daily run bills you for the day's new postings and nothing else. Pair it with
`sortBy: datePosted` and `postedWithinDays: 1` for a clean daily feed.

The memory persists across runs of the *same* Actor or Task. Running it as a saved Task and
running it directly keep separate histories.

### Ready-made searches

Each of these is a saved task you can run as-is or copy and edit:

| Task | What it returns |
|---|---|
| [Python jobs in New York](https://apify.com/webdata_labs/dice-job-scraper/examples/dice-python-jobs-in-new-york) | Python roles within 30 miles of NYC |
| [Remote software engineer jobs](https://apify.com/webdata_labs/dice-job-scraper/examples/dice-remote-software-engineer-jobs) | Everything Dice flags as Remote |
| [Data engineer jobs in San Francisco](https://apify.com/webdata_labs/dice-job-scraper/examples/dice-data-engineer-jobs-in-san-francisco) | Data engineering around the Bay |
| [DevOps jobs posted today](https://apify.com/webdata_labs/dice-job-scraper/examples/dice-devops-jobs-posted-today) | Last 24 hours, newest first |
| [Contract developer jobs in Texas](https://apify.com/webdata_labs/dice-job-scraper/examples/dice-contract-jobs-in-texas) | Contract roles with hourly rates |
| [Visa sponsorship tech jobs](https://apify.com/webdata_labs/dice-job-scraper/examples/dice-visa-sponsorship-tech-jobs) | Employers offering sponsorship |
| [Jobs with full descriptions and skills](https://apify.com/webdata_labs/dice-job-scraper/examples/dice-jobs-with-full-descriptions) | The complete description plus skills |
| [New jobs since the last run](https://apify.com/webdata_labs/dice-job-scraper/examples/dice-new-jobs-daily-monitor) | Delta mode on a daily schedule |

### Pricing

Pay per result: you are charged for each job returned, and nothing else. A run that Dice
answers with no matches costs nothing.

### 🧩 Related Actors

- [Company Career Page Jobs API](https://apify.com/webdata_labs/company-career-page-jobs-api) - read jobs off a company's own careers page when it is not on any board.
- [ATS Hiring Monitor API](https://apify.com/webdata_labs/ats-hiring-monitor-api) - watch a set of companies and report only what changed since the last run.
- [BuiltIn Jobs Scraper](https://apify.com/webdata_labs/builtin-jobs-scraper) - US tech-hub roles with the skills each posting asks for.
- [Wellfound Jobs Scraper](https://apify.com/webdata_labs/wellfound-jobs-scraper) - startup roles with equity ranges, funding stage and the ATS each company runs.
- [Website Email Scraper](https://apify.com/webdata_labs/website-contact-extractor) - turn any list of domains into emails, phone numbers and social profiles.

### FAQ

**Do I need a Dice account?** No. Nothing here is behind a login.

**Can I get the applicant's or recruiter's contact details?** No. Dice does not publish
them, and this Actor does not guess at them.

**Why is `summary` shorter than `descriptionText`?** `summary` is what Dice's search API
returns and it is truncated at roughly 500 characters. The full text needs
`includeDescription`, which opens the job's own page.

**Some jobs come back with an empty `skills` list.** Those postings genuinely have no skills
tagged on Dice — we checked the pages. How many carry them depends on the query: 37 of 40 on
a `python` search, 41 of 60 on `machine learning`.

**How fresh is the data?** Live. Each run queries Dice at the moment it runs; `postedDate`
and `modifiedDate` come straight from Dice.

# Actor input Schema

## `searchTerms` (type: `array`):

Keywords to search, one search per term. Leave empty to scrape the whole board without a keyword.

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

Free text, geocoded by Dice: a city (New York, NY, USA), a state (Texas, USA), a ZIP code (94105), or Remote. Leave empty to search the whole United States.

## `radiusMiles` (type: `integer`):

How far from the location to search. Ignored when no location is set.

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

Dice only supports these three windows. There is no 14- or 30-day option on Dice, so we do not offer one.

## `employmentType` (type: `string`):

Dice's own employment-type filter. Any value outside this list is silently ignored by Dice, so the Actor rejects it rather than returning an unfiltered board.

## `employerType` (type: `string`):

Direct Hire means the employer posted it themselves; Recruiter means a staffing agency did.

## `remoteOnly` (type: `boolean`):

Dice's own Remote workplace filter.

## `easyApplyOnly` (type: `boolean`):

Jobs you can apply to inside Dice, without being sent to the employer's own site.

## `willingToSponsorOnly` (type: `boolean`):

Only employers who marked the posting as willing to sponsor.

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

Relevance is Dice's default. Newest first genuinely sorts by posted date.

## `includeDescription` (type: `boolean`):

Fetches each job's own page. This is the only way to get the complete description and the skills list; the search API returns a summary truncated at about 500 characters. Costs one extra request per job, so the run takes longer.

## `maxResults` (type: `integer`):

Stop after this many jobs. Dice itself refuses to page past 10,000 results for any single search, so use several search terms or split by location to go deeper.

## `onlyNewJobs` (type: `boolean`):

Remembers the jobs already delivered and returns only the new ones next time. Use it on a schedule to monitor a search without paying for the same job twice.

## Actor input object example

```json
{
  "searchTerms": [
    "python"
  ],
  "location": "New York, NY, USA",
  "radiusMiles": 30,
  "postedWithinDays": "",
  "employmentType": "",
  "employerType": "",
  "remoteOnly": false,
  "easyApplyOnly": false,
  "willingToSponsorOnly": false,
  "sortBy": "relevance",
  "includeDescription": false,
  "maxResults": 200,
  "onlyNewJobs": false
}
```

# Actor output Schema

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

One row per Dice job, with parsed salary, skills and the full description.

## `overview` (type: `string`):

The same rows, trimmed to the fields most buyers scan first.

## `OUTPUT` (type: `string`):

Counts per search term, how many Dice reported, and any input value Dice would have ignored.

# 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 = {
    "searchTerms": [
        "python"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("webdata_labs/dice-job-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 = { "searchTerms": ["python"] }

# Run the Actor and wait for it to finish
run = client.actor("webdata_labs/dice-job-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 '{
  "searchTerms": [
    "python"
  ]
}' |
apify call webdata_labs/dice-job-scraper --silent --output-dataset

```

## MCP server setup

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