# Dice Job Details, Skills and the Real Salary (`gubidonius/dice-job-details`) Actor

Whole adverts from dice.com with the skills list, the postal code and the expiry date the board does not carry. Every structured salary is labelled, because on about one advert in five it is a band edge rather than the employer's pay.

- **URL**: https://apify.com/gubidonius/dice-job-details.md
- **Developed by:** [Gregory Bolshakov](https://apify.com/gubidonius) (community)
- **Categories:** Jobs, Lead generation, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.01 / 1,000 advert reads

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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 job details

Whole adverts from dice.com: the full text, the skills list, the postal code and the expiry
date. Give it advert ids, or let it read the board first.

### What the board does not have

Three fields exist only on the advert page. Skills, 22 of them on the advert read on
16 September 2026. The postal code. The date dice.com expires the advert, about a month after
it was posted.

The description is about 3,900 characters here against roughly 500 in the board summary.

### The structured salary is often a band edge

dice.com publishes a salary for search engines on every advert page:

```json
"baseSalary": { "@type": "MonetaryAmount", "currency": "USD", "value": 80001 }
```

That advert's own salary line reads `USD 80,001.00 - 120,000.00 per year`. The 80001 is the
lower edge of one of Dice's five salary bands, plus one. It is not what the employer pays, and
it is a single number in the field every structured data reader takes as the salary.

`structuredSalaryIsABandFloor` says which rows are like this.

### A missing advert answers 200, not 404

Ask for an advert id that never existed and dice.com returns a normal 55 KB page with the
title `Job Not Found`. The status code says nothing. So a scraper that trusts the status
writes a row of empty fields for an advert that is not there.

This run reads the page. Adverts that are gone are listed under `advertsTakenDown`. Requests
that failed are listed separately, because a failed request says nothing about whether the
advert still exists, and mixing the two reports disappearances that did not happen.

### Five columns are empty on purpose

`easyApply`, `isRemote`, `workFromHomeAvailability`, `workplaceTypes` and `clientBrandId` are
always null here. The advert page does carry those fields, but only for the four similar
adverts it shows at the bottom, and it tags all four with the id of the advert you asked for.
So reading them gives you a different advert's answer with nothing to show it. On the Hardware
Engineer advert the nearest such block belonged to a Systems Engineer.

Join the Dice jobs Actor on `jobId` for those five. `fieldsOnlyOnTheBoard` lists them on every
row.

### A city called remote

dice.com writes the word `remote` into the city field on remote adverts, and still publishes a
real postal code next to it. One advert had city `remote` and postal code 98826, which is a
town in Washington. `cityIsAWorkplaceWordNotAPlace` marks those rows.

The state is a two letter code here and the full name on the board, for the same advert.
Contract type is written three ways on one site: `FULL_TIME` on the advert page, `Full-time`
on the board, `FULLTIME` as a filter value.

### What it costs

$0.00001 per run and $0.00001 per advert. One advert is one request, so the number you ask for
is also the number of requests. An advert that has been taken down is not charged. The same id
given twice is read once and charged once.

### No keyword search

dice.com's robots.txt disallows `/jobs?q*` and explicitly allows `/job-detail`. When no ids are
given this Actor reads the board with place, contract type, workplace, who is advertising,
posted date and visa sponsorship. It never sends a keyword.

# Actor input Schema

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

dice.com advert ids, or the advert URLs, which contain the id. Leave empty to read the board instead using the filters below. A repeated id is read once and charged once.

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

Used only when no ids are given. A place in dice.com's own form, for example "Austin, TX, USA". A place dice.com cannot resolve returns the whole United States board rather than an error, so this run checks for that and stops.

## `postedDate` (type: `string`):

Used only when no ids are given. dice.com offers these three windows and nothing else.

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

Used only when no ids are given. dice.com takes the value, not the label, and a label returns zero adverts rather than an error.

## `workplaceTypes` (type: `string`):

Used only when no ids are given. This is the remote filter that works.

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

Used only when no ids are given.

## `willingToSponsor` (type: `string`):

Used only when no ids are given. 1,163 adverts of 111,682 on 2026-09-16.

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

The most adverts to read. One advert is one request, so this is also the request count. Must be a positive number: 0 is not read as "everything".

## Actor input object example

```json
{
  "jobIds": [],
  "location": "",
  "postedDate": "",
  "employmentType": "",
  "workplaceTypes": "",
  "employerType": "",
  "willingToSponsor": "",
  "maxResults": 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 = {
    "jobIds": [],
    "location": "",
    "postedDate": "",
    "employmentType": "",
    "workplaceTypes": "",
    "employerType": "",
    "willingToSponsor": "",
    "maxResults": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("gubidonius/dice-job-details").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 = {
    "jobIds": [],
    "location": "",
    "postedDate": "",
    "employmentType": "",
    "workplaceTypes": "",
    "employerType": "",
    "willingToSponsor": "",
    "maxResults": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("gubidonius/dice-job-details").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 '{
  "jobIds": [],
  "location": "",
  "postedDate": "",
  "employmentType": "",
  "workplaceTypes": "",
  "employerType": "",
  "willingToSponsor": "",
  "maxResults": 20
}' |
apify call gubidonius/dice-job-details --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,gubidonius/dice-job-details"
        }
    }
}
```

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/viBVLd9aC1KhoNlip/builds/e4G0NhtO1NwHrHNqY/openapi.json
