# Upwork Jobs \[$0.59] — 130K+ Instant Database, Budgets & Filters (`memo23/upwork-jobs-scraper-ppe`) Actor

\[From $0.59/1k] The only Upwork jobs scraper with its own 130,000+ job database — instant, uncapped, nothing to get blocked, refreshed every 6 hours. Search by keyword + filters (budget, experience, type, client location, date) or live-scrape any URL. Great for lead-gen, recruiting & idea research.

- **URL**: https://apify.com/memo23/upwork-jobs-scraper-ppe.md
- **Developed by:** [Muhamed Didovic](https://apify.com/memo23) (community)
- **Categories:** Jobs, Agents, AI
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.59 / 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 a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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

## Upwork Jobs Scraper — 130K+ Instant Database, Fresh Every 6h

<p align="center"><img src="https://raw.githubusercontent.com/muhamed-didovic/muhamed-didovic.github.io/main/assets/upwork-jobs.png" alt="Upwork Jobs Scraper" width="640"></p>

The only Upwork job scraper backed by its **own 130,000+ job database** — search by keyword and filters and get results **instantly**, uncapped, with nothing to get blocked. The database is refreshed every 6 hours, so you get today's jobs without ever hammering Upwork yourself. Need a filter we don't cover yet? It automatically falls back to a fresh live scrape, so you always get data.

| You give it | You get back |
|---|---|
| A keyword (e.g. `python scraper`) + optional filters | Every matching job from the 130k+ database, newest first |
| A public Upwork search URL | The same jobs that URL would show, fully structured |
| `minFixedBudget`, `experienceLevel`, `jobType`, `clientLocation`, `maxAgeDays`, `publishedAfter` | Precisely filtered results — budgets, client country, skills, activity all included |

> Pure HTTP + a pre-harvested database. No browser, no third-party CAPTCHA-bypass service, no per-search 250-job cap.

### Why use this instead of a live-only scraper

- **Instant & uncapped.** Live Upwork scrapers re-fetch every run, get rate-limited, and stop around Upwork's ~50–250 results per search. This one serves from a cumulative database — ask for 5,000 python jobs and get 5,000.
- **Always fresh.** A background worker refreshes the mirror every 6 hours and ages out jobs older than 45 days, so results are current without you paying for a live crawl each time.
- **Budgets & client data included.** ~40% of jobs carry an explicit fixed budget and ~100% carry client country — the fields that make Upwork data actually useful for demand analysis.
- **Nothing to get blocked.** Because the common case is served from the database, there's no live request to detect or ban.
- **Two ways in, one clean schema.** Paste a search URL or use structured filters — either returns the identical, fully-nested job object.

### Overview

Upwork is the largest open marketplace of paid freelance work — every job post is a business holding out a budget to solve a problem. That makes it the richest public signal of **what services are in demand and what people will pay for them**. This actor turns that stream into structured data you can filter, export, and analyze:

- **Recruiters & agencies** — find live projects in your niche and the clients posting them.
- **Lead generation** — surface businesses actively hiring for a service you sell.
- **Freelancers** — monitor new gigs matching your skills, filtered by budget and client quality.
- **Market & startup-idea research** — cluster recurring paid tasks to find automation opportunities and validate demand with real budgets, not guesses.

### Supported inputs

| Input | Example | Emits |
|---|---|---|
| Search keywords + filters | `searchQuery: "web scraping"`, `minFixedBudget: 200` | All matching jobs from the database |
| Upwork search URL | `https://www.upwork.com/nx/search/jobs/?q=python&sort=recency` | The jobs that URL resolves to |
| Individual job URL | `https://www.upwork.com/jobs/~021936702637394960044` | That single job, fully structured |

### How it works

<p align="center"><img src="https://raw.githubusercontent.com/muhamed-didovic/muhamed-didovic.github.io/main/assets/how-it-works-upwork.png" alt="How the Upwork Jobs Scraper works" width="820"></p>

1. **You submit** a keyword + filters (or a URL).
2. **The Instant Database** is queried first — a cumulative Turso store of 130k+ Upwork jobs, indexed for full-text keyword search and filtered by budget, experience, job type, client location and publish date. Results come back in seconds, newest first.
3. **Automatic live fallback** — if a filter combination isn't yet covered in the database, the actor transparently runs a fresh scrape so you still get data.
4. **A background worker** refreshes the database every 6 hours and ages out stale jobs, keeping results current.
5. **You export** to JSON, CSV or Excel, or pull via the Apify API.

### Input configuration

| Field | Type | Required | Notes |
|---|---|---|---|
| `startUrls` | array | one of URL / keywords | Public Upwork search or job URLs. Filters in the URL are honored. |
| `searchQuery` | string | one of URL / keywords | Keywords matched against job title + description. |
| `jobType` | array | no | `hourly`, `fixed`. |
| `experienceLevel` | array | no | `entry`, `intermediate`, `expert`. |
| `minFixedBudget` | number | no | Only fixed-price jobs with budget ≥ this (USD). |
| `clientLocation` | array | no | Client country name(s), substring match. |
| `maxAgeDays` | number | no | Only jobs published in the last N days. |
| `publishedAfter` | string | no | Only jobs published at/after this ISO date (e.g. `2026-07-01`). |
| `monitorMode` | boolean | no | 🔔 Return only jobs new since the previous run for this exact search. Put the Actor on a Schedule for a clean, duplicate-free feed of new gigs. |
| `maxItems` | number | no | Cap on jobs returned per search. |
| `proxy` | object | no | Optional proxy override (only used on live fallback). |

#### Example input

```json
{
  "searchQuery": "web scraping",
  "jobType": ["fixed"],
  "experienceLevel": ["intermediate", "expert"],
  "minFixedBudget": 200,
  "maxAgeDays": 7,
  "maxItems": 500
}
````

### Output

Each row is one job, returned in Upwork's own nested shape so nothing is lost. Abridged sample:

```jsonc
{
  "opening": {
    "job": {
      "status": "ACTIVE",
      "publishTime": "2026-07-08T08:27:46.991Z",
      "contractorTier": "INTERMEDIATE",
      "info": {
        "ciphertext": "~021936702637394960044",
        "type": "FIXED",
        "title": "Social Media Manager for Airbnb & Hotels"
      },
      "category": { "name": "Digital Marketing", "urlSlug": "digital-marketing" },
      "categoryGroup": { "name": "Sales & Marketing" },
      "budget": { "amount": 300, "currencyCode": "USD" },
      "engagementDuration": { "label": "1 to 3 months", "weeks": 9 },
      "sandsData": {
        "occupation": { "prefLabel": "Social Media Marketing" },
        "additionalSkills": [{ "prefLabel": "Instagram" }, { "prefLabel": "Facebook" }]
      },
      "clientActivity": { "totalApplicants": 20, "totalHired": 0 }
    }
  },
  "buyer": {
    "isPaymentMethodVerified": false,
    "info": {
      "location": { "country": "Seychelles", "city": null },
      "stats": { "totalAssignments": 0, "feedbackCount": 0, "score": 0 },
      "company": { "profile": { "industry": "Travel & Hospitality", "size": 1 } }
    }
  }
}
```

#### Key output fields

| Field | Meaning |
|---|---|
| `opening.job.info.title` / `.type` | Job title and payment type (FIXED / HOURLY) |
| `opening.job.budget.amount` | Fixed-price budget in USD |
| `opening.job.contractorTier` | Required experience level |
| `opening.job.category` / `categoryGroup` | Upwork category taxonomy |
| `opening.job.sandsData.*Skills` | Occupation + skill tags |
| `opening.job.publishTime` | When the job was posted (sort/monitor on this) |
| `opening.job.clientActivity.totalApplicants` / `totalHired` | Competition + hiring signal |
| `buyer.info.location.country` | Client country |
| `buyer.info.stats.*` | Client history — assignments, spend, feedback score |
| `buyer.isPaymentMethodVerified` | Whether the client's payment method is verified |

### Pricing

Pay-per-event. You're charged per job returned plus a small run-start fee — the same whether a result is served instantly from the database or live-scraped.

| Event | When | Notes |
|---|---|---|
| Actor start | Per run | Standard platform start fee |
| Job result | Per job returned | The bulk of the cost |

### 🔔 Monitoring mode — a live feed of new gigs

Turn on **`monitorMode`** and put the Actor on a **Schedule** (Apify Console → Schedules, e.g. hourly or daily). Each run then returns **only jobs posted since the previous run** for that exact keyword + filter combination — a clean, duplicate-free feed you can wire to a webhook, Slack, or email integration.

- The **first** run seeds the cursor and returns the current matches.
- **Every run after** returns only what's new (often zero — that's a valid "nothing new yet" result, not an error).
- Each distinct search (different keywords/filters) is tracked **separately**, so you can run several monitors in parallel.

Typical setup: `searchQuery: "shopify developer"`, `minFixedBudget: 200`, `monitorMode: true`, scheduled hourly → you get pinged only when a new matching gig appears.

### Common use cases

- **"Show me every fixed-budget web-scraping job over $200 posted this week."** — recurring manual tasks people pay for = automation opportunities.
- **"Alert me the moment a new Shopify-developer gig is posted."** — `monitorMode: true` on an hourly schedule (see above).
- **"Which clients in the US are hiring for lead generation right now?"** — filter by keyword + `clientLocation` for a warm B2B lead list.
- **"What are people paying freelancers to do that I could turn into a product?"** — export a category and cluster the recurring pain points with budgets attached.

### FAQ

**How fresh is the database?** Refreshed every 6 hours; jobs older than 45 days are aged out.

**What if my exact filter isn't in the database?** The actor automatically falls back to a live scrape for that query, so you still get results.

**Is there a per-search cap like on Upwork itself?** No. Upwork limits a search to a few hundred results; the database serves as many matches as exist, up to your `maxItems`.

**Do I get client budgets?** Yes where Upwork exposes them — roughly 40% of jobs carry an explicit fixed budget, and nearly all carry client country and activity stats.

**Can I scrape a single job page?** Yes — pass the job URL in `startUrls`.

### Support

Questions, custom fields, or bulk/enterprise needs: **muhameddidovic@gmail.com**. More tools: Upwork Reviews Scraper · Fiverr Scraper · Indeed Scraper.

### ⚠️ Disclaimer

This actor collects only **publicly available** job-posting data from Upwork and performs no login, paywall circumvention, or access to private/personal account data. You are responsible for using the output in compliance with Upwork's Terms of Service, applicable laws, and data-protection regulations (including GDPR/CCPA where relevant). This tool is provided for legitimate research, recruiting, and market-analysis purposes. It is not affiliated with, endorsed by, or sponsored by Upwork Global Inc. "Upwork" is a trademark of its respective owner.

### SEO Keywords

Upwork scraper, Upwork jobs scraper, Upwork job data, Upwork API alternative, scrape Upwork jobs, Upwork freelance jobs, freelance job data, Upwork market research, freelance demand data, Upwork lead generation, Upwork recruiting tool, gig economy data, freelance market analysis, Upwork jobs database, Upwork job monitoring, startup idea validation, SaaS idea research, pain point research, automation opportunity finder, Upwork budget data, freelance job feed, Upwork jobs by keyword, Upwork jobs by budget.

# Actor input Schema

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

Public Upwork search URLs to scrape (e.g. https://www.upwork.com/nx/search/jobs/?q=python+developer\&sort=recency). Any filters already in the URL are honored. Leave empty to use the structured filters below instead.

## `searchQuery` (type: `string`):

What to search for in job titles and descriptions. Served instantly from our 130k+ job database; falls back to live scraping only for filters not yet covered.

## `jobType` (type: `array`):

Restrict to hourly and/or fixed-price jobs.

## `experienceLevel` (type: `array`):

Restrict to one or more required experience levels.

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

Order results by best match or newest first.

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

Restrict to one or more Upwork job categories.

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

One or more Upwork subcategory UIDs (advanced). Tick a subcategory on Upwork's search page and copy the numeric `subcategory2_uid` value from the resulting URL, e.g. 531770282589356032.

## `hoursPerWeek` (type: `array`):

Restrict to part-time or full-time engagements.

## `projectLength` (type: `array`):

Restrict to one or more expected project lengths.

## `contractToHire` (type: `boolean`):

Show only roles that can convert into a full-time position.

## `maxAgeDays` (type: `integer`):

Only return jobs published within the last N days (e.g. 1 = today, 7 = this week). Results are always newest-first. Applies to the Instant Database.

## `publishedAfter` (type: `string`):

Only return jobs published on/after this date (YYYY-MM-DD). Handy for pulling everything new since your last run. Applies to the Instant Database.

## `monitorMode` (type: `boolean`):

Turn this on and put the Actor on a Schedule (e.g. hourly): each run returns only jobs posted since the previous run for this exact search, so you get a clean feed of new gigs with no duplicates. The first run seeds the cursor (returns current matches), every run after that returns only what's new. Each distinct keyword/filter combination is tracked separately.

## `minFixedBudget` (type: `integer`):

Only fixed-price jobs with a budget at or above this amount.

## `clientHires` (type: `array`):

Restrict by how many freelancers the client has previously hired.

## `clientLocation` (type: `array`):

One or more client locations. Accepts country names (e.g. "United States", "India") or Upwork region groups (e.g. "Americas", "Europe").

## `clientTimezone` (type: `array`):

One or more client time zones as IANA zone names (e.g. "America/New\_York", "Europe/London").

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

Maximum number of jobs to scrape per search.

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

Maximum number of pages that can be processed at the same time.

## `minConcurrency` (type: `integer`):

Minimum number of pages that will be processed at the same time.

## `maxRequestRetries` (type: `integer`):

Number of times the crawler will retry a failed request before giving up.

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

Leave empty — the actor already routes all traffic through its own built-in residential proxy at no extra cost to you. Only set this if you want to use your own proxies.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.upwork.com/nx/search/jobs/?q=python+developer&sort=recency"
    }
  ],
  "searchQuery": "Software Developer",
  "sortBy": "relevance",
  "contractToHire": false,
  "maxAgeDays": 7,
  "publishedAfter": "2026-07-01",
  "monitorMode": false,
  "maxItems": 100,
  "maxConcurrency": 10,
  "minConcurrency": 1,
  "maxRequestRetries": 100
}
```

# 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 = {
    "startUrls": [
        {
            "url": "https://www.upwork.com/nx/search/jobs/?q=python+developer&sort=recency"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("memo23/upwork-jobs-scraper-ppe").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 = { "startUrls": [{ "url": "https://www.upwork.com/nx/search/jobs/?q=python+developer&sort=recency" }] }

# Run the Actor and wait for it to finish
run = client.actor("memo23/upwork-jobs-scraper-ppe").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 '{
  "startUrls": [
    {
      "url": "https://www.upwork.com/nx/search/jobs/?q=python+developer&sort=recency"
    }
  ]
}' |
apify call memo23/upwork-jobs-scraper-ppe --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Upwork Jobs [$0.59] — 130K+ Instant Database, Budgets & Filters",
        "description": "[From $0.59/1k] The only Upwork jobs scraper with its own 130,000+ job database — instant, uncapped, nothing to get blocked, refreshed every 6 hours. Search by keyword + filters (budget, experience, type, client location, date) or live-scrape any URL. Great for lead-gen, recruiting & idea research.",
        "version": "0.0",
        "x-build-id": "SH9cnNKezOXOJh6pn"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/memo23~upwork-jobs-scraper-ppe/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-memo23-upwork-jobs-scraper-ppe",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/memo23~upwork-jobs-scraper-ppe/runs": {
            "post": {
                "operationId": "runs-sync-memo23-upwork-jobs-scraper-ppe",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/memo23~upwork-jobs-scraper-ppe/run-sync": {
            "post": {
                "operationId": "run-sync-memo23-upwork-jobs-scraper-ppe",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "startUrls": {
                        "title": "Start URLs",
                        "type": "array",
                        "description": "Public Upwork search URLs to scrape (e.g. https://www.upwork.com/nx/search/jobs/?q=python+developer&sort=recency). Any filters already in the URL are honored. Leave empty to use the structured filters below instead.",
                        "items": {
                            "type": "object",
                            "required": [
                                "url"
                            ],
                            "properties": {
                                "url": {
                                    "type": "string",
                                    "title": "URL of a web page",
                                    "format": "uri"
                                }
                            }
                        }
                    },
                    "searchQuery": {
                        "title": "Search keywords",
                        "type": "string",
                        "description": "What to search for in job titles and descriptions. Served instantly from our 130k+ job database; falls back to live scraping only for filters not yet covered."
                    },
                    "jobType": {
                        "title": "Payment type",
                        "type": "array",
                        "description": "Restrict to hourly and/or fixed-price jobs.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "hourly",
                                "fixed"
                            ],
                            "enumTitles": [
                                "Hourly",
                                "Fixed-Price"
                            ]
                        }
                    },
                    "experienceLevel": {
                        "title": "Experience level",
                        "type": "array",
                        "description": "Restrict to one or more required experience levels.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "entry",
                                "intermediate",
                                "expert"
                            ],
                            "enumTitles": [
                                "Entry Level",
                                "Intermediate",
                                "Expert"
                            ]
                        }
                    },
                    "sortBy": {
                        "title": "Sort results",
                        "enum": [
                            "relevance",
                            "recent"
                        ],
                        "type": "string",
                        "description": "Order results by best match or newest first.",
                        "default": "relevance"
                    },
                    "categories": {
                        "title": "Job categories",
                        "type": "array",
                        "description": "Restrict to one or more Upwork job categories.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "531770282584862721",
                                "531770282580668416",
                                "531770282580668417",
                                "531770282580668420",
                                "531770282580668421",
                                "531770282584862722",
                                "531770282580668419",
                                "531770282584862723",
                                "531770282580668422",
                                "531770282584862720",
                                "531770282580668418",
                                "531770282580668423"
                            ],
                            "enumTitles": [
                                "Accounting & Consulting",
                                "Admin Support",
                                "Customer Service",
                                "Data Science & Analytics",
                                "Design & Creative",
                                "Engineering & Architecture",
                                "IT & Networking",
                                "Legal",
                                "Sales & Marketing",
                                "Translation",
                                "Web, Mobile & Software Dev",
                                "Writing"
                            ]
                        }
                    },
                    "subcategories": {
                        "title": "Job subcategories",
                        "type": "array",
                        "description": "One or more Upwork subcategory UIDs (advanced). Tick a subcategory on Upwork's search page and copy the numeric `subcategory2_uid` value from the resulting URL, e.g. 531770282589356032.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "hoursPerWeek": {
                        "title": "Weekly commitment",
                        "type": "array",
                        "description": "Restrict to part-time or full-time engagements.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "part_time",
                                "full_time"
                            ],
                            "enumTitles": [
                                "Part-time (less than 30 hrs/week)",
                                "Full-time (30+ hrs/week)"
                            ]
                        }
                    },
                    "projectLength": {
                        "title": "Project duration",
                        "type": "array",
                        "description": "Restrict to one or more expected project lengths.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "under_1_month",
                                "1_to_3_months",
                                "3_to_6_months",
                                "over_6_months"
                            ],
                            "enumTitles": [
                                "Less than 1 month",
                                "1 to 3 months",
                                "3 to 6 months",
                                "More than 6 months"
                            ]
                        }
                    },
                    "contractToHire": {
                        "title": "Contract-to-hire only",
                        "type": "boolean",
                        "description": "Show only roles that can convert into a full-time position.",
                        "default": false
                    },
                    "maxAgeDays": {
                        "title": "Published in last N days",
                        "type": "integer",
                        "description": "Only return jobs published within the last N days (e.g. 1 = today, 7 = this week). Results are always newest-first. Applies to the Instant Database."
                    },
                    "publishedAfter": {
                        "title": "Published after date",
                        "type": "string",
                        "description": "Only return jobs published on/after this date (YYYY-MM-DD). Handy for pulling everything new since your last run. Applies to the Instant Database."
                    },
                    "monitorMode": {
                        "title": "🔔 Monitoring — only NEW jobs since last run",
                        "type": "boolean",
                        "description": "Turn this on and put the Actor on a Schedule (e.g. hourly): each run returns only jobs posted since the previous run for this exact search, so you get a clean feed of new gigs with no duplicates. The first run seeds the cursor (returns current matches), every run after that returns only what's new. Each distinct keyword/filter combination is tracked separately.",
                        "default": false
                    },
                    "minFixedBudget": {
                        "title": "Min fixed-price budget (USD)",
                        "type": "integer",
                        "description": "Only fixed-price jobs with a budget at or above this amount."
                    },
                    "clientHires": {
                        "title": "Client hiring history",
                        "type": "array",
                        "description": "Restrict by how many freelancers the client has previously hired.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "none",
                                "1_to_9",
                                "10_plus"
                            ],
                            "enumTitles": [
                                "No hires yet",
                                "1 to 9 hires",
                                "10+ hires"
                            ]
                        }
                    },
                    "clientLocation": {
                        "title": "Client location",
                        "type": "array",
                        "description": "One or more client locations. Accepts country names (e.g. \"United States\", \"India\") or Upwork region groups (e.g. \"Americas\", \"Europe\").",
                        "items": {
                            "type": "string"
                        }
                    },
                    "clientTimezone": {
                        "title": "Client time zone",
                        "type": "array",
                        "description": "One or more client time zones as IANA zone names (e.g. \"America/New_York\", \"Europe/London\").",
                        "items": {
                            "type": "string"
                        }
                    },
                    "maxItems": {
                        "title": "Max jobs per search",
                        "type": "integer",
                        "description": "Maximum number of jobs to scrape per search.",
                        "default": 100
                    },
                    "maxConcurrency": {
                        "title": "Max Concurrency",
                        "type": "integer",
                        "description": "Maximum number of pages that can be processed at the same time.",
                        "default": 10
                    },
                    "minConcurrency": {
                        "title": "Min Concurrency",
                        "type": "integer",
                        "description": "Minimum number of pages that will be processed at the same time.",
                        "default": 1
                    },
                    "maxRequestRetries": {
                        "title": "Max Request Retries",
                        "type": "integer",
                        "description": "Number of times the crawler will retry a failed request before giving up.",
                        "default": 100
                    },
                    "proxy": {
                        "title": "Proxy configuration (optional override)",
                        "type": "object",
                        "description": "Leave empty — the actor already routes all traffic through its own built-in residential proxy at no extra cost to you. Only set this if you want to use your own proxies."
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
