# Upwork MCP - SaaS Ideas (`epicscrapers/upwork-scraper-mcp`) Actor

Find SaaS ideas using upwork. Search for zapier automation, n8n, automate etc to find what business are looking to automate. Feed this to an AI agent to extract business ideas.

- **URL**: https://apify.com/epicscrapers/upwork-scraper-mcp.md
- **Developed by:** [Epic Scrapers](https://apify.com/epicscrapers) (community)
- **Categories:** Lead generation, Jobs, MCP servers
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.80 / 1,000 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 Job Scraper ⭐

**Turn thousands of real Upwork job posts into your next business idea.** Every listing is a client telling you, in their own words, what problem they have and what they're willing to pay to solve it. Pull a few hundred of these into an LLM or AI agent and you get instant market signal: recurring pain points, underserved niches, pricing benchmarks, and validated SaaS or agency ideas — all sourced from real buyer intent, not guesswork.

This actor is built to make that pipeline effortless. It returns just the **title** and **description** of each job — the two fields that actually carry signal — cleaned and ready to drop straight into a prompt. And because it needs **no login, no cookies, and no API key**, it starts pulling data the moment you hit run, so you can go from "I wonder what people are hiring for right now" to a dataset of thousands of jobs in minutes.

### 🚀 Features

- **⚡ Built for speed** — no cookies, no login flow, no session warm-up. Point it at a query and it starts pulling data immediately.
- **🔍 Keyword search** — Search by any keyword or phrase (e.g. "react developer", "python data science", "Shopify expert"). Leave blank to browse all available jobs.
- **📊 Three sort modes** — Most Relevant, Newest First, or Highest Budget.
- **🎛️ Experience level filter** — Entry Level, Intermediate, Expert, or any combination.
- **💰 Budget type filter** — Fixed-price, Hourly, or Weekly Retainer.
- **⏱️ Workload filter** — Part Time, Full Time, As Needed, or Not Specified.
- **👥 Client history filter** — No previous hires, 1–9 hires, or 10+ hires.
- **📅 Job duration filter** — Less than 1 month, 1–3 months, 3–6 months, or 6+ months/Ongoing.
- **🔄 Contract-to-hire** — Only show jobs offering a path to full-time work.
- **🏆 Established clients only** — Skip first-time posters, focus on experienced buyers.
- **📋 Proposal count filter** — Find low-competition jobs (0–4, 5–9, 10–14, 15–19, 20–49 proposals).
- **📄 Just title + description** — The two fields that actually matter, cleaned of markup artifacts and ready to drop straight into a prompt.
- **🔢 Configurable result limits** — 1 to 5,000 jobs per run.
- **🔐 No login required** — No Upwork account, cookies, or API tokens needed. Works out of the box.

### 📥 Input

| Input             | Description                                    |
| ----------------- | ---------------------------------------------- |
| `query`           | Search keywords to find relevant jobs          |
| `sort`            | Most Relevant, Newest First, or Highest Budget |
| `maxResults`      | Max jobs to collect (1–5,000)                  |
| `contractorTier`  | Entry, Intermediate, Expert                    |
| `jobType`         | Fixed-price, Hourly, Weekly Retainer           |
| `workload`        | Part Time, Full Time, As Needed, Not Specified |
| `clientHires`     | 0, 1-9, or 10+ previous hires                  |
| `duration`        | <1mo, 1-3mo, 3-6mo, 6+mo                       |
| `contractToHire`  | Only contract-to-hire jobs                     |
| `proposals`       | Proposal count ranges                          |
| `previousClients` | Only clients with hiring history               |

#### Example Input

```json
{
  "query": "react developer",
  "sort": "relevance+desc",
  "maxResults": 50,
  "contractorTier": ["Intermediate", "Expert"],
  "jobType": ["fixed", "hourly"],
  "workload": ["part_time", "full_time"],
  "clientHires": ["1-9", "10-"],
  "duration": ["month", "ongoing"],
  "proposals": ["0-4", "5-9"],
  "previousClients": true
}
````

### 📋 Output

Every scraped job returns exactly what you need — no extra fields to filter out:

- **`id`** — Unique Upwork job identifier
- **`title`** — Job title, markup removed
- **`description`** — Full job description, cleaned and ready to use

#### Example Output

```json
{
  "id": "2072993847889702808",
  "title": "Build AI Lead Generation + Verification Workflow in Google Sheets/Airtable",
  "description": "We need someone to help build a simple AI-assisted lead generation + verification workflow.\n\nThis is not meant to be a large custom software project. We are looking for a practical, lightweight system that can collect potential leads from public online sources, organize them, check/verify them, score them, and place them into a Google Sheet or Airtable database."
}
```

### 🤖 For AI Agents

This actor is designed to be called programmatically by AI agents via the [Apify MCP Server](https://mcp.apify.com/) or the Apify REST API. The output is deliberately minimal — just `id`, `title`, and `description` — so agents get clean signal with zero cleanup.

#### Via MCP (recommended for agents)

Connect to [`https://mcp.apify.com`](https://mcp.apify.com/) (OAuth or `Authorization: Bearer <APIFY_TOKEN>`). Agents can discover the actor with `search-actors`, run it with any combination of filters, and fetch results with `get-dataset-items`.

**Example agent prompt:**

> Search Apify for `epicscrapers/upwork-scraper` and run it with query `"AI agent"`, max 500 results, newest first. Cluster the job descriptions by recurring problem type and suggest a SaaS product idea for each cluster with 10+ postings.

#### Via REST API

```bash
## Run the actor
curl -X POST "https://api.apify.com/v2/acts/epicscrapers~upwork-scraper/runs" \
  -H "Authorization: Bearer YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "react developer",
    "sort": "relevance+desc",
    "maxResults": 100
  }'

## Get the dataset when the run finishes
curl "https://api.apify.com/v2/datasets/DATASET_ID/items" \
  -H "Authorization: Bearer YOUR_APIFY_TOKEN"
```

#### Output schema for tool-calling agents

| Field | Type | Description |
|-------|------|-------------|
| `id` | `string` | Unique Upwork job identifier. Use for deduplication across runs. |
| `title` | `string` | Job title, markup removed |
| `description` | `string` | Full job description. This is where the signal lives — feed it directly into an LLM. |

All three fields are always present (`required`). No nesting, no optional fields, no extra metadata to filter out.

#### Ready-to-use prompts for LLM workflows

**Find recurring pain points**

> Run `epicscrapers/upwork-scraper` with query `"Shopify"`, max 500, sorted by recency. Cluster descriptions by the underlying business problem. For each cluster with 10+ postings, suggest a SaaS product idea ranked by hiring volume.

**Validate pricing**

> Run `epicscrapers/upwork-scraper` with query `"web scraping"`, max 300, sorted by highest budget. Extract rates and budgets mentioned in descriptions. Give me a realistic pricing range for a SaaS targeting this audience.

**Discover underserved niches**

> Run `epicscrapers/upwork-scraper` with empty query, max 1000. Find clusters where many postings describe the same problem but no clear dominant SaaS solution exists.

**Build a demand heatmap**

> Run `epicscrapers/upwork-scraper` with empty query, max 2000, sorted by recency. Extract and count all skills/services mentioned. Show the top 50 with counts.

#### Gist for agent discovery

A [public GitHub Gist](https://gist.github.com/jwlben11/8392d1d268102cdb8114c13d42cb2f2a) with full input/output specs and agent prompts is available so AI agents and developer tools can discover and integrate with this actor.

### 🔗 Related Actors

| Actor | Description |
|---|---|
| [Indeed Job Scraper](https://apify.com/epicscrapers/indeed-scraper) | Scrape job listings from Indeed.com |
| [Naukri Scraper](https://apify.com/epicscrapers/naukri-scraper) | Extract jobs from India's #1 job portal |
| [Naukrigulf Jobs Scraper](https://apify.com/epicscrapers/naukrigulf-jobs-scraper) | Scrape jobs from the leading GCC job portal |
| [SEEK Job Scraper](https://apify.com/epicscrapers/seek-job-scraper) | Extract job listings from SEEK (Australia & NZ) |
| [WeWorkRemotely Jobs Scraper](https://apify.com/epicscrapers/weworkremotely-jobs-scraper) | Scrape remote jobs from WeWorkRemotely |
| [StepStone Germany Scraper](https://apify.com/epicscrapers/stepstone-de-scraper) | Extract job listings from StepStone Germany |
| [s1jobs.com Jobs Scraper](https://apify.com/epicscrapers/s1jobs-scraper) | Scrape Scottish job listings from s1jobs |

### 💡 Use Cases

#### **Mine Business & SaaS Ideas with an AI Agent**

This is the core use case. Title + description is exactly the input an LLM needs to spot patterns in buyer demand. Feed a batch of 500–1,000 raw job postings into your favorite agent and ask it to cluster them by problem type, surface recurring pain points, or draft SaaS/product ideas based on what clients are repeatedly asking for and paying for. Because there's no extra metadata to strip out, the data goes straight from scrape to prompt with zero cleanup — so you spend your time reviewing ideas, not wrangling data.

#### **Find High-Quality Freelance Gigs with Less Competition**

Filter to **Entry Level** or **Intermediate** jobs with **0–4 proposals** to find gigs with minimal competition, and **10+ previous client hires** to focus on buyers who actually pay and leave feedback. Schedule daily runs for your niche keywords and get a curated list of fresh opportunities every morning.

#### **Monitor Market Demand for Skills and Technologies**

Run this actor weekly with broad queries like "data science" or "machine learning" and track posting volume over time. Segment by **budget type** and **experience level**, dedupe with the `id` field, and build a demand-trend dashboard.

#### **Build a Personalized Job Alert System**

Run this actor on a recurring schedule with your ideal search criteria, add **established clients only** to skip vague first-time posters, and forward results via webhook to Slack, Telegram, email, or a Google Sheet.

#### **Agency Lead Generation and Sales Intelligence**

Companies posting jobs for "Shopify development," "lead generation," or "Zapier automation" are actively looking for services you provide. Scrape daily, mine the description text for client needs and budget signals, and reach out while they're still actively hiring.

#### **Rate Benchmarking and Pricing Strategy**

Search your skill area, sort by **Highest Budget**, and combine **Expert** + **Hourly** filters to see what experienced buyers pay. Build a dataset of 500+ jobs and set your rates on real data, not guesswork.

#### **Academic and Labor Market Research**

Run at regular intervals across industries to build a longitudinal dataset of job titles and descriptions — clean natural-language data ready for text analysis, topic modeling, and skill extraction.

### ❓ Frequently Asked Questions

#### **How do I search for specific jobs on Upwork?**

Enter your keywords in the `query` field — anything you'd normally type into the Upwork search bar. Leave it empty to browse all available jobs.

#### **How many jobs can I scrape in one run?**

Up to **5,000 jobs** per run. Start small (10–25) to test your filters, then scale up. Need more than 5,000? Run the actor multiple times with different queries and combine outputs.

#### **Do I need an Upwork account or login?**

No. This actor only accesses publicly available job data and needs **no account, cookies, or API tokens** — which is a big part of why it's fast. Just enter your search and run.

#### **What countries and regions are covered?**

Same scope as the public Upwork search — jobs from clients in over 180 countries. Target specific markets by including country or region names in your query.

#### **How fresh is the data?**

Real-time. Each run queries Upwork's current listings. Schedule the actor to run daily or hourly for ongoing monitoring.

#### **What formats can I export the data in?**

JSON, JSONL, CSV, Excel, XML, RSS, and HTML — plus programmatic access via the Apify API or integrations like Google Sheets, Google Drive, and Slack.

#### **How is this actor different from the Upwork API?**

The Upwork API needs OAuth 2.0 and is built for authenticated account holders, with rate limits tied to your account. This actor scrapes publicly available listings — no authentication, no account-level rate limits, and just the two fields you actually need, delivered fast.

#### **What are some effective filter combinations?**

- **Low-competition gigs:** `proposals: ["0-4"]` + `clientHires: ["1-9", "10-"]`, sorted by recency
- **High-value projects:** `contractorTier: ["Expert"]` + `previousClients: true`, sorted by highest budget
- **Long-term work:** `duration: ["ongoing"]` + `workload: ["full_time"]` + `contractToHire: true`
- **Quick starter projects:** `workload: ["as_needed"]` + `clientHires: ["0"]`

### Keywords

Upwork scraper, Upwork job scraper, Upwork data extraction, scrape Upwork jobs, Upwork job listings, freelance job scraper, Upwork API alternative, Upwork job search automation, Upwork market research, freelance marketplace data, Upwork job filters, Upwork experience level filter, Upwork budget filter, Upwork client history, Upwork proposals filter, Upwork contract-to-hire, Upwork job monitor, Upwork lead generation, Upwork hiring trends, gig economy data, freelance job data, remote work scraper, Upwork job dataset, apify Upwork actor, Upwork job export CSV, Upwork job export JSON, Upwork competitor analysis, freelance rate benchmarking, Upwork job alert system, scrape Upwork without login, Upwork public job data, Upwork job descriptions, Upwork scraping tool, Upwork automation, AI agent job data, SaaS idea generation from job postings

### ⚠️ Disclaimer

This Actor is an independent tool and is **not affiliated with, endorsed by, or sponsored by Upwork Inc. or any of its subsidiaries**. All trademarks are the property of their respective owners.

This Actor accesses only publicly available job listing data on [upwork.com](https://www.upwork.com). You are solely responsible for ensuring your use complies with the site's Terms of Service and applicable laws.

# Actor input Schema

## `query` (type: `string`):

Enter keywords to find relevant jobs (e.g., "react developer", "python data science"). Leave empty to browse all available jobs.

## `sort` (type: `string`):

Choose how to order the job listings. Most Relevant is usually the best starting point.

## `maxResults` (type: `integer`):

Maximum number of job listings to scrape. Keep this low on first run to test quickly.

## `contractorTier` (type: `array`):

Filter by the client's required experience level. Select one or more, or leave empty for all.

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

Filter by how the job is priced. Select one or more, or leave empty for all types.

## `workload` (type: `array`):

Filter by expected weekly hours. Select one or more, or leave empty for all.

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

Filter by how many freelancers the client has hired on Upwork. Helpful for finding established clients.

## `duration` (type: `array`):

Filter by the estimated length of the job. Select one or more, or leave empty for all.

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

Only include jobs that offer a contract-to-hire option. Disabled by default to show all jobs.

## `previousClients` (type: `boolean`):

Only show jobs where the client has hired on Upwork before. Useful for filtering out first-time clients.

## `proposals` (type: `array`):

Filter by how many proposals have already been submitted. Lower competition jobs often have fewer proposals.

## Actor input object example

```json
{
  "query": "react developer",
  "sort": "relevance+desc",
  "maxResults": 10,
  "contractorTier": [],
  "jobType": [],
  "workload": [],
  "clientHires": [],
  "duration": [],
  "contractToHire": false,
  "previousClients": false,
  "proposals": []
}
```

# Actor output Schema

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

Link to the dataset of scraped records

# 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 = {
    "query": "react developer"
};

// Run the Actor and wait for it to finish
const run = await client.actor("epicscrapers/upwork-scraper-mcp").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 = { "query": "react developer" }

# Run the Actor and wait for it to finish
run = client.actor("epicscrapers/upwork-scraper-mcp").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 '{
  "query": "react developer"
}' |
apify call epicscrapers/upwork-scraper-mcp --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Upwork MCP - SaaS Ideas",
        "description": "Find SaaS ideas using upwork. Search for zapier automation, n8n, automate etc to find what business are looking to automate. Feed this to an AI agent to extract business ideas.",
        "version": "0.1",
        "x-build-id": "JPHeUZQDuxgymIYs3"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/epicscrapers~upwork-scraper-mcp/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-epicscrapers-upwork-scraper-mcp",
                "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/epicscrapers~upwork-scraper-mcp/runs": {
            "post": {
                "operationId": "runs-sync-epicscrapers-upwork-scraper-mcp",
                "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/epicscrapers~upwork-scraper-mcp/run-sync": {
            "post": {
                "operationId": "run-sync-epicscrapers-upwork-scraper-mcp",
                "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": {
                    "query": {
                        "title": "🔍 Search Query",
                        "type": "string",
                        "description": "Enter keywords to find relevant jobs (e.g., \"react developer\", \"python data science\"). Leave empty to browse all available jobs."
                    },
                    "sort": {
                        "title": "Sort By",
                        "enum": [
                            "relevance+desc",
                            "recency+desc",
                            "budget+desc"
                        ],
                        "type": "string",
                        "description": "Choose how to order the job listings. Most Relevant is usually the best starting point.",
                        "default": "relevance+desc"
                    },
                    "maxResults": {
                        "title": "Max Jobs",
                        "minimum": 1,
                        "maximum": 5000,
                        "type": "integer",
                        "description": "Maximum number of job listings to scrape. Keep this low on first run to test quickly.",
                        "default": 10
                    },
                    "contractorTier": {
                        "title": "Experience Level",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Filter by the client's required experience level. Select one or more, or leave empty for all.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "EntryLevel",
                                "Intermediate",
                                "Expert"
                            ],
                            "enumTitles": [
                                "Entry Level",
                                "Intermediate",
                                "Expert"
                            ]
                        },
                        "default": []
                    },
                    "jobType": {
                        "title": "Budget Type",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Filter by how the job is priced. Select one or more, or leave empty for all types.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "fixed",
                                "hourly",
                                "weekly_retainer"
                            ],
                            "enumTitles": [
                                "Fixed-price",
                                "Hourly",
                                "Weekly Retainer"
                            ]
                        },
                        "default": []
                    },
                    "workload": {
                        "title": "Workload",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Filter by expected weekly hours. Select one or more, or leave empty for all.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "part_time",
                                "full_time",
                                "as_needed",
                                "none"
                            ],
                            "enumTitles": [
                                "Part Time",
                                "Full Time",
                                "As Needed",
                                "Not Specified"
                            ]
                        },
                        "default": []
                    },
                    "clientHires": {
                        "title": "Client History",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Filter by how many freelancers the client has hired on Upwork. Helpful for finding established clients.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "0",
                                "1-9",
                                "10-"
                            ],
                            "enumTitles": [
                                "No previous hires",
                                "1-9 hires",
                                "10+ hires"
                            ]
                        },
                        "default": []
                    },
                    "duration": {
                        "title": "Job Duration",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Filter by the estimated length of the job. Select one or more, or leave empty for all.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "week",
                                "month",
                                "semester",
                                "ongoing"
                            ],
                            "enumTitles": [
                                "Less than 1 month",
                                "1-3 months",
                                "3-6 months",
                                "6+ months / Ongoing"
                            ]
                        },
                        "default": []
                    },
                    "contractToHire": {
                        "title": "Contract-to-Hire",
                        "type": "boolean",
                        "description": "Only include jobs that offer a contract-to-hire option. Disabled by default to show all jobs.",
                        "default": false
                    },
                    "previousClients": {
                        "title": "Established Clients Only",
                        "type": "boolean",
                        "description": "Only show jobs where the client has hired on Upwork before. Useful for filtering out first-time clients.",
                        "default": false
                    },
                    "proposals": {
                        "title": "Proposal Count",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Filter by how many proposals have already been submitted. Lower competition jobs often have fewer proposals.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "*",
                                "0-4",
                                "5-9",
                                "10-14",
                                "15-19",
                                "20-49"
                            ],
                            "enumTitles": [
                                "Any",
                                "0-4 proposals",
                                "5-9 proposals",
                                "10-14 proposals",
                                "15-19 proposals",
                                "20-49 proposals"
                            ]
                        },
                        "default": []
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
