# Dice Jobs Scraper – Tech Jobs, Search URLs & Companies (`abotapi/dice-com-scraper`) Actor

Pull structured tech job listings from Dice.com by keyword, filters, or Dice URLs. Returns title, company, recruiter type, parsed salary, location, skills, posted date, apply URL/email, and full job description. Auto-paginates with simple pay-per-result pricing and no subscription required.

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

## Pricing

from $1.20 / 1,000 job 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/platform/actors/running/actors-in-store#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 Jobs Scraper

Pull clean, structured tech job listings from Dice (dice.com) at scale. Search by keyword, location, and filters, or paste any Dice search or job URL. Every run returns rich records: title, company, recruiter/employer type, parsed salary, location, workplace type, skills, posted date, apply URL or email, and the full job description. Pay only per result, with no monthly subscription.

### Why This Scraper?

- Dual input: build a search from keywords + location + filters, or paste Dice URLs directly (both search pages and single job pages).
- Full filter set: posted-date window, employment type, workplace type (remote/hybrid/on-site), employer type (recruiter vs direct hire), Easy Apply, visa-sponsor willingness, and sort by relevance or date.
- Superset of fields: structured salary (min, max, currency, period), skills list, apply URL and apply email, company profile link, structured street address, and validity dates, on top of every core listing field.
- Forward pagination: walks result pages automatically until your listing cap or the results run out.
- Optional detail enrichment: turn on richer per-job data (full description, skills, apply contact) only when you need it.
- Export anywhere: optionally pipe results into Notion, Linear, Airtable, or any MCP-compatible app.
- Simple pricing: pay per result, no rental fee, runs on any Apify plan.

### Data You Get

> Sample shape, values are illustrative placeholders, not from a live listing.

| Field | Example |
| --- | --- |
| id | `00000000000000000000000000000000` |
| guid | `00000000-0000-0000-0000-000000000000` |
| url | `https://www.dice.com/job-detail/00000000-0000-0000-0000-000000000000` |
| title | `Senior Python Developer` |
| company | `Sample Company` |
| companyLogo | `https://d3qscgr6xsioh.cloudfront.net/000000000-logo.webp` |
| companyProfileUrl | `https://www.dice.com/company-profile/00000000-0000-0000-0000-000000000000` |
| city | `Austin` |
| state | `Texas` |
| country | `USA` |
| locationDisplay | `Austin, Texas, USA` |
| workplaceTypes | `["Remote"]` |
| remote | `true` |
| salary | `USD 120,000.00 - 150,000.00 per year` |
| salaryMin | `120000` |
| salaryMax | `150000` |
| salaryCurrency | `USD` |
| salaryPeriod | `year` |
| employmentType | `Full-time` |
| employerType | `Direct Hire` |
| easyApply | `false` |
| willingToSponsor | `false` |
| skills | `["Python", "AWS", "PostgreSQL"]` |
| postedDate | `2026-01-01T00:00:00Z` |
| applyType | `APPLY_TO_URL` |
| applyUrl | `https://careers.example.com/apply/0000` |
| applyEmail | `recruiter@example.com` |
| summary | `Sample summary text appears here.` |
| description | `Full HTML description appears here when fetchDetails is on.` |
| companyReviews | `null` |

Note on reviews: Dice is a job board and does not expose company reviews or star ratings, so `companyReviews` is always `null`. Company identity is still captured via `company`, `companyProfileUrl`, and `companyLogo`.

### How to Use

Basic keyword search:

```json
{
  "mode": "search",
  "queries": ["python developer"],
  "countryCode": "US",
  "maxListings": 50
}
```

Search with location and filters:

```json
{
  "mode": "search",
  "queries": ["data engineer"],
  "location": "New York, NY, USA",
  "radius": 30,
  "radiusUnit": "mi",
  "employmentType": "FULLTIME",
  "workplaceType": "Remote",
  "postedDate": "SEVEN",
  "sortBy": "date",
  "maxListings": 100
}
```

Multiple keywords with detail enrichment:

```json
{
  "mode": "search",
  "queries": ["devops", "site reliability engineer"],
  "fetchDetails": true,
  "maxListings": 200
}
```

URL mode (paste search or job URLs):

