# Dice Jobs Scraper (`axiomworks/dice-jobs-scraper`) Actor

Scrape Dice search results and return job titles, companies, locations, employment types, posting dates, salary, summaries and application links. You can optionally fetch each job page for skill tags, the full description and its closing date, or skip details for a lighter collection.

- **URL**: https://apify.com/axiomworks/dice-jobs-scraper.md
- **Developed by:** [Axiom Works](https://apify.com/axiomworks) (community)
- **Categories:** Jobs
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.35 / 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

## Dice Jobs Scraper

**Returns:** one row per Dice job with title, companyName, location, employmentType, salary, postedDate, skills.
**Input:** `{"searchQueries": ["python developer"], "location": "New York, NY", "includeDetails": false, "maxItems": 20}`
**Best for:** tech recruiting lead lists, salary and rate research, job alert feeds for contract and full-time roles.

```json
{
  "id": "8beb49a9-d16e-4c66-bd56-6c4d97c62df0",
  "title": "Senior Python Developer",
  "companyName": "CBTS",
  "location": "New York, New York, USA",
  "employmentType": "Full-time",
  "postedDate": "2026-10-14T00:01:06Z",
  "workplaceTypes": [
    "On-Site"
  ],
  "applyUrl": "https://www.dice.com/job-detail/8beb49a9-d16e-4c66-bd56-6c4d97c62df0"
}
```

### What does Dice Jobs Scraper do?

Dice Jobs Scraper collects public Dice.com tech job listings by keyword, search URL or job ID. It paginates search results and saves titles, companies, locations, employment types, posting dates, workplace labels, published salaries, summaries and application links.

Set `includeDetails: true` to add skills, full descriptions and closing dates from each job page. The opening input and daily prefill use false for speed; search-result skills, description, validThrough and postalCode then stay null. Direct job targets always fetch details.

Use the Dice scraper and its Apify API for recruiting lists, job alerts and salary research. It reads public pages without logging in.

### What data can you get?

Each job is one record in the dataset. Fields that Dice does not provide for a given job are returned as null, so every record has the same shape.

| Field | Type | Description |
|---|---|---|
| id | string | Stable Dice job identifier (a GUID). Unique within a run. |
| sourceUrl | string | The Dice page the record came from: the search results page or the job page. |
| title | string | Job title. |
| clientBrandId | string | Employer brand ID as published in search results; null for direct job targets. |
| companyName | string | Hiring company or staffing agency name. |
| location | string | Job location as Dice shows it, for example "Jersey City, New Jersey, USA". |
| employmentType | string | Full-time, Part-time, Contract, Third Party, or a combination such as "Third Party, Contract". |
| postedDate | string | ISO 8601 time when the job was first posted. |
| modifiedDate | string | ISO 8601 time of the last update to the listing (search results only). |
| validThrough | string | ISO 8601 closing date of the posting (needs job details). |
| workplaceTypes | array | Workplace types: On-Site, Remote or Hybrid. |
| isRemote | boolean | True when Dice marks the job as remote. |
| employerType | string | Direct Hire, Recruiter or Other. |
| salary | string | Pay range or rate as listed by the employer, for example "USD 55 - 65". Null when it is not disclosed or only a placeholder such as "Depends on Experience". |
| salaryMin | number | Lower bound of the listed pay as a number; null when no salary is listed. |
| salaryMax | number | Upper bound of the listed pay as a number. |
| salaryPeriod | string | Pay period of the salary figures: hour, month or year. Inferred from the amount when the text does not say. |
| salaryCurrency | string | Currency code of the listed pay, for example USD. With details enabled, uses the job page’s structured salary currency when the search salary omits it. |
| city | string | City of the job location. |
| state | string | State or region code of the job location, for example NJ. |
| country | string | Country of the job location. |
| postalCode | string | Postal code from the job page (needs job details). |
| daysSincePosted | integer | Whole days between the posted date and the run. |
| summary | string | Short description snippet from the search results. |
| skills | array | Skill tags shown on the job page (needs job details). |
| description | string | Full job description converted to plain text (needs job details). |
| easyApply | boolean | True when the job accepts Dice Easy Apply. |
| applyUrl | string | The Dice job page where the application is made. |
| companyLogoUrl | string | URL of the company logo image. |
| companyProfileUrl | string | URL of the Dice company profile page. |

Salary is only filled in for a minority of listings, because many employers do not publish pay. Salary text is lightly normalised: repeated currency symbols are collapsed, and a space is placed between the currency code and the amount. When the search result has no salary but the job page publishes structured pay data, that value is used instead.

### How to use Dice Jobs Scraper

1. Open the Actor in Apify Console and go to the Input tab.
2. Enter one or more search keywords, for example "python developer".
3. Optionally enter a location such as "New York, NY". Leave it empty to search across the whole United States, remote roles included.
4. Set "Max items" to the number of jobs you want. The run stops as soon as that many jobs have been saved.
5. Choose whether to include job details. Details add skills, the full description and the closing date, but need one extra request per job.
6. Optionally restrict the search to remote jobs, to jobs posted today, within 3 days or within 7 days, or to one employment type.
7. Start the run and download the dataset as JSON, CSV, Excel or HTML, or read it through the API.

You can also paste Dice URLs. A search URL such as a Dice jobs page with your own filters is followed page by page. A job page URL returns just that one job, with details.

If the same job appears under several keywords, it is saved only once per run, so there are no duplicate ids in your dataset.

### Input

For a focused application feed, set `easyApplyOnly: true`. The Actor keeps only search records where Dice explicitly publishes `easyApply: true`; an absent flag does not count as Easy Apply. This checks the search record before opening a detail page, saving that extra request for discarded jobs. It does not submit applications or authenticate to Dice.

Use `workplaceTypes: ["Hybrid", "On-Site"]` to collect either selected setting. The values match Dice's published workplace labels exactly. An empty array leaves all workplace types eligible. These filters apply to keyword searches and search URLs, and combine with existing filters. Combining `remoteOnly: true` with only `On-Site` can return no items because both conditions must hold. Direct job IDs and job-detail URLs refresh known jobs without these search filters.

Use `employerTypes: ["Direct Hire"]` to focus keyword searches and search URLs on employers that Dice labels Direct Hire. Select `Recruiter` or `Other` instead, or combine labels to accept any selected value. The default empty array accepts every employer. A result without a published employer label cannot match a selected label. This filter runs before detail fetching; direct job targets ignore it.

For repeated collection, pass previous output `id` values in `excludeJobIds`. Dice job-detail URLs also work in that list. Matching is case insensitive for GUIDs. Exclusions apply to searches and direct targets, before opening job pages, and excluded jobs consume no result budget. Search pagination continues to look for unseen jobs. This is caller-managed monitoring: the Actor does not remember previous datasets automatically, so keep the previous IDs in your own integration and send them on each run. To refresh a known job deliberately, remove it from the exclusion list and supply it through `jobIds`.

Filtering continues through search pages until the shared `maxItems` budget is filled or results end. Narrow filters can therefore require more search-page requests. Employer brand IDs help group search results from the same Dice employer without relying on matching company-name text. `clientBrandId` is copied from Dice, and stays null on direct detail records because that page source does not supply the search identifier.

| Field | Type | Description |
|---|---|---|
| searchQueries | array of strings | Job keywords to search, for example "python developer". Required unless startUrls is given. |
| location | string | City and state, for example "New York, NY". Empty means all of the US. |
| maxItems | integer | Maximum number of jobs across all searches, 1 to 10000, default 50. |
| includeDetails | boolean | Open each job page to add skills, the description and the closing date. Default true. |
| jobIds | array of strings | Optional Dice job GUIDs or job-detail URLs, fetched directly. Useful to refresh jobs you already know. |
| startUrls | array | Optional dice.com search URLs or job-detail URLs. |
| easyApplyOnly | boolean | Keep search results explicitly marked Easy Apply. Default false; direct job targets are unchanged. |
| workplaceTypes | array | Match any of Remote, Hybrid, On-Site. Default empty; direct job targets are unchanged. |
| employerTypes | array | Match any selected Direct Hire, Recruiter or Other label in search results. Default empty accepts all. |
| excludeJobIds | array of strings | Skip known job GUIDs or detail URLs across all targets. Default empty; skipped jobs do not count toward maxItems. |
| remoteOnly | boolean | Request Remote jobs for keyword searches and search URLs. Default false; direct job targets ignore this filter. |
| postedWithin | string | One of any, today, 3days, 7days. Default any. |
| employmentType | string | One of any, fulltime, parttime, contract, thirdparty. Default any. |
| proxyConfiguration | object | Apify Proxy settings. Datacenter proxy is the default. |

Example input:

```json
{
  "searchQueries": ["python developer"],
  "location": "New York, NY",
  "includeDetails": true,
  "maxItems": 30
}
```

Example input for recent remote roles without details:

```json
{
  "searchQueries": ["data engineer"],
  "remoteOnly": true,
  "postedWithin": "7days",
  "includeDetails": false,
  "maxItems": 40
}
```

### Output

Each item looks like the example below, taken from a real run for "python developer" in New York. Long text is shortened here.

```json
{
  "id": "7015377a-0d8c-4367-86c2-c8de29fa55b8",
  "sourceUrl": "https://www.dice.com/jobs?q=python+developer&location=New+York%2C+NY&page=1",
  "title": "Senior Python Developer",
  "companyName": "Randstad Digital",
  "location": "Jersey City, New Jersey, USA",
  "employmentType": "Contract",
  "postedDate": "2026-09-28T21:04:03Z",
  "modifiedDate": "2026-10-02T03:03:11Z",
  "validThrough": "2026-11-02T04:03:11.000Z",
  "workplaceTypes": ["On-Site"],
  "isRemote": false,
  "employerType": "Recruiter",
  "salary": "USD 55 - 65",
  "summary": "job summary: Position will be a Senior Python Developer who has experience working in Python, REST...",
  "skills": ["Senior Python Developer"],
  "description": "job summary:\n\n- Position will be a Senior Python Developer who has experience working in Python, REST...",
  "easyApply": false,
  "applyUrl": "https://www.dice.com/job-detail/7015377a-0d8c-4367-86c2-c8de29fa55b8",
  "companyLogoUrl": "https://d3qscgr6xsioh.cloudfront.net/nwd2B9CDT8Oo4K91VMeJ_transformed.png?format=webp",
  "companyProfileUrl": "https://www.dice.com/company-profile/ee3855f3-d056-5325-bc31-ad5f53052a28"
}
```

The dataset has an Overview view that shows the most useful columns: id, title, company, location, employment type, salary, posted date, workplace types, employer type, skills and apply URL.

### How much does it cost?

The Actor is charged per result: each job saved to the dataset counts as one result. There is no charge for jobs that are skipped, for duplicates that are dropped, or for runs that return nothing. See the Pricing tab on the Actor page for the current rate. You can control the total cost of a run by setting "Max items", which the Actor honours exactly. Turning off job details reduces the requests needed.

### Use with AI agents (MCP)

You can call this Actor from an AI assistant through the Apify MCP server. Add the Actor to your MCP client configuration:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=axiomworks/dice-jobs-scraper"
    }
  }
}
```

Example prompts you can give your assistant:

- "Find 20 recent remote data engineer jobs on Dice and list company, salary and employment type."
- "Search Dice for python developer contract roles in New York and show which ones list a salary."
- "Get the skills and description for this Dice job page and summarise the requirements."

Put the required input first in your prompt: the keyword is the only required argument, and "maxItems" keeps the result small for the model's context.

### Integrations and API

Run the Actor from code with the Apify client libraries or plain HTTP.

Python:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("axiomworks/dice-jobs-scraper").call(run_input={
    "searchQueries": ["python developer"],
    "location": "New York, NY",
    "maxItems": 20,
})
for job in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(job["title"], job["companyName"], job["location"])
```

