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

Scrape US tech jobs from Dice (dice.com): full descriptions, skills, parsed salaries, remote/hybrid flags, Easy Apply and visa-sponsorship filters, and an incremental "only new jobs" mode. No login, no browser.

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

## Pricing

from $1.50 / 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.

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: Extract US Tech Jobs from Dice.com (Job Postings API)

**Dice Jobs Scraper** pulls tech job listings from **Dice** (dice.com), the US job board for software, data, cloud, security and IT roles. It returns clean, structured job data: title, company, location, remote/hybrid/on-site flags, employment type, parsed salary, posting and expiry dates, full description, skills, contract terms, Easy Apply and visa-sponsorship flags, and the job and apply links.

It reads the same JSON search API that dice.com uses, so it is **fast, cheap and reliable**: no login, no browser, and no proxy by default. You **only pay for the jobs you get**.

Search by keywords, location and Dice's own filters, or paste search URLs straight from your browser. Turn on **Only new jobs** and schedule it to get just the jobs posted since the last run.

### What can this Dice scraper do?

- 🔎 **Search like on dice.com.** Keywords (Dice's boolean syntax works), US location and radius, remote / hybrid / on-site, employment type (full-time, contract, part-time, third party, internship), posted today / last 3 days / last 7 days, Easy Apply only, willing to sponsor only, and employer type (direct hire / recruiter).
- 🔗 **Paste search URLs.** Set up a search on dice.com and paste the address. Keywords, location, radius and every filter are read from the URL. Several URLs run as separate searches in one run, de-duplicated.
- 📄 **Full job details.** The full description as HTML and clean plain text, the skills list, the employer's position ID, contract types (W2, corp-to-corp, independent) and duration, the employer's own apply link, postal code and the posting's expiry date.
- 💵 **Parsed salaries.** Dice's free-text pay field ("USD 140,000.00 - 160,000.00 per year", "$60 - $70 per hour", "$62", "85+") becomes `min`, `max`, `currency` and `interval`. When the listing has no amount, the scraper looks for a pay range in the description.
- 🏠 **Clear remote flags.** `isRemote`, a normalised `workplaceType` (remote / hybrid / onsite) and Dice's raw work settings, e.g. `["Remote", "On-Site"]`.
- 🔁 **Incremental monitoring.** Turn on **Only new jobs** and schedule the Actor. Each run outputs, and charges for, only jobs that were not seen before.
- 🧩 **Same schema as our other jobs Actors.** `id`, `company`, `title`, `location`, `isRemote`, `workplaceType`, `employmentType`, `salary{min,max,currency,interval,text,source}`, `postedAt`, `jobUrl`, `applyUrl`, `descriptionText` and `descriptionHtml` match our ATS Jobs Scraper, so you can merge the datasets.
- 🛡️ **Built for reliability.** Retries with backoff on rate limits and server errors. If Dice's API key changes, the scraper reads the current one from dice.com at runtime, and if the API refuses requests it falls back to Dice's search pages. If Dice blocks the run, it stops with a clear message instead of crashing.
- 💸 **Pay per job.** No start fee from us, no subscription.

### What you get

| | **Dice Jobs Scraper** |
|---|---|
| Full description (HTML + plain text) | ✅ From each job page |
| Skills, position ID, contract type and duration | ✅ |
| Salary parsed into min / max / currency / interval | ✅ Including hourly rates and "85+" style values |
| Remote / hybrid / on-site, Easy Apply, visa sponsorship | ✅ As filters and as output fields |
| Paste dice.com search URLs | ✅ All filters are read from the URL |
| Incremental "only new jobs" mode | ✅ One memory per monitor, shared across searches |
| Recruiter e-mail addresses or phone numbers | ❌ Never collected (see below) |
| Proxy required | ❌ Not by default |
| Start fee | ❌ None |

### How to scrape Dice jobs

1. Click **Try for free** or **Start**.
2. Enter **Keywords** and, optionally, a **Location** and filters. Or paste one or more Dice search URLs into **Or paste Dice search URLs**.
3. Set **Max jobs per search** (default 100).
4. Click **Start**. Then download the jobs as JSON, CSV, Excel or HTML, or get them through the API.

### Input example

```json
{
    "keywords": "data engineer",
    "location": "Austin, TX",
    "radius": 30,
    "workplaceTypes": ["remote", "hybrid"],
    "employmentTypes": ["fullTime", "contract"],
    "postedWithin": "7days",
    "easyApplyOnly": false,
    "willingToSponsorOnly": false,
    "includeRemote": true,
    "maxJobs": 200,
    "includeDescription": true,
    "sortBy": "datePosted",
    "onlyNewJobs": false
}
```

| Field | Description |
|---|---|
| `keywords` | What you would type in Dice's search box. Empty = all jobs. |
| `location`, `radius` | US city, state or ZIP code, and a radius in miles (default 30). |
| `workplaceTypes` | Any of `remote`, `hybrid`, `onsite`. |
| `employmentTypes` | Any of `fullTime`, `contract`, `partTime`, `thirdParty`, `internship`. |
| `postedWithin` | `any`, `today`, `3days` or `7days`. |
| `easyApplyOnly`, `willingToSponsorOnly` | Dice's Easy Apply and "willing to sponsor" filters. |
| `employerTypes` | Any of `directHire`, `recruiter`, `other`. |
| `includeRemote` | Dice's default (`true`): with a location set, remote jobs located elsewhere in the US are also returned. Set `false` to keep only jobs in or near the location. |
| `startUrls` | Dice search URLs. When set, the search fields above are ignored and each URL is its own search. |
| `maxJobs` | Limit per search (each URL counts separately). `0` = no limit (Dice stops at 10,000 results per search). Default `100`. |
| `includeDescription` | Open each job page for the full description and details (default `true`). Turn off for a fast listing-only scrape. |
| `sortBy` | `datePosted` (newest first, default) or `relevance`. |
| `onlyNewJobs` | Incremental mode: only output jobs not seen in previous runs. |
| `stateKey` | Name of the monitor. Separate monitors keep separate memories. |
| `requestsPerSecond`, `maxConcurrency` | Politeness limits (defaults 4 and 4). |
| `proxyConfiguration` | Off by default. See the FAQ. |

### Using Dice search URLs

Set up the search on dice.com with all the filters you want, then copy the address bar:

```
https://www.dice.com/jobs?q=devops&location=Denver,%20CO,%20USA&radius=50&filters.employmentType=CONTRACTS%7CTHIRD_PARTY&filters.postedDate=SEVEN
https://www.dice.com/jobs?q=python&filters.workplaceTypes=Remote&filters.easyApply=true
https://www.dice.com/jobs?q=java&location=Seattle,%20WA&filters.willingToSponsor=true
```

Supported: keywords, location (including the latitude/longitude Dice adds), radius, work setting, employment type, employer type, posted date, Easy Apply, willing to sponsor and the company filter. Single job pages (`/job-detail/...`), company pages and old-style URLs (`/jobs/q-python-l-...`) are rejected with a message that says what to paste instead.

### Output example

Every job is one dataset item (description and summary shortened here):

```json
{
    "id": "dice:00a4e3dc-1d1c-4479-96d8-84f8f8e89023",
    "source": "dice",
    "company": "Robert Half",
    "title": "Data Scientist, Growth Analytics",
    "location": "San Francisco, California, USA",
    "locations": ["San Francisco, California, USA"],
    "isRemote": true,
    "workplaceType": "remote",
    "employmentType": "CONTRACT",
    "salary": { "min": 75, "max": 85, "currency": "USD", "interval": "hour", "text": "USD 75.00 - 85.00 per hour", "source": "dice" },
    "postedAt": "2026-11-01T00:08:26.000Z",
    "updatedAt": "2026-11-02T01:03:08.000Z",
    "validThrough": "2026-12-03T01:03:08.000Z",
    "jobUrl": "https://www.dice.com/job-detail/00a4e3dc-1d1c-4479-96d8-84f8f8e89023",
    "applyUrl": "https://www.dice.com/job-detail/00a4e3dc-1d1c-4479-96d8-84f8f8e89023",
    "applyType": "email",
    "easyApply": true,
    "employerType": "Recruiter",
    "willingToSponsor": false,
    "isThirdParty": false,
    "employmentTypes": ["Contract"],
    "workplaceTypes": ["Remote", "On-Site"],
    "workSetting": "On-site",
    "contractTypes": ["CONTRACT_INDEPENDENT", "CONTRACT_W2"],
    "contractDuration": null,
    "skills": ["Reporting", "Leadership", "Acquisition", "Modeling", "Budget", "Data Engineering"],
    "summary": "Description We are looking for a Data Scientist/Analyst to support a fintech client ...",
    "descriptionText": "Description\n\nWe are looking for a Data Scientist/Analyst to support a fintech client ...",
    "descriptionHtml": "<b>Description</b><br /><br /> We are looking for a Data Scientist/Analyst ...",
    "city": "San Francisco",
    "state": "California",
    "stateCode": "CA",
    "country": "USA",
    "postalCode": "94111",
    "guid": "00a4e3dc-1d1c-4479-96d8-84f8f8e89023",
    "legacyJobId": "59a3aa0758b17f27d0bfa9cd757fdbd1",
    "positionId": "00410-0013535112",
    "diceId": "rhalfint",
    "companyProfileUrl": "https://www.dice.com/company-profile/8c2cf2a7-dcd7-42dc-b8d4-2b90acef1688",
    "companyLogoUrl": "https://d3qscgr6xsioh.cloudfront.net/jLZGbw1aTAehDYuxFRDm_transformed.png?format=webp",
    "detailsFetched": true,
    "sourceUrl": "https://www.dice.com/jobs?q=python&countryCode=US&filters.workplaceTypes=Remote&filters.employmentType=CONTRACTS",
    "scrapedAt": "2026-11-02T11:19:51.783Z"
}
```

Notes on the fields:

- `id` (`dice:{guid}`) is stable across runs. Use it to de-duplicate.
- `salary.source` is `dice` when the numbers come from Dice's pay field and `description` when they were found in the description text. If the listing gives no interval ("$65 - $67"), the scraper takes it from the job page ("$65 - $67/hr") or, failing that, infers it from the amount: up to 500 is hourly, 10,000 or more is yearly, anything in between stays `null`. Text without numbers ("Depends on Experience") is kept in `salary.text` with `null` amounts. Currency defaults to USD when the text has none, because Dice only lists US jobs.
- `isRemote` is `true` when remote work is possible, including jobs listed as "Remote or On-Site". `workplaceType` is `remote` if remote is possible, else `hybrid`, else `onsite`. `workplaceTypes` keeps Dice's raw values, and `workSetting` is the badge shown on the job page.
- `employmentType` is normalised from the first Dice type. "Third Party" is reported as `isThirdParty`, and a job listed only as "Third Party" has `employmentType: null`. `employmentTypes` keeps Dice's raw values.
- `location` is `"Remote"` for remote jobs that Dice lists without a location.
- `applyUrl` is the employer's own application page for jobs that apply externally (DoubleClick tracking wrappers are removed; other tracking links are kept as Dice gives them). For Easy Apply and "apply by e-mail" jobs it is the Dice job page. `applyType` is `external` or `email`.
- The fields that come from the job page (`descriptionText`, `descriptionHtml`, `skills`, `positionId`, `contractTypes`, `contractDuration`, `workSetting`, `postalCode`, `validThrough`, `applyType`) are only filled with **Include full description** on. `detailsFetched` tells you whether the job page was read.

A `RUN_SUMMARY` record in the run's key-value store lists, for every search: jobs output, jobs listed, already-seen jobs, total results reported by Dice, the route used (API or website), request counts and any warnings.

### What this scraper does not collect

Only the public job listing and the company name. It never collects recruiters' or hiring managers' names, e-mail addresses or phone numbers. For "apply by e-mail" jobs it reports `applyType: "email"` and links to the Dice job page; the address itself is not read into the output. In testing, the description text Dice publishes had contact details already removed, and none of the test output contained an e-mail address or phone number.

### How much does it cost to scrape Dice jobs?

This Actor uses **pay-per-event** pricing: you pay per job that appears in your dataset, and there is no start fee from us.

| Your Apify plan | Price per job | 1,000 jobs |
|---|---|---|
| Free | $0.0015 | $1.50 |
| Starter | $0.0012 | $1.20 |
| Scale | $0.0010 | $1.00 |
| Business | $0.0009 | $0.90 |

Jobs that are already seen in incremental mode, duplicates across your searches, expired jobs and failed searches cost nothing. Your Apify plan's free monthly credit applies. To cap spending, set **Maximum cost per run** in the run options. The scraper stops cleanly when the budget is reached and says so in the status message.

### Scheduling and incremental monitoring of new jobs

Use this to get **alerts for new Dice jobs**, or to keep a job board or spreadsheet in sync:

1. Turn on **Only new jobs** and give the monitor a name in **Monitor name** (e.g. `python-remote`).
2. Save the configuration as a **Task** and add a **Schedule** (e.g. every morning).
3. The first run outputs all current matching jobs (up to **Max jobs per search**) and saves them as the baseline.
4. Every later run reads results newest first and outputs **only jobs that appeared since**. It stops paging after 200 already-seen jobs in a row, so a daily run usually costs one or two search requests plus the new jobs.

The memory is kept in a named key-value store (`dice-jobs-scraper-state` by default) under the monitor name, and is shared by all searches in the run, so a job matching two of your searches is output and charged once. If you set **Max jobs per search** on the first run, later runs also pick up older matching jobs that the first run left out, up to the limit each time. To get only genuinely new postings, do the first run with a limit high enough to cover the search. Don't run two runs with the same monitor name at the same time.

### Limits

- **10,000 results per search.** Dice does not serve results beyond the first 10,000 of a search. The log and `RUN_SUMMARY` say when a search is larger; split it with filters, locations or posted date to reach the rest.
- **US only.** Dice lists US jobs. All amounts default to USD.
- **Datacenter IPs.** Testing so far was done from a residential connection. Dice may treat Apify's datacenter IPs differently, especially on job pages. If Dice blocks requests (HTTP 403, repeated 429, or a bot-check page), the run stops with a message that says so, keeps the jobs already saved, and suggests a proxy. If that happens, enable **Proxy configuration** (residential works best), lower **Max requests per second**, or turn off **Include full description** to use only the search API.
- **Fallback route.** If Dice's search API stops accepting its public key, the scraper reads the current key from dice.com. If that fails too, it falls back to Dice's search pages, which return 30 jobs per page and only sort by relevance. The run still works, more slowly.
- **Single job URLs** (`/job-detail/...`) are not supported as input. Paste a search URL.
- **Unofficial interface.** Dice has no public API for job seekers. This Actor uses the endpoints dice.com itself uses, which Dice can change without notice. The parsing is covered by tests against saved pages, and failures are reported clearly.

### Integrations and API

- **API.** Start runs and fetch results with the [Apify API](https://docs.apify.com/api/v2), or the JavaScript and Python clients:

  ```bash
  curl -X POST "https://api.apify.com/v2/acts/rjmacarthy~dice-jobs-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{"keywords":"python","workplaceTypes":["remote"],"maxJobs":50}'
  ```

- **Webhooks.** Get notified (or trigger your pipeline) when a run finishes.

- **Zapier, Make, n8n.** Send new jobs to Google Sheets, Airtable, Slack, e-mail or your CRM with no code.

- **Google Sheets, Slack, Airbyte, Keboola and more** through Apify integrations.

- **AI agents.** Use the Actor as a tool through the Apify MCP server.

### FAQ

**Do I need a Dice account, login, cookies or a proxy?**
No. Dice job listings are public. The proxy option is there in case Dice blocks requests from Apify's servers.

**How fast is it?**
Listing-only runs fetch 100 jobs per request: 250 jobs took 3 seconds in testing. With full descriptions, each job needs one job-page request, so speed is capped by **Max requests per second** (default 4, so at most about 4 jobs per second).

**Why is `salary` null or without amounts?**
Many Dice employers leave the pay field empty or write text such as "Depends on Experience" or "Compensation information provided in the description". With **Include full description** on, the scraper then looks for a pay range in the description.

**Why do I get remote jobs from other states when I set a location?**
That is Dice's default behaviour. Turn off **Include remote jobs from anywhere in the US** to keep only jobs in or near your location.

**Can I scrape more than 10,000 jobs?**
Not from one search: Dice stops there. Split the search into several (by location, employment type, posted date and so on) and paste them as separate URLs. Jobs found by more than one search are output once.

**Is scraping Dice legal?**
The scraper only collects job postings that employers publish publicly to attract applicants, and no personal contact data. Always check that your use complies with Dice's terms and the laws that apply to you.

### Ready-to-run examples

- [Scrape Java developer jobs in New York from Dice](https://apify.com/rjmacarthy/dice-jobs-scraper/examples/java-developer-jobs-new-york)
- [Find tech jobs that sponsor visas on Dice](https://apify.com/rjmacarthy/dice-jobs-scraper/examples/visa-sponsorship-tech-jobs)

### More scrapers by the same developer

- [ATS Jobs Scraper: Greenhouse, Lever, Ashby & Workday](https://apify.com/rjmacarthy/ats-jobs-scraper)
- [SEEK Jobs Scraper](https://apify.com/rjmacarthy/seek-jobs-scraper)
- [Workday Jobs Scraper](https://apify.com/rjmacarthy/workday-jobs-scraper)
- [Google Ads Transparency Scraper](https://apify.com/rjmacarthy/google-ads-transparency-scraper)
- [Substack Scraper](https://apify.com/rjmacarthy/substack-scraper)
- [Telegram Channel Scraper](https://apify.com/rjmacarthy/telegram-channel-scraper)

Browse all my Actors on [my Apify Store profile](https://apify.com/rjmacarthy).

### Support

Found a search that doesn't work, or need an extra field? Open an issue on the **Issues** tab with your input. Fixes are usually quick.

# Actor input Schema

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

What you would type in Dice's search box, e.g. "python developer", "Java AND Spring" or a company name. Leave empty for all jobs.

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

City, state or ZIP code in the US, e.g. "Austin, TX", "New York" or "94105". Leave empty for the whole US.

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

Search radius around the location. Only used when a location is set. Dice's own options are 10, 30, 50 and 75 miles.

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

Only jobs with these work settings. Leave empty for all.

## `employmentTypes` (type: `array`):

Only jobs with these employment types. Leave empty for all.

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

Only jobs posted within this period.

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

Only jobs you can apply to directly on Dice.

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

Only jobs where the employer is willing to sponsor a work visa.

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

Only jobs posted by these employer types. Leave empty for all.

## `includeRemote` (type: `boolean`):

Dice's default. With a location set, remote jobs located elsewhere are also returned. Turn off to get only jobs in or near the location.

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

Search result URLs copied from your browser, e.g. https://www.dice.com/jobs?q=python\&location=Austin,%20TX\&filters.workplaceTypes=Remote. Each URL is one search with its own keywords and filters; when you add URLs, the search fields above are ignored. Single job pages (/job-detail/...) are not supported.

## `maxJobs` (type: `integer`):

Stop after this many jobs from each search (each URL counts as one search). 0 = no limit; Dice itself returns at most the first 10,000 results of a search.

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

Open each job's page for the full description (HTML and plain text), skills, position ID, contract type and duration, external apply link, postal code, expiry date and the pay interval. Turn off for a faster, listing-only scrape (title, company, location, salary text, summary, flags).

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

Newest first is best with a job limit. Incremental mode always reads newest first.

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

Remember which jobs were already output and only output (and charge for) jobs that are new since the previous run. The first run outputs all matching jobs (up to the limit) and saves them as the baseline. Ideal for scheduled alerts.

## `stateKey` (type: `string`):

Name of this monitor's memory. Runs with the same name share the list of already-seen jobs. Use different names for independent monitors (e.g. "python-austin" vs "java-remote").

## `stateStoreName` (type: `string`):

Named key-value store in your account where incremental state is kept (letters, digits and dashes).

## `requestsPerSecond` (type: `integer`):

Upper limit on requests per second to each Dice host. The default is fast and polite; lower it if Dice starts rate-limiting.

## `maxConcurrency` (type: `integer`):

Maximum parallel HTTP requests.

## `searchSource` (type: `string`):

Auto uses Dice's JSON search API and falls back to Dice's search result pages if the API refuses requests. You normally don't need to change this.

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

Not needed normally. Enable it if Dice blocks or rate-limits requests from Apify's servers (residential proxies work best for job pages).

## Actor input object example

```json
{
  "keywords": "python developer",
  "radius": 30,
  "postedWithin": "any",
  "easyApplyOnly": false,
  "willingToSponsorOnly": false,
  "includeRemote": true,
  "maxJobs": 50,
  "includeDescription": true,
  "sortBy": "datePosted",
  "onlyNewJobs": false,
  "stateKey": "default",
  "stateStoreName": "dice-jobs-scraper-state",
  "requestsPerSecond": 4,
  "maxConcurrency": 4,
  "searchSource": "auto",
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

One item per job: company, title, location, remote flag, employment type, salary, posting date and job URL.

## `jobsFull` (type: `string`):

Every field for each job, including skills, parsed salary and the full description in HTML and plain text.

## `summary` (type: `string`):

Per-search status, counts, request statistics and any warnings.

# 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": "python developer",
    "maxJobs": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("rjmacarthy/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 = {
    "keywords": "python developer",
    "maxJobs": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("rjmacarthy/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 '{
  "keywords": "python developer",
  "maxJobs": 50
}' |
apify call rjmacarthy/dice-jobs-scraper --silent --output-dataset

```

## MCP server setup

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