```json
{
  "mode": "url",
  "urls": [
    "https://www.dice.com/jobs?q=golang&countryCode=US",
    "https://www.dice.com/job-detail/00000000-0000-0000-0000-000000000000"
  ],
  "maxListings": 100
}
```

### Resume & recurring updates

There are two different things here — pick the one that matches what you're doing:

| Need | Use |
| --- | --- |
| A crawl stopped and should continue | `resumeFromRunId` / automatic checkpoint recovery |
| Run the same search every day and receive only changes | `incrementalMode` |
| Keep separate daily campaigns for similar searches | distinct `stateKey` values |
| Run a normal full snapshot | leave both off |

**Resume** (`resumeFromRunId`) continues one specific interrupted or previous large crawl: paste a run ID or dataset ID and this run skips listings already collected there (deduped on `guid`), returning only the remaining new listings. An automatic same-run checkpoint also protects against platform migrations/resurrects without any input needed.

**Incremental mode** (`incrementalMode`) is for a schedule (for example, daily): the actor remembers the previous run of the *same* search by itself, so you never paste a run ID. The first run returns everything as `NEW`. Later runs return only `NEW`, `UPDATED`, and `REAPPEARED` listings by default — duplicates and unchanged listings are suppressed (and not charged, including the detail-enrichment surcharge). Turn on `emitUnchanged` or `emitExpired` only when you also want those rows returned (and billed for). State is isolated automatically per mode/keyword/location/filter/URL and `fetchDetails` setting; set `stateKey` to name or deliberately share a monitoring campaign. Raising `maxPages`, `maxListings`, or `maxNotifyListings` never starts a new baseline — those are run-size caps, not part of the tracked search.

Scheduled-run example — same search, run daily:

Day 1 (first run ever for this search):

```json
{ "mode": "search", "queries": ["python developer"], "incrementalMode": true }
```

→ every listing comes back with `"changeType": "NEW"`.

Day 2 (the schedule fires again, identical input):

```json
{ "mode": "search", "queries": ["python developer"], "incrementalMode": true }
```

→ listings that vanished or reappeared come back as `"changeType": "REAPPEARED"`, listings whose title/salary/company/description/etc. changed come back as `"changeType": "UPDATED"` with `changedFields` listing what changed, brand-new postings come back as `"changeType": "NEW"` — and listings that are still there, unchanged, are **not** returned at all (suppressed, not charged) unless `emitUnchanged` is on.

#### What counts as "changed"

Change detection compares every real listing field. Two fields are deliberately excluded from that comparison because they are not real listing data:

- `scrapedAt` — a per-run timestamp, stamped fresh on every push. Comparing it would make every re-scrape look "changed."
- `score` — the search **relevance score**. Measured live (2026-08-04): fetching the same search page twice, 3 seconds apart, changed `score` on 33 of 33 common listings while every other field (`easyApply`, `modifiedDate`, `url`) stayed byte-identical. It moves with the query and the rest of the index, not with the listing itself, so including it would make `emitUnchanged=false` runs never suppress anything.

Everything else — `title`, `company`, `salary`/`salaryMin`/`salaryMax`, `description`, `skills`, `employmentType`, `postedDate`, `modifiedDate`, `validThrough`, `easyApply`, and the location fields — is real data and does trigger `UPDATED` when it changes.

#### Cap semantics under incremental mode

`maxListings` (and the per-search share of it) counts listings **scanned**, not listings **emitted**. Outside incremental mode the two numbers are always equal, since nothing is suppressed. Under incremental mode with most listings `UNCHANGED`, counting emitted rows instead would make a quiet run walk deeper and deeper pages to "backfill" the cap with rows it is just going to suppress again — so cost would never drop even when nothing changed. Counting scanned listings means a quiet incremental run costs the same (in pages walked) as the equivalent full run, and stays there.