JavaScript:

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<YOUR_API_TOKEN>' });
const run = await client.actor('axiomworks/dice-jobs-scraper').call({
    searchQueries: ['data engineer'],
    remoteOnly: true,
    maxItems: 40,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
process.stdout.write(`${items.length} jobs\n`);
```

cURL:

```bash
curl -X POST "https://api.apify.com/v2/acts/axiomworks~dice-jobs-scraper/runs" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"searchQueries": ["python developer"], "location": "New York, NY", "maxItems": 20}'
```

The Actor also works with Apify schedules, webhooks, Make, Zapier, Google Sheets and any tool that can read a dataset through the API. A common setup is a daily scheduled run with "postedWithin" set to today, sending new jobs to a spreadsheet or a database.

### FAQ

**How many jobs can I get per search?**
Dice returns 30 jobs per page and caps the result set by relevance. Broad keywords can have thousands of matches, and the Actor stops at your "maxItems" value, up to 10000.

**Why is salary empty for many jobs?**
Many employers do not publish pay on Dice. The Actor returns null rather than guessing.

**Why are skills missing?**
Skills are only on the individual job page. Turn on "Include job details" to get them. A few jobs have no skill tags at all.

**What happens with a keyword that has no results?**
The run finishes successfully with zero items and a warning in the log. Nothing is charged.

**What happens if Dice blocks a request?**
Requests that return 403, 429 or a server error are retried with increasing delays on a fresh proxy session. If a job page still fails, that job is saved with search data only and a warning is logged.

**How fast is it?**
Requests are spaced at least 700 milliseconds apart. Detail fetching adds one request per job; retries can extend runtime.

**Can I filter by experience level or by salary?**
Not directly. Filter the dataset after the run on the salary and employmentType fields.

**Do the dates come with a time zone?**
Yes. Dates are ISO 8601 timestamps in UTC.

### Is it legal to scrape Dice?

This Actor reads public Dice job listings without login and collects no private account data. Scraping laws vary by jurisdiction, and site terms may restrict automation. You are responsible for your use of the data and applicable data protection obligations. This Actor is not affiliated with, endorsed by or sponsored by Dice. Obtain legal advice for your specific use case.

### Feedback

If a field is missing, the results look wrong, or you need another filter, open an issue from the Issues tab on the Actor page. Reports that include the input you used and the Dice URL in question help us fix problems quickly.

# Actor input Schema

## `searchQueries` (type: `array`):

Job keyword strings, e.g. \["python developer", "data engineer"]. Searches run in order and share maxItems with URLs and IDs. Required by the schema; use \[] with startUrls or jobIds. No matches or a blocked target returns no rows for that target; try broader keywords or retry later.

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

Location text for every searchQueries entry, e.g. "New York, NY" or "Texas". Default "" searches across the US, including remote jobs. startUrls retain their own location parameter; direct job IDs ignore location.

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

Maximum unique jobs saved across all keyword, URL and ID targets combined, in processing order: URLs and IDs first, then keywords. 1-10000, default 50; e.g. 20. Fewer rows are returned when matches run out, targets are blocked or your spending limit is reached.

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

Set true (default) to fetch each search result job page for skills, description, validThrough and postalCode; this adds one request per job. Set false for faster search lists with those fields null, e.g. false for a 20-job preview. Direct job IDs and job-detail URLs always fetch their page.

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

Dice /jobs search URLs or /job-detail/<guid> URLs, e.g. \[{"url":"https://www.dice.com/jobs?q=python\&location=Texas"}]. String URLs also work. Default \[]; use searchQueries: \[] for URL-only runs. Search URLs keep their location and query; supplied search filters still apply. Unsupported or non-Dice URLs are skipped.

## `jobIds` (type: `array`):

Dice job GUID strings or job-detail URLs, e.g. \["8beb49a9-d16e-4c66-bd56-6c4d97c62df0"]. Default \[]; use searchQueries: \[] for ID-only runs. Direct jobs always fetch details and ignore search filters. Expired or removed jobs produce no row; check the ID or search for current jobs.

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

Set true to request the Remote workplace filter for keyword searches and search URLs, e.g. true. Default false keeps the URL filter, if any, or all workplace types. Combines with workplaceTypes, so selecting only On-Site can yield no rows. Direct job targets ignore this option.

## `postedWithin` (type: `string`):

Posting-age filter for keyword searches and search URLs: "any", "today", "3days" or "7days", e.g. "7days". Default "any" adds no age filter and retains any filter in a supplied URL. It does not restrict direct job refreshes.

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

Employment filter for keyword searches and search URLs: "any", "fulltime", "parttime", "contract" or "thirdparty", e.g. "contract". Default "any" adds no filter and retains any filter in a supplied URL. Direct job targets ignore this option.

## `proxyConfiguration` (type: `object`):

Proxy settings object, e.g. {"useApifyProxy":true}. Default uses Apify Proxy with automatic datacenter selection. Blocked requests retry on a fresh session; persistent blocks return no rows for that target. Retry later if the target remains blocked.

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

Set true to save only search results explicitly marked easyApply: true, e.g. true. Default false keeps both application types. Applies to keyword searches and search URLs, alongside other filters; direct job IDs and job-detail URLs ignore it.

## `workplaceTypes` (type: `array`):

Workplace label strings to match any selected value: \["Remote"], \["Hybrid", "On-Site"], or \[] (default, all labels). Applies to keyword searches and search URLs alongside remoteOnly and other filters. Direct job targets ignore it. Clear this list if filters yield no matches.

## `employerTypes` (type: `array`):

Employer labels to include in keyword and search-URL results, e.g. \["Direct Hire"] to omit recruiters. Default \[] accepts all employers. Matches any selected label exactly; missing labels are excluded when filtering. Direct job targets ignore this filter.

## `excludeJobIds` (type: `array`):

Job GUIDs or Dice job-detail URLs to skip, e.g. IDs from a previous dataset. Default \[] excludes nothing. Applies to all targets before detail requests. Excluded jobs do not count toward maxItems; search pagination continues for unseen jobs. No state is shared between runs unless you pass this list.

## Actor input object example

```json
{
  "searchQueries": [
    "python developer"
  ],
  "location": "New York, NY",
  "maxItems": 20,
  "includeDetails": true,
  "startUrls": [],
  "jobIds": [],
  "remoteOnly": false,
  "postedWithin": "any",
  "employmentType": "any",
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "easyApplyOnly": false,
  "workplaceTypes": [],
  "employerTypes": [],
  "excludeJobIds": []
}
```

# 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 = {
    "searchQueries": [
        "python developer"
    ],
    "location": "New York, NY",
    "maxItems": 20,
    "includeDetails": false,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("axiomworks/dice-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 = {
    "searchQueries": ["python developer"],
    "location": "New York, NY",
    "maxItems": 20,
    "includeDetails": False,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("axiomworks/dice-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 '{
  "searchQueries": [
    "python developer"
  ],
  "location": "New York, NY",
  "maxItems": 20,
  "includeDetails": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call axiomworks/dice-jobs-scraper --silent --output-dataset

```

## MCP server setup

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