# Upwork Jobs History — 3M+ Postings Since 2024, by Period, Skill (`hyperbach/upwork-jobs-history`) Actor

Every Upwork job posting since November 2024: the last 3, 6 or 12 months or all of it, narrowed by category and skill. Full description, budget, skills, and the client's spend, hires and rating as they stood the day the job was posted. $0.20 per 1,000 rows, less on paid plans; free estimate.

- **URL**: https://apify.com/hyperbach/upwork-jobs-history.md
- **Developed by:** [Hyperbach](https://apify.com/hyperbach) (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 $0.10 / 1,000 job postings

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

## Upwork Jobs History — 3M+ Postings Since 2024, by Period, Skill

**Every Upwork job posting since November 2024 — 3.28 million of them on 2026-09-26 — for the last 3, 6 or 12 months or all of it, narrowed by category, subcategory and skill.** Full description, budget, skills, and the client's spend, hires, rating and average hourly rate paid **as they stood on the day the job was posted**, not as they are today. Every Shopify job of the last year, every data-science posting since 2024, or the whole archive in one run. **$0.20 per 1,000 postings, less on paid plans, plus $0.25 per run** — and a free estimate of the size and the price before you buy. For the last 90 days, searchable by keyword with filters, use [Upwork Job Scraper](https://apify.com/hyperbach/upwork-scraper-ai).

### Why this dataset

- **Fixed on the day it was posted.** Every column is one Upwork froze when the job went up, or a figure about the client read within minutes of it: total spent, hires, jobs posted, rating, reviews, average hourly rate paid — on that day. Columns that move after posting (proposals, interviews, the client's later history) are left out on purpose, so a row read today and a row read next year say the same thing.
- **3,287,228 postings, November 2024 to August 2026** (read 2026-09-26). Between 93,404 and 193,230 a month since December 2024; November 2024, when collection began, holds 12,380. The newest month on sale is the one 30 days behind today, and the status message names the day it runs through.
- **Ask the way you think about it.** The last 3, 6 or 12 months, or everything since November 2024 — or exact dates when you need them. Narrow by any of Upwork's 12 categories (plus the ~1% of postings published without one), any of its 65 subcategories — Ecommerce Development, AI & Machine Learning, Video & Animation — and by skills: `shopify` finds Shopify and Shopify Theme, `machine learning` finds Machine Learning Model. Rows outside the selection are never delivered and never charged. Delivered in order: month, then category, then time of posting.
- **Full text.** The description as the client published it, not a preview: median 575 characters in June 2025, one in ten over 2,000.
- **Price it before you buy it.** `estimate: true` counts the postings in any selection and prices them for your plan, by month and by category, and delivers and charges nothing.
- **Everything in one run.** Rows are served from files written once per month, not queried per run: about 1,500 postings a second into your dataset (17,117 rows in 16 s, 2026-09-26), so the whole archive takes about 40 minutes. A run that meets its own timeout stops cleanly, charges only what it delivered, and names the date to start the next run from.

### Who it's for

- **Market and pricing research** — what clients in a niche asked for and offered to pay, month by month, with the client's spend and hire record beside every budget.
- **Freelancers and agencies choosing a niche** — every posting for your skill over the last year, with budgets and the clients behind them, to see where the demand and the paying clients are before you commit.
- **Data and AI teams** — the whole archive, or the slice you need: a typed corpus of real job descriptions with budgets, skills and categories, for classification, extraction and forecasting.
- **Anyone who needs the past, not the feed** — postings that closed long ago, as they were published, which Upwork itself no longer shows.

### Quick start

**Shopify jobs of the last 12 months**

```json
{
  "period": "12m",
  "categories": [
    "web-mobile-software-dev"
  ],
  "skills": [
    "shopify"
  ]
}
```

**AI & Machine Learning jobs of the last 12 months**

```json
{
  "period": "12m",
  "subcategories": [
    "AI & Machine Learning",
    "AI Apps & Integration"
  ]
}
```

**Data science jobs of the last 6 months**

```json
{
  "period": "6m",
  "categories": [
    "data-science-analytics"
  ]
}
```

**Price the whole archive, free**

```json
{
  "period": "all",
  "estimate": true
}
```

**Exact dates**

```json
{
  "from": "2026-06-01",
  "to": "2026-06-30",
  "categories": [
    "legal"
  ]
}
```

### Output

One record per job posting:

| field | meaning |
|---|---|
| `id` | Upwork's job id, the number after `~` in the posting URL. Unique across the whole history. |
| `url` | The posting on Upwork. A closed or removed posting may no longer open; the row keeps what it said. |
| `postedAt` | When Upwork published the posting, UTC, ISO 8601. The month a row belongs to is this date's month. |
| `title` | The posting's title as the client wrote it. |
| `description` | The full description as first published, not a preview. |
| `category` | Upwork's top-level category, one of 12. Null on about 1% of postings, which Upwork published without one; those are sold as Uncategorized. Filled on 99% of rows (read 2026-09-26). |
| `subcategory` | Upwork's subcategory within the category, e.g. Web Development. Filled on 99% of rows (read 2026-09-26). |
| `skills` | The skills the client attached, in Upwork's wording. Filled on 99% of rows (read 2026-09-26). |
| `jobType` | `hourly` or `fixed`. |
| `fixedPrice` | The budget of a fixed-price job. Null on hourly jobs. Filled on 45% of rows (read 2026-09-26). |
| `hourlyMin` | The low end of an hourly job's rate range. Null when the client gave none, and on fixed-price jobs. Filled on 39% of rows (read 2026-09-26). |
| `hourlyMax` | The high end of an hourly job's rate range. Filled on 39% of rows (read 2026-09-26). |
| `experienceLevel` | `entry`, `intermediate` or `expert`. Filled on 99% of rows (read 2026-09-26). |
| `duration` | The expected length, in Upwork's wording: Less than 1 month, 1 to 3 months, 3 to 6 months, More than 6 months. Filled on 64% of rows (read 2026-09-26). |
| `workload` | Hours per week for hourly jobs, in Upwork's wording: Less than 30 hrs/week, More than 30 hrs/week. Filled on 35% of rows (read 2026-09-26). |
| `contractToHire` | The client marked the job as possibly leading to a full-time hire. |
| `englishLevel` | The English level asked for: `any`, `conversational`, `fluent` or `native`. Filled on 99% of rows (read 2026-09-26). |
| `clientCountry` | The client's country, as Upwork showed it on the posting. Filled on 99% of rows (read 2026-09-26). |
| `clientPaymentVerified` | The client's payment method was verified when the job was posted. Filled on 82% of rows (read 2026-09-26). |
| `clientMemberSince` | The date the client joined Upwork, ISO 8601. Filled on 84% of rows (read 2026-09-26). |
| `clientTotalSpentAtPosting` | What the client had spent on Upwork in total, on the day the job was posted. Filled on 62% of rows (read 2026-09-26). |
| `clientHiresAtPosting` | Freelancers the client had hired in total, on the day the job was posted. Filled on 72% of rows (read 2026-09-26). |
| `clientJobsPostedAtPosting` | Jobs the client had posted in total, on the day the job was posted. Filled on 69% of rows (read 2026-09-26). |
| `clientRatingAtPosting` | The client's average rating from freelancers (0-5), on the day the job was posted. Filled on 62% of rows (read 2026-09-26). |
| `clientReviewsAtPosting` | How many freelancer reviews that rating was based on. Filled on 66% of rows (read 2026-09-26). |
| `clientCompanySize` | The lower bound of the company-size band the client chose: 1, 2 (2-9), 10 (10-99), 100, 500, 1000, 5000, 10000. Filled on 41% of rows (read 2026-09-26). |
| `clientIndustry` | The industry the client chose on Upwork, e.g. Tech & IT. Filled on 31% of rows (read 2026-09-26). |
| `clientHireRateAtPosting` | The share of the client's postings that ended in a hire, in percent (0-100), on the day the job was posted. Recorded since February 2026, on every posting from then; null before. |
| `clientAvgHourlyRatePaidAtPosting` | The average hourly rate the client had paid, on the day the job was posted. Filled on 40% of rows (read 2026-09-26). |

Example record:

```json
{
  "id": "021929210319849117903",
  "url": "https://www.upwork.com/jobs/~021929210319849117903",
  "postedAt": "2025-06-01T16:15:58Z",
  "title": "Technical Expert Needed for Meta Pixel and GTM Tracking Issues",
  "description": "We are seeking a technical expert to troubleshoot and resolve issues with Meta Pixel and Google Tag Manager (GTM) tracking on our hotel booking engine. Our current setup is failing …(truncated for display)",
  "category": "Data Science & Analytics",
  "subcategory": "Data Analysis & Testing",
  "skills": [
    "Google Analytics",
    "Google Tag Manager",
    "JavaScript",
    "Google Ads",
    "WordPress"
  ],
  "jobType": "hourly",
  "fixedPrice": null,
  "hourlyMin": 25,
  "hourlyMax": 50,
  "experienceLevel": "expert",
  "duration": "1 to 3 months",
  "workload": null,
  "contractToHire": false,
  "englishLevel": "any",
  "clientCountry": "United States",
  "clientPaymentVerified": true,
  "clientMemberSince": "2022-08-20",
  "clientTotalSpentAtPosting": 21353.99,
  "clientHiresAtPosting": 36,
  "clientJobsPostedAtPosting": 36,
  "clientRatingAtPosting": 4.73,
  "clientReviewsAtPosting": 28,
  "clientCompanySize": 2,
  "clientIndustry": "Sales & Marketing",
  "clientHireRateAtPosting": null,
  "clientAvgHourlyRatePaidAtPosting": 14.0277
}
```

### Pricing

Two charges, both taken once, at the end of a run that delivered rows. Prices fall with your Apify plan:

| | Free | Starter | Scale | Business |
|---|---|---|---|---|
| per 1,000 postings | $0.20 | $0.17 | $0.14 | $0.10 |
| per run | $0.25 | $0.2125 | $0.175 | $0.125 |

What that comes to on the Free plan, from the archive on 2026-09-26: June 2026's Shopify jobs in Web, Mobile & Software Dev (2,611 postings) are **$0.77**; all 524,254 Web, Mobile & Software Dev postings of 2025 **$105.10**; the whole archive (3,287,228) **$657.70**. About half of each on Business.

A run that delivers nothing, a run that fails and an estimate cost nothing — the run charge included. Your maximum charge per run is honoured before the first row: a run never delivers more postings than it can bill, and its status message says how many more the selection holds.

### Usage patterns

- **Your niche over the last year** — `period` 12m, one or two `categories`, and the `skills` that define the niche. Ready-made: [Shopify jobs of the last 12 months](https://apify.com/hyperbach/upwork-jobs-history/examples/upwork-shopify-jobs-last-12-months).
- **The whole archive** — `period` all and no filters: every posting since November 2024 in one run of about 40 minutes. Price it first with `estimate`. Ready-made: [Price the whole archive](https://apify.com/hyperbach/upwork-jobs-history/examples/price-the-whole-upwork-archive).
- **A category's recent months** — `period` 3m or 6m and a category: the recent market in one area, counted back from today. Ready-made: [Data science jobs of the last 6 months](https://apify.com/hyperbach/upwork-jobs-history/examples/upwork-data-science-jobs-last-6-months).
- **Exact dates** — `from` and `to` (YYYY-MM-DD) replace the period, for the rare question with fixed dates — a launch, a quarter, a before-and-after.
- **A spend limit** — `maxItems` stops a run after that many postings, and the run's maximum charge is honoured as well. The status message says what was delivered and whether the selection holds more.

### Input configuration

| field | type | default | what it does |
|---|---|---|---|
| `period` | `3m` / `6m` / `12m` / `all` | `"12m"` | How far back from today. The newest 30 days are not on sale, so the last 3 months deliver about two months of postings; the status message names the exact days. from/to below replace this. |
| `from` | `string` |  | First day, YYYY-MM-DD (YYYY-MM means that month's first day). Replaces period. Collection began on 2024-11-01. |
| `to` | `string` |  | Last day, included, YYYY-MM-DD (YYYY-MM means that month's last day). Empty: the newest day on sale, 30 days behind today. |
| `categories` | `array` |  | Upwork's top-level categories. Empty: all of them, with the uncategorized postings too. |
| `subcategories` | `array` |  | Upwork's subcategories, e.g. Ecommerce Development or AI & Machine Learning. A posting must be in one of them. Combined with categories, only subcategories inside those categories count. Empty: no subcategory filter. |
| `skills` | `array` |  | A posting matches when any of its skills contains one of these as whole words, ignoring case: shopify matches Shopify and Shopify Theme; machine learning matches Machine Learning Model. Empty: no skill filter. Rows that do not match are not delivered and not charged. |
| `maxItems` | `integer` |  | Stop after this many rows. Empty: every posting in the selection. The run's maximum charge is honoured as well: a run never delivers more rows than it pays for. |
| `estimate` | `boolean` | `false` | Count the postings in the selection and price them for your plan, by month and by category, without delivering any. Free: no run charge, no rows. The answer is in the status message, the log, and the Estimate on the Output tab. |

### FAQ

**Why skills and not keywords?**

Skills are the one filter that defines a niche, and they are Upwork's own labels, so a match is exact rather than a guess. A keyword search over titles and descriptions is the live side's job: [Upwork Job Scraper](https://apify.com/hyperbach/upwork-scraper-ai) searches the last 90 days by keyword with 60 filters. Every row here carries the title and the full description, so any keyword is one line on your side.

**Why 30 days behind today?**

This is the archive, sold as history — so the last 3 months deliver about two months of postings, and the status message names the exact days: the numbers you buy are the ones that will still be the numbers next month. The live side — new postings minutes after they go up — is [Upwork Job Scraper](https://apify.com/hyperbach/upwork-scraper-ai).

**Which categories and subcategories are there?**

Upwork's 12 categories and their 65 subcategories, with the postings each holds in the archive (read 2026-09-26). Pick any of them in `categories` and `subcategories`; 40,939 postings Upwork published without a category are sold as `uncategorized`.

- **Web, Mobile & Software Dev** (777,721): Web Development (292,650), Web & Mobile Design (199,845), Ecommerce Development (85,540), Mobile Development (76,365), Scripts & Utilities (55,797), QA Testing (18,741), AI Apps & Integration (12,974), Other - Software Development (10,981), Game Design & Development (10,024), Desktop Application Development (7,772), Product Management & Scrum (4,944), Blockchain, NFT & Cryptocurrency (2,088)
- **Design & Creative** (832,753): Video & Animation (311,566), Graphic, Editorial & Presentation Design (294,299), Branding & Logo Design (83,061), Art & Illustration (49,789), Performing Arts (39,993), Product Design (23,184), Audio & Music Production (15,489), Photography (13,751), NFT, AR/VR & Game Art (1,621)
- **Sales & Marketing** (611,851): Digital Marketing (382,123), Lead Generation & Telemarketing (169,403), Marketing, PR & Brand Strategy (60,325)
- **Admin Support** (283,750): Virtual Assistance (161,264), Data Entry & Transcription Services (54,868), Market Research & Product Reviews (37,839), Project Management (29,779)
- **Accounting & Consulting** (145,287): Accounting & Bookkeeping (61,316), Recruiting & Human Resources (30,544), Financial Planning (19,081), Management Consulting & Analysis (16,641), Other - Accounting & Consulting (11,676), Personal & Professional Coaching (6,029)
- **Engineering & Architecture** (138,761): 3D Modeling & CAD (42,002), Building & Landscape Architecture (19,683), Civil & Structural Engineering (17,872), Contract Manufacturing (16,525), Electrical & Electronic Engineering (14,991), Interior & Trade Show Design (10,361), Energy & Mechanical Engineering (9,799), Physical Sciences (6,671), Chemical Engineering (857)
- **Writing** (121,746): Content Writing (65,411), Editing & Proofreading Services (27,670), Professional & Business Writing (17,102), Sales & Marketing Copywriting (11,563)
- **Data Science & Analytics** (105,528): Data Analysis & Testing (38,110), AI & Machine Learning (35,065), Data Extraction/ETL (23,300), Data Mining & Management (9,053)
- **IT & Networking** (72,097): Network & System Administration (25,761), DevOps & Solution Architecture (21,380), Information Security & Compliance (14,836), ERP/CRM Software (7,627), Database Management & Administration (2,493)
- **Customer Service** (59,330): Customer Service & Tech Support (54,102), Community Management & Tagging (5,228)
- **Translation** (53,356): Translation & Localization Services (43,707), Language Tutoring & Interpretation (7,926), Legal, Medical & Technical Translation (1,723)
- **Legal** (44,109): Corporate & Contract Law (37,206), Public Law (3,041), International & Immigration Law (2,685), Finance & Tax Law (1,177)

**How complete is each column?**

Every posting has its id, URL, time, title, description and job type. Upwork shows some postings without the client's statistics, so the client columns are not on every row: total spend on 62%, rating on 62%, average hourly rate paid on 40%, and the hire rate only on postings since February 2026 (read 2026-09-26). A missing figure arrives as null, never as a zero. Each field's fill rate is in the output table above.

**What about personal data?**

A row carries no client name, no freelancer and no contact detail: the client appears only through the figures Upwork publishes beside every posting (country, spend, hires, rating). What you may do with the data depends on your purpose and your jurisdiction, and that part is yours.

**How do I get the rows out?**

They land in the run's dataset: JSON, CSV, Excel or XML from the run page, or the same rows over the Apify API. Every row carries Upwork's own job `id`, so repeated runs deduplicate against your table.

### Integration

A year of a large category is several hundred thousand rows, the whole archive over three million. Read them from the run's dataset with the paginated items endpoint or the CSV export, not in one response.

#### JavaScript

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('hyperbach/upwork-jobs-history').call({"period": "12m", "categories": ["web-mobile-software-dev"], "skills": ["shopify"]});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

#### Python

```python
from apify_client import ApifyClient
client = ApifyClient('YOUR_TOKEN')
run = client.actor('hyperbach/upwork-jobs-history').call(run_input={'period': '12m', 'categories': ['web-mobile-software-dev'], 'skills': ['shopify']})
items = client.dataset(run['defaultDatasetId']).list_items().items
```

#### CLI

```bash
apify call hyperbach/upwork-jobs-history --input '{"period": "12m", "categories": ["web-mobile-software-dev"], "skills": ["shopify"]}'
```

#### REST

```bash
curl -X POST "https://api.apify.com/v2/acts/hyperbach~upwork-jobs-history/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H 'Content-Type: application/json' -d '{"period": "12m", "categories": ["web-mobile-software-dev"], "skills": ["shopify"]}'
```

### Support

apify@hyperbach.com

*This page is generated from the Actor's schemas and a live sample — it cannot describe a field the Actor does not have.*

# Actor input Schema

## `period` (type: `string`):

How far back from today. The newest 30 days are not on sale, so the last 3 months deliver about two months of postings; the status message names the exact days. from/to below replace this.

## `from` (type: `string`):

First day, YYYY-MM-DD (YYYY-MM means that month's first day). Replaces period. Collection began on 2024-11-01.

## `to` (type: `string`):

Last day, included, YYYY-MM-DD (YYYY-MM means that month's last day). Empty: the newest day on sale, 30 days behind today.

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

Upwork's top-level categories. Empty: all of them, with the uncategorized postings too.

## `subcategories` (type: `array`):

Upwork's subcategories, e.g. Ecommerce Development or AI & Machine Learning. A posting must be in one of them. Combined with categories, only subcategories inside those categories count. Empty: no subcategory filter.

## `skills` (type: `array`):

A posting matches when any of its skills contains one of these as whole words, ignoring case: shopify matches Shopify and Shopify Theme; machine learning matches Machine Learning Model. Empty: no skill filter. Rows that do not match are not delivered and not charged.

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

Stop after this many rows. Empty: every posting in the selection. The run's maximum charge is honoured as well: a run never delivers more rows than it pays for.

## `estimate` (type: `boolean`):

Count the postings in the selection and price them for your plan, by month and by category, without delivering any. Free: no run charge, no rows. The answer is in the status message, the log, and the Estimate on the Output tab.

## Actor input object example

```json
{
  "period": "3m",
  "categories": [
    "web-mobile-software-dev"
  ],
  "skills": [
    "shopify"
  ],
  "estimate": false
}
```

# Actor output Schema

## `results` (type: `string`):

All scraped records in the default dataset. One record per job posting:

## `estimate` (type: `string`):

The size and the price of the selection for your plan, by month and by category. Written only by a run with estimate: true, which delivers no rows and charges nothing.

# 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 = {
    "period": "3m",
    "categories": [
        "web-mobile-software-dev"
    ],
    "skills": [
        "shopify"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("hyperbach/upwork-jobs-history").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 = {
    "period": "3m",
    "categories": ["web-mobile-software-dev"],
    "skills": ["shopify"],
}

# Run the Actor and wait for it to finish
run = client.actor("hyperbach/upwork-jobs-history").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 '{
  "period": "3m",
  "categories": [
    "web-mobile-software-dev"
  ],
  "skills": [
    "shopify"
  ]
}' |
apify call hyperbach/upwork-jobs-history --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,hyperbach/upwork-jobs-history"
        }
    }
}
```

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/LqOgnqi6JSKORjePB/builds/C6a2JCTHCAzbKgHcZ/openapi.json