`emitExpired` only fires after a **complete** scan of the tracked search — never on a run capped by `maxListings`, a `resumeFromRunId` run, or a run that only fetched individual job detail URLs (those never walk a catalogue page, so there's no way to tell "gone" apart from "not reached"). A partial scan leaves previously-tracked listings' state untouched instead of guessing.

### Input Parameters

| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| mode | string | `search` | `search` builds a query from the fields below; `url` reads the URLs list. |
| queries | array | `["python developer"]` | Keywords. One scrape per keyword. |
| location | string | (empty) | City + state or country. Empty searches nationwide. |
| radius | integer | `0` | Distance around the location. 0 uses the site default. |
| radiusUnit | string | `mi` | `mi` or `km`. |
| countryCode | string | `US` | Two-letter country code for the market. |
| postedDate | string | `any` | `any`, `ONE`, `THREE`, or `SEVEN` (days). |
| employmentType | string | `any` | `FULLTIME`, `PARTTIME`, `CONTRACTS`, `THIRD_PARTY`. |
| workplaceType | string | `any` | `Remote`, `Hybrid`, `On-Site`. |
| employerType | string | `any` | `Recruiter` or `Direct Hire`. |
| easyApply | boolean | `false` | Only jobs with one-click Easy Apply. |
| willingToSponsor | boolean | `false` | Only jobs whose employer indicates visa-sponsor willingness. |
| sortBy | string | `relevance` | `relevance` or `date`. |
| urls | array | (example) | Dice URLs (URL mode). Filter fields are ignored. |
| fetchDetails | boolean | `false` | Also fetch each job page for full description, skills, and apply contact. |
| maxPages | integer | `0` | Safety bound on result pages per search. `0` = unlimited: walk the whole catalogue until a page comes back empty/repeats listings already collected (natural stop), or Max listings is hit first. Set a number only for an explicit page cap below that natural stop. |
| maxListings | integer | `20` | The sole soft cap on the run, across all searches. Defaults to 20 so a run stays small unless you raise it. `0` = unlimited (bounded only by the natural stop on Max pages). |
| proxy | object | Apify proxy | Connection routing. Works on any Apify plan. |
| mcpConnectors | array | (empty) | Optional MCP connectors to also receive results. |
| resumeFromRunId | string | (empty) | Optional prior run ID or dataset ID. Listings already saved by that run are loaded before scraping starts and skipped (deduped on `guid`), so this run only appends new listings — useful for continuing a large walk-all pull across separate runs. For recurring daily monitoring of the same search, use `incrementalMode` instead — see "Resume & recurring updates" above. |
| incrementalMode | boolean | `false` | Daily/recurring monitoring of this same search. First run returns everything as `NEW`; later runs return only `NEW`/`UPDATED`/`REAPPEARED` by default. See "Resume & recurring updates" above. |
| stateKey | string | (empty) | Optional name for a monitoring campaign, so its incremental state stays stable or is deliberately shared. Auto-derived from your search/URL and filter settings when left empty. |
| emitUnchanged | boolean | `false` | Incremental mode only. Also return listings unchanged since the last run, marked `UNCHANGED`. Adds and bills extra rows you already have. |
| emitExpired | boolean | `false` | Incremental mode only. Also return listings from a previous run no longer found, marked `EXPIRED`, once a run has fully scanned the search (not capped, not a resume, not detail-URLs-only). Adds and bills extra synthetic rows. |

### Output Example

> Sample shape, values are illustrative placeholders, not from a live listing.

```json
{
  "id": "00000000000000000000000000000000",
  "guid": "00000000-0000-0000-0000-000000000000",
  "url": "https://www.dice.com/job-detail/00000000-0000-0000-0000-000000000000",
  "title": "Senior Python Developer",
  "company": "Sample Company",
  "companyProfileUrl": "https://www.dice.com/company-profile/00000000-0000-0000-0000-000000000000",
  "city": "Austin",
  "state": "Texas",
  "country": "USA",
  "locationDisplay": "Austin, Texas, USA",
  "workplaceTypes": ["Remote"],
  "remote": true,
  "salary": "USD 120,000.00 - 150,000.00 per year",
  "salaryMin": 120000,
  "salaryMax": 150000,
  "salaryCurrency": "USD",
  "salaryPeriod": "year",
  "employmentType": "Full-time",
  "employerType": "Direct Hire",
  "easyApply": false,
  "willingToSponsor": false,
  "skills": ["Python", "AWS", "PostgreSQL"],
  "positionId": "R000000",
  "postedDate": "2026-01-01T00:00:00Z",
  "modifiedDate": "2026-01-02T00:00:00Z",
  "validThrough": "2026-02-01T00:00:00Z",
  "applyType": "APPLY_TO_URL",
  "applyUrl": "https://careers.example.com/apply/0000",
  "applyEmail": "recruiter@example.com",
  "emails": ["recruiter@example.com"],
  "summary": "Sample summary text appears here.",
  "description": "<p>Full HTML description appears here when fetchDetails is on.</p>",
  "companyReviews": null,
  "scrapedAt": "2026-01-01T00:00:00.000Z"
}
```

With `incrementalMode` on, every record additionally carries `changeType` (`NEW`/`UPDATED`/`UNCHANGED`/`REAPPEARED`/`EXPIRED`), `changedFields` (array, populated only for `UPDATED`), `firstSeenAt`, and `lastSeenAt` — see "Resume & recurring updates" above.

### Send results into your apps (MCP connectors)

Optionally push each result into the tools you already use, through Model Context Protocol (MCP) connectors. Authorize a connector once under Apify, Settings, Integrations, then select it in the `mcpConnectors` input. For Notion, also set `notionParentPageUrl`. The connector receives a condensed, human-readable summary per item (title plus key fields); the complete record always stays in the Apify dataset. Leave the field empty to skip. Supported connectors include Notion, Linear, Airtable, and Apify.

### Plan Requirement

Runs on any Apify plan, including the free tier. A paid plan with residential routing is optional and can improve reliability for very large runs.

# Actor input Schema

## `mode` (type: `string`):

Search mode = pick keywords + location + filters below. URL mode = paste any dice.com search or job URL refined in your browser.

## `queries` (type: `array`):

Free-text search terms (e.g. "python developer", "data engineer", "devops"). One scrape per keyword. Leave empty to browse without a keyword filter.

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

City + state or country. Examples: "New York, NY, USA", "Austin, TX, USA". Leave empty to search nationwide.

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

Distance around the location to include. Leave at 0 to use the site default radius. Ignored when Location is empty.

## `radiusUnit` (type: `string`):

Unit for the search radius.

## `countryCode` (type: `string`):

Two-letter country code for the job market (Dice is primarily US). Example: "US".

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

Only return jobs posted within this window. "Any time" walks the unfiltered results.

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

Filter by employment scope. "Any" walks the unfiltered results.

## `workplaceType` (type: `string`):

Filter by on-site / hybrid / remote arrangement. "Any" walks the unfiltered results.

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

Filter by who posted the job. "Any" walks the unfiltered results.

## `easyApply` (type: `boolean`):

Only return jobs that support one-click Easy Apply.

## `willingToSponsor` (type: `boolean`):

Only return jobs whose employer indicates willingness to sponsor a visa.

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

Result ordering. "Relevance" is the site default; "Date" surfaces the most recently posted first.

## `urls` (type: `array`):

One or more dice.com URLs. Examples: https://www.dice.com/jobs?q=python%20developer\&countryCode=US, or a single job URL like https://www.dice.com/job-detail/00000000-0000-0000-0000-000000000000. Multi-URL supported; each URL pages forward independently. Filter fields above are ignored.

## `fetchDetails` (type: `boolean`):

When ON, also fetch each job's detail page for the full HTML description, skills list, structured street address, apply URL/email, valid-through date, and structured salary. Search results already carry id, title, company, location, salary, employment type, posted date, and summary, so many feeds work great with this OFF. Default OFF.

## `maxPages` (type: `integer`):

Safety bound on how many result pages to walk per keyword (or per pasted URL). Each page returns roughly 20 listings. 0 (default) means unlimited - the walk stops naturally once a page comes back empty or repeats listings already collected, or sooner once Max listings is reached. Set a number only for an explicit page cap below that natural stop.

## `maxListings` (type: `integer`):

The sole soft cap on the run: stop after this many listings across all searches. Defaults to 20 so a run stays small unless you raise it. 0 = unlimited (bounded only by the natural stop on Max pages).

## `proxy` (type: `object`):

Connection routing. The default works on any Apify plan, including the free tier. Residential routing is optional and can improve reliability under heavy use.

## `mcpConnectors` (type: `array`):

Optionally send the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize a connector once under Apify → Settings → Integrations, then select it here. The connector receives a condensed, human-readable summary per item (title + key fields), not the full JSON — the complete record stays in the dataset. Leave empty to skip. Supported: Notion (https://mcp.notion.com/mcp), Linear (https://mcp.linear.app/sse), Airtable (https://mcp.airtable.com/mcp), Apify (https://mcp.apify.com).

## `notionParentPageUrl` (type: `string`):

URL (or id) of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors.

## `maxNotifyListings` (type: `integer`):

Cap on items written to each connector per run. Does not affect the dataset.

## `resumeFromRunId` (type: `string`):

Optional. Paste a previous run ID or dataset ID to continue a large walk-all pull: listings already saved by that run are loaded before scraping starts and skipped, so this run only appends new listings. For recurring daily monitoring of the same search, use Incremental mode below instead.

## `incrementalMode` (type: `boolean`):

Turn this on for daily or recurring monitoring. The first run returns all matching listings as NEW. Later runs normally return only NEW, UPDATED, and REAPPEARED listings. Turn on "Emit unchanged" or "Emit expired" only when you also want those listings returned (and billed). State is kept separately for each mode/keyword/location/filter/URL and detail-fetch setup; use State key when you want to name or deliberately share a monitoring campaign. To continue one specific interrupted run instead, use Resume from a prior run above.

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

Optional. Name this monitoring campaign to keep its state stable, or to deliberately share state across differently-configured runs. Leave empty to let the actor derive a key automatically from the search/URL and filter settings — different searches then never mix state with each other.

## `emitUnchanged` (type: `boolean`):

Off by default. Turn on to also return listings that have not changed since the last run, marked UNCHANGED. This returns — and bills — extra rows you already have, so leave it off unless you specifically want the full snapshot every run.

## `emitExpired` (type: `boolean`):

Off by default. Turn on to also return listings that were present in a previous run but are no longer found, marked EXPIRED. Only produced once a run has fully scanned the tracked search — not when Max listings capped it, when Resume was used, or on a run that only fetched individual job detail URLs. This returns — and bills — extra synthetic rows, so leave it off unless you need expiry tracking.

## Actor input object example

```json
{
  "mode": "search",
  "queries": [
    "python developer"
  ],
  "radius": 0,
  "radiusUnit": "mi",
  "countryCode": "US",
  "postedDate": "any",
  "employmentType": "any",
  "workplaceType": "any",
  "employerType": "any",
  "easyApply": false,
  "willingToSponsor": false,
  "sortBy": "relevance",
  "urls": [
    "https://www.dice.com/jobs?q=python%20developer&countryCode=US"
  ],
  "fetchDetails": false,
  "maxPages": 0,
  "maxListings": 20,
  "proxy": {
    "useApifyProxy": true
  },
  "maxNotifyListings": 50,
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false
}
```

# Actor output Schema

## `overview` (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 = {
    "mode": "search",
    "queries": [
        "python developer"
    ],
    "location": "",
    "urls": [
        "https://www.dice.com/jobs?q=python%20developer&countryCode=US"
    ],
    "proxy": {
        "useApifyProxy": true
    },
    "incrementalMode": false,
    "emitUnchanged": false,
    "emitExpired": false
};

// Run the Actor and wait for it to finish
const run = await client.actor("abotapi/dice-com-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 = {
    "mode": "search",
    "queries": ["python developer"],
    "location": "",
    "urls": ["https://www.dice.com/jobs?q=python%20developer&countryCode=US"],
    "proxy": { "useApifyProxy": True },
    "incrementalMode": False,
    "emitUnchanged": False,
    "emitExpired": False,
}

# Run the Actor and wait for it to finish
run = client.actor("abotapi/dice-com-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "mode": "search",
  "queries": [
    "python developer"
  ],
  "location": "",
  "urls": [
    "https://www.dice.com/jobs?q=python%20developer&countryCode=US"
  ],
  "proxy": {
    "useApifyProxy": true
  },
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false
}' |
apify call abotapi/dice-com-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=abotapi/dice-com-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/tH2RK0hZMDwvqzpZ8/builds/T9QweIBdOGv78b2hj/openapi.json
