# We Work Remotely Jobs Scraper | 💵$2 per 1,000 (`webdata_labs/weworkremotely-jobs-scraper`) Actor

\[💵 $2 / 1K · no start fee] Every live We Work Remotely posting, not the first 25 per category. Full description, exact posted and expiry dates, salary parsed into numbers, eligible countries as ISO codes and the hiring company's own website - all in the per-job price.

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

## Pricing

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

## We Work Remotely Jobs Scraper

**Every live posting on We Work Remotely, with the full job description and the hiring company's own website, for one flat price per job.**

We Work Remotely is the largest remote job board on the web, and it has no API. Its own search page only renders about 25 cards per category however many jobs match, so a scraper pointed at search quietly returns a fraction of the board and nothing tells you rows are missing. This Actor reads the category pages instead, which render the complete list, and then normalizes what the board leaves as loose text: salary brackets become numbers, flag chips become ISO country codes, the "New" badge becomes a real publication timestamp, and every hiring company is resolved to its own domain.

### ✅ What you get / ❌ what this isn't

| ✅ What you get | ❌ What this isn't |
|---|---|
| **The complete category listing**, roughly 700 live jobs across all ten categories | Not the ~25-per-category search preview that looks complete and is not |
| **Full description included in the per-job price**, as clean text and as HTML | Not a cheap listing row with descriptions billed separately at ten times the price |
| **Exact `postedAt` and `expiresAt` timestamps** read from the board's own feed | Not a relative "11d" string you have to date-math yourself |
| **`salaryMin` / `salaryMax` as numbers** plus the currency | Not a `$50,000 - $74,999 USD` string glued into one cell |
| **Eligible countries as ISO 2-letter codes**, plus an `isWorldwide` flag | Not a row of flag emoji you have to translate |
| **The employer's own website and domain** for every hiring company | Not just a link back to the job board profile |
| **`onlyNew` dedup across scheduled runs** | Not the same 700 rows re-delivered and re-charged every week |

### 🔎 Why use this Actor

- **Full category coverage, by construction.** The Actor reads `/categories/<category>`, which renders every job filed under it. The site's search endpoint caps each category section at about 25 cards, so anything built on search silently undercounts. The bundled canary measures both numbers on every run of the test suite and fails if the gap closes.
- **Descriptions cost one request per category, not one per job.** Each category publishes an RSS feed carrying the same body text and the exact publication date as the detail page, for effectively the whole category. The Actor reads that first and only falls back to per-job pages for what the feed missed, which is why full descriptions fit inside a $2 / 1K price.
- **The freshness filter uses the real date.** An employer can bump a month-old posting and the card says "New" again. `postedWithinDays` is measured against the publication timestamp, so a "posted this week" run does not fill up with refreshed old listings. `postedAgoText` still reports the badge exactly as the board showed it.
- **Filters run before any paid request.** Country, salary, job type, keyword and company filters are applied to the listing card, so a strict filter costs you one category page rather than a page of rows you did not want.
- **Worldwide postings are handled correctly.** A job marked "Anywhere in the World" is open to Germany too, so it counts as a match for `countries: ["DE"]`. Set `includeWorldwide: false` when you specifically want country-restricted roles.
- **One bumped posting is one row.** A refreshed job can appear twice on the same page under one URL. The Actor keeps the fresher card and drops the twin, so you are never charged for the same job twice.
- **Every row has every column.** Fields the source left empty come back as `null` or `[]` rather than vanishing, so the CSV export is rectangular and downstream joins do not break.

### 👥 Who it's for

Recruiters and sourcers tracking who is hiring remotely, job-board and aggregator operators who need a clean feed, B2B teams prospecting companies that hire remote talent, and analysts benchmarking remote pay and hiring volume.

- Build a weekly list of new remote engineering roles open to your country.
- Feed a job board or newsletter with normalized rows instead of scraped HTML.
- Turn "companies hiring remotely this month" into a domain list for outbound.
- Track how many roles a competitor has open, and in which categories.
- Benchmark published salary brackets by category and engagement type.

### Example tasks

- [Scrape all remote jobs on We Work Remotely](https://apify.com/webdata_labs/weworkremotely-jobs-scraper/examples/we-work-remotely-all-remote-jobs)
- [Scrape remote programming jobs](https://apify.com/webdata_labs/weworkremotely-jobs-scraper/examples/we-work-remotely-programming-jobs)
- [Scrape remote design jobs](https://apify.com/webdata_labs/weworkremotely-jobs-scraper/examples/we-work-remotely-design-jobs)
- [Scrape remote customer support jobs](https://apify.com/webdata_labs/weworkremotely-jobs-scraper/examples/we-work-remotely-customer-support-jobs)
- [Find remote jobs paying $100,000 or more](https://apify.com/webdata_labs/weworkremotely-jobs-scraper/examples/remote-jobs-paying-100k)
- [Find remote contract and freelance jobs](https://apify.com/webdata_labs/weworkremotely-jobs-scraper/examples/remote-contract-freelance-jobs)
- [Find remote jobs open to the United States](https://apify.com/webdata_labs/weworkremotely-jobs-scraper/examples/remote-jobs-hiring-in-usa)
- [Monitor new remote jobs every week](https://apify.com/webdata_labs/weworkremotely-jobs-scraper/examples/new-remote-jobs-weekly-monitor)
- [Build a list of companies hiring remotely](https://apify.com/webdata_labs/weworkremotely-jobs-scraper/examples/companies-hiring-remotely-lead-list)

### ⚙️ How to scrape We Work Remotely jobs

1. Click **Try for free** and open the Input tab.
2. Pick one or more **Categories**, or leave the field empty to scan the whole board.
3. Narrow the run with any combination of **Title or company keywords**, **Countries**, **Salary ranges**, **Job types** and **Posted within (days)**.
4. Set **Max results**. The default of 50 keeps a first run cheap; `0` returns everything that matched.
5. Click **Start**. Results stream into the dataset as they are enriched, so you can watch the first rows arrive while the run continues.
6. Open the **Output** tab to browse the table, or export to CSV, Excel, JSON or XML from the Storage tab.

#### Get only the new jobs every week

Turn on **Only jobs not seen in previous runs**, save the configuration as a task, and schedule it. The Actor remembers the job IDs each run returned and skips them next time, so the second run delivers only postings that appeared since the first. The memory is kept separately per filter combination, so a "new design jobs" schedule and a "new devops jobs" schedule can run side by side without eating each other's history.

### 📥 Input

```json
{
  "categories": ["Full-Stack Programming", "DevOps and Sysadmin"],
  "searchTerms": ["senior"],
  "countries": ["US"],
  "jobTypes": ["Full-Time"],
  "postedWithinDays": 7,
  "includeDescription": true,
  "includeCompanyProfile": true,
  "maxItems": 100
}
```

- `categories` - which of the ten We Work Remotely categories to scan. Empty means all of them.
- `searchTerms` - keep jobs whose title or company name contains any of these words. Case-insensitive substring match.
- `excludeKeywords` - drop jobs whose title or company name contains any of these words.
- `companies` - keep only these employers. Company name or board slug, punctuation and case ignored.
- `jobUrls` - scrape named postings directly instead of scanning categories. Full URLs or bare slugs. Filters are not applied to these.
- `countries` - ISO 2-letter codes or country names. Worldwide postings count as a match by default.
- `includeWorldwide` - default `true`. Set to `false` to exclude "Anywhere in the World" jobs from a country filter.
- `salaryRanges` - one or more of the board's five published brackets. `$100k`, `100000` and the full bracket string all resolve.
- `requireSalary` - keep only postings that publish a bracket at all.
- `jobTypes` - Full-Time, Part-Time, Full-Time/Part-Time, Contract, Internship.
- `postedWithinDays` - freshness cut-off measured against the real publication date. `0` means any age.
- `onlyTop100`, `onlyFeatured`, `onlyHot` - board badges, useful for filtering down to actively promoted roles.
- `onlyNew` - only jobs not returned by a previous run with the same filters. Meant for schedules.
- `includeDescription` - default `true`. Adds the description, exact dates, eligibility list, contact emails and ATS link. Advanced: turn it off for a faster listing-only run at the same price.
- `includeCompanyProfile` - default `true`. Adds the employer's own website, domain, headquarters and job count. Advanced: turn it off to skip one request per company.
- `maxItems` - rows for the run, newest first. Default 50, `0` for unlimited. There is no hard ceiling.

Field names from other We Work Remotely Actors are accepted too: `maxResults`, `includeDetails`, `engagementType`, `timeFilter`, `term` and `query` all work, so competitor input JSON runs here unchanged.

### 📤 Output

| title | companyName | jobType | salaryText | regions | postedAt | companyDomain |
|---|---|---|---|---|---|---|
| Data Engineering Manager | Doximity | Full-Time | | Anywhere in the World | 2026-08-02T09:14:00Z | doximity.com |
| AI Product Engineer | ClickHouse | Full-Time | $100,000 or more USD | Anywhere in the World | 2026-08-01T15:02:11Z | clickhouse.com |
| Customer Support Agent | CRAE GROUP LTD | Full-Time | $10,000 - $25,000 USD | 🇧🇬 🇨🇾 🇵🇱 🇺🇦 | 2026-07-31T08:40:52Z | craegroup.com |

Each row also carries `jobId` and `url` for the posting, `companySlug`, `companyUrl`, `companyLogoUrl`, `companyHeadquarters`, `companyHeadquartersFull` and `companyJobsPosted` for the employer, `category`, `categorySlug` and `categoryUrl` for where it is filed, `jobTypes` as an array when a posting names more than one, `salaryMin`, `salaryMax` and `salaryCurrency` as parsed numbers, `countryCodes` and `countryNames` from the card plus `applicantCountryCodes` and `applicantCountryCount` for the full eligibility list, `isWorldwide`, `isFeatured`, `isBoosted`, `isTop100`, `isHot` and `isNew` as booleans, `postedAgoText`, `daysSincePosted`, `postedAtIsExact` and `expiresAt` for freshness, `description`, `descriptionHtml` and `descriptionLength` for the body, `contactEmails` and `atsApplyUrl` when the posting exposes them, `detailError` when a single posting could not be read, and `scrapedAt`.

Four dataset views ship with the Actor: **Jobs** for the scannable overview, **Full descriptions** for the body text, **Hiring companies** for the domain list, and **Published salaries** for pay benchmarking.

### 💵 How much does it cost?

**\[💵 $2.00 / 1K]** per job returned, with no Actor start fee. One price covers the listing, the full description and the company website: there is no separate detail charge and no cheaper tier that leaves out the body text. You are charged only for rows that reach the dataset, so jobs removed by your filters are free.

A typical run costs very little because the board is small: the whole of We Work Remotely measured 721 live postings on 2026-08-02, so scraping every job in every category costs about $1.44. A single category is usually 15 to 160 jobs. Lower per-result prices apply automatically on higher Apify subscription tiers.

### 🔁 Run it on the Apify platform

Save any configuration as a task and schedule it hourly, daily or weekly, then let the results land where you work. The dataset exports to CSV, Excel, JSON, XML and RSS, and the Apify API gives you the same rows programmatically with a single call. Webhooks fire when a run finishes, so you can push new jobs into Slack, Google Sheets, Airtable, a CRM or your own database through Make, Zapier or a plain HTTP endpoint. Combined with `onlyNew`, a weekly schedule turns into a hands-off feed of jobs you have not seen before.

### ⚠️ Limits and caveats

- **No external apply link.** We Work Remotely puts its own "Apply now" button behind a free account for every posting, so there is no application URL to scrape. `url` points at the board's job page, which is where a candidate applies. `atsApplyUrl` is filled only when the employer pasted a Greenhouse, Lever, Ashby or similar link into the description body, which happened on 5 of the 721 live postings measured on 2026-08-02.
- **Salary is usually not published.** Only 6% of live postings showed a bracket when the whole board was measured on 2026-08-02. `salaryText`, `salaryMin` and `salaryMax` are `null` for the rest, and no salary is inferred from the description. Expect `requireSalary` and `salaryRanges` to return small sets.
- **Contact emails are rare.** About 11% of postings mention an email in the body. `contactEmails` is an empty array for the rest, and no address is guessed from the domain.
- **The board is small and the archive is not scrapeable.** Only currently live postings are listed; expired jobs drop off the category pages and cannot be recovered. Roughly 700 jobs live at any time is the ceiling of what any We Work Remotely scraper can return.
- **The "New" badge is a bump marker.** An employer can refresh an old posting and the card says "New" again. `daysSincePosted` and `isNew` follow the real publication date instead, which means they can disagree with `postedAgoText`. That disagreement is the honest answer, not a bug.
- **Category is the board's own filing, not a skill taxonomy.** A React role can sit under Full-Stack, Front-End or All Other Remote depending on how the employer filed it. Scan several categories, or leave the field empty, when completeness matters more than tidiness.
- **A handful of company profiles have no website link**, so `companyWebsite` and `companyDomain` come back `null` for those employers.
- **Full descriptions for very old postings cost an extra request each.** Anything the category feed no longer covers falls back to its own detail page. This does not change the price, only the run time.

### 🧩 Related Actors

- **[ATS Jobs Scraper](https://apify.com/webdata_labs/greenhouse-lever-ashby-jobs-scraper)** - once you know which companies are hiring, pull their full role list straight from Greenhouse, Lever, Ashby or Workday, including the roles they never posted to a job board.
- **[Company Career Page Jobs API](https://apify.com/webdata_labs/company-career-page-jobs-api)** - feed the `companyDomain` column in and get the jobs published on the company's own careers page.
- **[ATS Hiring Monitor API](https://apify.com/webdata_labs/ats-hiring-monitor-api)** - watch the same employers over time and get told when roles open or close.
- **[Website Contact Extractor](https://apify.com/webdata_labs/website-contact-extractor)** - turn the `companyWebsite` column into emails, phone numbers and social profiles.
- **[Website Tech Stack Detector](https://apify.com/webdata_labs/website-tech-stack-detector)** - qualify the same domains by the technologies they run.
- **[Lead List Deduplicator & Normalizer](https://apify.com/webdata_labs/lead-list-deduplicator)** - merge several runs, or this Actor's output with another source, into one clean list.

### ❓ FAQ

**Am I charged for jobs my filters removed?**
No. Filtering happens on the listing card before any detail or company request, and you are charged only for rows written to the dataset.

**Does the description really cost nothing extra?**
Yes. There is one event, `job-scraped`, at $2 per 1,000. Descriptions are included because the board publishes them in its category feeds, so reading them costs one request per category rather than one per job.

**How many jobs can I get in total?**
Whatever is live, which is roughly 700 across all ten categories. Expired postings are removed by the board and cannot be scraped afterwards, so there is no historical archive to pull.

**Which countries does it cover?**
All of them. Most We Work Remotely jobs are open worldwide; the rest name specific countries, which are returned as ISO 2-letter codes in `countryCodes` and, when the description is included, as the complete eligibility list in `applicantCountryCodes`.

**How does the weekly new-jobs feature work?**
`onlyNew` stores the job IDs a run returned in a key-value store, keyed by your filter combination, and skips them on the next run with the same filters. Change the filters and you get a fresh memory rather than a polluted one.

**Do I need a proxy, a login or an API key?**
No. There is nothing to configure. Proxying and request pacing are handled inside the Actor.

**Can I pass input written for another We Work Remotely Actor?**
Usually yes. `maxResults`, `includeDetails`, `engagementType`, `timeFilter`, `term` and `query` are all accepted, and category values are matched loosely, so `full-stack-programming` and `Full-Stack Programming` both work.

### 🛠️ Support

Something wrong? Open an Actor issue with the run URL, the input you used and what you expected to see. Issues with a run URL get fixed fastest.

### ⭐ Rate this Actor

If this saved you time, please leave a rating on the Reviews tab. Reviews are the main trust signal other buyers have, and they decide what gets built and improved next. If something is broken or missing, open an issue first so it can be fixed before you rate.

# Actor input Schema

## `categories` (type: `array`):

We Work Remotely categories to scan. Empty means all ten. The full category page is read, not the search preview, so you get every job filed under the category rather than the first 25.

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

Keep only jobs whose title or company name contains one of these words. Case-insensitive, matched as a substring, and a job matching any one of them is kept. Example: "senior", "react".

## `excludeKeywords` (type: `array`):

Drop jobs whose title or company name contains one of these words. Runs after the keyword filter. Example: "intern", "sales".

## `companies` (type: `array`):

Keep only jobs from these companies. Company name or the We Work Remotely company slug both work, and matching ignores case and punctuation.

## `jobUrls` (type: `array`):

Scrape named postings instead of scanning categories. Full URLs such as https://weworkremotely.com/remote-jobs/stripe-fullstack-engineer-privy, or the bare slug. Filters are not applied to these.

## `countries` (type: `array`):

Keep jobs open to these countries. ISO 2-letter codes ("US", "DE") or country names both work. Jobs marked "Anywhere in the World" are open to any country and are kept as matches unless you switch that off below.

## `includeWorldwide` (type: `boolean`):

On by default. Turn off to get only postings that name your country explicitly, excluding the "Anywhere in the World" majority. Has no effect when no country is set.

## `salaryRanges` (type: `array`):

Keep only jobs carrying one of these published salary brackets. Fewer than one in ten We Work Remotely postings publishes a bracket at all, so this filter is narrow by nature.

## `requireSalary` (type: `boolean`):

Keep only postings that show a salary bracket, whichever bracket it is. Useful for pay benchmarking; expect a small result set.

## `jobTypes` (type: `array`):

Keep only these engagement types. Empty means all of them.

## `postedWithinDays` (type: `integer`):

Keep only jobs posted in the last N days. 0 means any age. Measured from the real publication timestamp, not the board's "New" badge, which resets whenever an employer bumps an old posting.

## `onlyTop100` (type: `boolean`):

Keep only jobs from companies We Work Remotely badges as Top 100.

## `onlyFeatured` (type: `boolean`):

Keep only postings the employer paid to highlight. These are usually the best-funded, most actively hiring companies.

## `onlyHot` (type: `boolean`):

Keep only postings carrying the board's hot-job flame, which marks unusually high applicant interest.

## `onlyNew` (type: `boolean`):

Remembers the job IDs each run returned and skips them next time, so a scheduled run returns only postings you have not seen yet. The memory is kept per filter combination, so several schedules can run side by side.

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

On by default. Adds the complete posting body as clean text and as HTML, plus the exact posted and expiry timestamps, the full list of eligible countries, any contact emails and the employer's own ATS link when the posting carries one.

## `includeCompanyProfile` (type: `boolean`):

On by default. Adds the hiring company's own website and domain, its headquarters and how many jobs it has posted on the board. One request per company, cached across the run.

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

Jobs returned by the run, newest first. The default keeps a first run cheap; set 0 for unlimited - there is no hard ceiling, and the whole board is roughly 700 live postings.

## Actor input object example

```json
{
  "categories": [
    "Full-Stack Programming",
    "DevOps and Sysadmin"
  ],
  "searchTerms": [
    "senior",
    "react"
  ],
  "excludeKeywords": [
    "intern"
  ],
  "companies": [
    "Stripe",
    "coinbase"
  ],
  "jobUrls": [
    "https://weworkremotely.com/remote-jobs/stripe-fullstack-engineer-privy"
  ],
  "countries": [
    "US",
    "Germany"
  ],
  "includeWorldwide": true,
  "salaryRanges": [
    "$100,000 or more USD"
  ],
  "requireSalary": false,
  "jobTypes": [
    "Contract"
  ],
  "postedWithinDays": 7,
  "onlyTop100": false,
  "onlyFeatured": false,
  "onlyHot": false,
  "onlyNew": false,
  "includeDescription": true,
  "includeCompanyProfile": true,
  "maxItems": 20
}
```

# Actor output Schema

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

No description

## `descriptions` (type: `string`):

No description

## `companies` (type: `string`):

No description

## `salaries` (type: `string`):

No description

## `runSummary` (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 = {
    "categories": [
        "Full-Stack Programming"
    ],
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("webdata_labs/weworkremotely-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 = {
    "categories": ["Full-Stack Programming"],
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("webdata_labs/weworkremotely-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 '{
  "categories": [
    "Full-Stack Programming"
  ],
  "maxItems": 20
}' |
apify call webdata_labs/weworkremotely-jobs-scraper --silent --output-dataset

```

## MCP server setup

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