# Upwork Job Scraper - Fresh Jobs & Client Signals (`chronometrica/upwork-job-scraper`) Actor

Find fresh Upwork jobs by keyword, filter worthwhile gigs by budget, hourly or fixed type, experience level, proposal count, and title terms, then export clean rows for alerts, lead routing, market research, and workflows. No Upwork login or cookies required.

- **URL**: https://apify.com/chronometrica/upwork-job-scraper.md
- **Developed by:** [Chronometrica](https://apify.com/chronometrica) (community)
- **Categories:** Jobs, Lead generation, Automation
- **Stats:** 4 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 saved upwork jobs

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

### 🚀 What does Upwork Job Scraper do?

Upwork Job Scraper finds fresh Upwork jobs by keyword and turns them into clean,
flat rows you can export, schedule, route, or plug into an automation workflow.
It captures stable Upwork IDs, job URLs, titles, descriptions, skills, budgets,
hourly ranges, proposal counts, posting times, public activity signals, and
search context.

Use it when you need to find new gigs quickly, monitor a niche, route matching
jobs to a freelancer or agency team, build job alerts, research buyer demand, or
feed a spreadsheet, dashboard, CRM, or workflow tool.

To get started, enter one or more keywords, choose how fresh the jobs should be,
set how many listings to save, add filters for worthwhile gigs, and click
**Start**.

```json
{
    "searchTerm": "web scraping\nlead generation\ndata entry\nAI automation\nShopify\nPython",
    "postedWithin": "7d",
    "sortBy": "recency",
    "maxItems": 25,
    "jobType": "any",
    "experienceLevel": "any",
    "maxProposalCount": 0,
    "saveOnlyUniqueItems": true,
    "maxPagesPerSearch": 2
}
````

With Upwork Job Scraper, you can:

- 🔎 Search Upwork jobs by keyword, title, skill, or buyer-intent phrase.
- ⚡ Find fresh jobs quickly with last 24h, 3d, 7d, 14d, and 30d windows.
- ♻️ Save one row per unique job by default, even when keywords and pages overlap.
- 🎛️ Filter by posting date, hourly or fixed-price work, experience level, proposal
  count, budget, hourly range, and title terms.
- 📦 Collect public job details such as title, description, skills, budget, hourly
  range, publish time, and Upwork job URL.
- 📊 Add public activity fields such as client activity time, interviewing count,
  invites sent, unanswered invites, hires, offers, and recommendations when
  Upwork exposes them.
- ⬇️ Export results as JSON, JSONL, CSV, Excel, XML, RSS, or HTML.
- 🧭 Check the run summary to see candidates, saved rows, duplicates, filters,
  blocked requests, warnings, and suggested next-run timing.

No Upwork account login, user-provided cookies, or user-provided Upwork
credentials are required.

### 📦 What Upwork job data can I extract?

Each dataset row represents one saved Upwork job opportunity.

| Data group        | Example fields                                                                                   |
| ----------------- | ------------------------------------------------------------------------------------------------ |
| 🆔 Identity       | `source_job_id`, `url`                                                                           |
| 💼 Job details    | `title`, `description`, `skills`, `engagement_type`, `experience_level`                          |
| 💰 Budget         | `budget_amount`, `budget_currency`, `hourly_min_amount`, `hourly_max_amount`, `hourly_currency`  |
| 📊 Activity       | `proposal_count`, `client_last_activity_at`, `interviewing_count`, `invites_sent`, `hires_count` |
| 🔍 Search context | `source_query`                                                                                   |
| ⏱️ Time           | `published_at`, `source_created_at`, `observed_at`                                               |

Field availability depends on what Upwork exposes publicly for each search
result or job. Missing values are saved as `null` instead of guessed or filled
with fake zeroes.

### ⚙️ Can I use this Actor through an API?

Yes. You can run Upwork Job Scraper manually in Apify Console or use it as an
API for Upwork job discovery.

Developers can call this Actor through:

- 🔌 Apify API
- 🐍 Python SDK
- 🟩 Node.js SDK
- 🪝 Webhooks
- ⏰ Scheduled runs
- 🧩 Apify integrations

This makes it useful for freelance job alerts, agency opportunity monitoring,
lead routing, internal work queues, labor-market dashboards, and automated
research workflows.

### 🎯 Why scrape Upwork jobs?

Upwork job postings are a useful source of fresh freelance opportunities and
active buyer demand. Scraping Upwork jobs can help you find gigs quickly,
monitor client demand, route worthwhile jobs to specialized teams, and study the
language buyers use when asking for work.

| Use case                       | How Upwork job data helps                                                                  |
| ------------------------------ | ------------------------------------------------------------------------------------------ |
| ⚡ Find new gigs quickly       | Track fresh jobs by keyword and sort newest-first.                                         |
| 🔔 Monitor a niche             | Schedule repeat runs for terms such as data extraction, AI automation, Shopify, or Python. |
| 💎 Filter worthwhile gigs      | Keep jobs by budget, hourly range, experience level, proposal count, and title relevance.  |
| 🧲 Route qualified leads       | Send matching jobs to the right freelancer, sales rep, or delivery pod.                    |
| 📊 Build alerts and dashboards | Compare jobs by stable Upwork IDs and export clean rows.                                   |
| 🧪 Research market language    | Analyze titles and descriptions to understand how buyers describe tasks.                   |

### 🔎 Fresh Upwork job discovery by keyword

Most users should start with `searchTerm`. Enter one keyword, skill, title, or
buyer-intent phrase per line:

```text
web scraping
lead generation
data extraction
AI automation
Shopify
Python
```

The Actor searches each term, saves matching jobs, removes duplicates when
`saveOnlyUniqueItems` is enabled, and applies one shared `maxItems` cap across
the whole run.

Keep `sortBy` set to `recency` and choose a `postedWithin` window when you care
about fresh jobs you can apply to or route quickly.

### ♻️ Clean, duplicate-free Upwork job datasets

Upwork search results can overlap across related keywords and pages. For normal
datasets, keep `saveOnlyUniqueItems` enabled so the Actor saves each Upwork job
once and skips duplicate candidates before they become saved rows.

The `OUTPUT` summary shows `candidateItemsSeen`, `duplicateCandidatesSeen`,
`duplicatesSkipped`, and `jobsSaved`, so you can see how many matching rows were
found, how many were duplicates, and how many unique job listings were saved.

Turn unique-job mode off only when you intentionally want to measure keyword
overlap or search ranking behavior.

### 💵 How much does scraping Upwork jobs cost?

Upwork Job Scraper is designed for Pay-Per-Event pricing, where you are charged
for saved job listings. The planned launch price is **$2.50 per 1,000 saved job
listings**, or **$0.0025 per saved job listing**.

| Saved job listings | Estimated Actor charge |
| ------------------ | ---------------------- |
| 100 jobs           | $0.25                  |
| 1,000 jobs         | $2.50                  |
| 10,000 jobs        | $25.00                 |

Check the **Pricing** tab for the current rate before production runs. Start
with `maxItems` between 10 and 100 if you want to inspect output quality before
larger searches.

### 🚀 How do I use Upwork Job Scraper?

Upwork Job Scraper is designed for an easy first run:

1. Create or log in to your Apify account.
2. Open **Upwork Job Scraper**.
3. Enter one or more Upwork job keywords, such as `web scraping` or
   `lead generation`.
4. Choose a freshness window such as last 24 hours, last 3 days, or last 7 days.
5. Set the maximum number of job listings to collect.
6. Add filters such as job type, experience level, proposal count, title terms,
   hourly range, or fixed budget if needed.
7. Click **Start**.
8. Open the **Output** tab to inspect the dataset and run summary.
9. Download your data in JSON, JSONL, CSV, Excel, XML, RSS, or HTML.

### ⬇️ Input

The input form follows the way users actually run Upwork job scrapers:

1. Enter keywords.
2. Keep jobs fresh.
3. Filter for worthwhile gigs.
4. Export clean unique rows.

Enter at least one keyword in `searchTerm`. The Actor searches each keyword,
deduplicates overlapping jobs when `saveOnlyUniqueItems` is enabled, and applies
one shared `maxItems` cap.

#### 🔑 Keywords

Use one keyword, skill, title, or phrase per line. Multiple terms help you cover
a niche without creating separate runs.

Good keyword examples:

```text
web scraping
lead generation
data entry
AI automation
Shopify
Python
```

If broad keywords return off-target rows, use title filters:

```json
{
    "searchTerm": "automation",
    "titleMustInclude": "automation\nworkflow\nzapier",
    "titleExclude": "crypto\nforex",
    "maxItems": 100
}
```

#### 🎛️ Freshness, filters, and run controls

| Option                   | What it does                                                                  |
| ------------------------ | ----------------------------------------------------------------------------- |
| 📅 `postedWithin`        | Keeps jobs from the selected freshness window when publish time is available. |
| 🔀 `sortBy`              | Sorts keyword searches by newest first or relevance.                          |
| 🔢 `maxItems`            | Sets the total number of jobs to save across the run.                         |
| 💼 `jobType`             | Keeps hourly, fixed-price, or any jobs.                                       |
| 🪜 `experienceLevel`     | Keeps entry, intermediate, expert, or any jobs.                               |
| 👥 `maxProposalCount`    | Skips jobs above a proposal-count ceiling when available.                     |
| 💸 `minHourlyRate`       | Keeps hourly jobs whose max hourly rate reaches the selected floor.           |
| 💸 `maxHourlyRate`       | Keeps hourly jobs whose min hourly rate stays below the selected ceiling.     |
| 💰 `minFixedBudget`      | Keeps fixed-price jobs at or above a budget floor.                            |
| 💰 `maxFixedBudget`      | Keeps fixed-price jobs at or below a budget ceiling.                          |
| 🎯 `titleMustInclude`    | Saves jobs whose title contains at least one required term.                   |
| 🚫 `titleExclude`        | Skips jobs whose title contains excluded terms.                               |
| ♻️ `saveOnlyUniqueItems` | Saves each Upwork job once by default.                                        |
| 📄 `maxPagesPerSearch`   | Sets how many result pages to check for each keyword.                         |

For most first runs, keep the default quality controls on and use a small
`maxItems` value.

### ⬆️ Output sample

The results are stored in the default dataset. Each result is one saved Upwork
job opportunity.

```json
{
    "title": "Build a web scraping pipeline",
    "url": "https://www.upwork.com/jobs/~021234567890123456789",
    "description": "Need help collecting public product data and exporting it to CSV.",
    "published_at": "2026-06-25T15:52:24.851Z",
    "category": null,
    "subcategory": null,
    "skills": ["Data Extraction", "Python", "Web Scraping"],
    "engagement_type": "fixed",
    "experience_level": "expert",
    "budget_amount": 500,
    "budget_currency": "USD",
    "hourly_min_amount": null,
    "hourly_max_amount": null,
    "hourly_currency": null,
    "freelancers_to_hire": 1,
    "proposal_count": 4,
    "client_last_activity_at": "2026-06-25T17:06:13.700Z",
    "interviewing_count": 1,
    "invites_sent": 0,
    "unanswered_invites_count": 0,
    "hires_count": 0,
    "offers_count": 0,
    "recommended_count": 2,
    "source_query": "web scraping",
    "source_job_id": "1234567890123456789",
    "source_created_at": "2026-06-25T15:50:00.000Z",
    "observed_at": "2026-06-25T18:49:05.448Z"
}
```

The default Apify table view focuses on the fields most users scan first:
title, description, posted time, type, experience level, budget, hourly range,
proposal count, client activity, skills, query, and URL.

### 📌 Run summary

The Actor writes a compact `OUTPUT` record with run accounting. Use it to audit
whether the run stopped because it hit `maxItems`, page limits, source
exhaustion, filters, or blocked requests.

Useful summary fields include:

| Summary field                 | Meaning                                                      |
| ----------------------------- | ------------------------------------------------------------ |
| 🚦 `stopReason`               | Why the run stopped.                                         |
| 👀 `candidateItemsSeen`       | Number of candidate job rows seen before filtering.          |
| ✅ `jobsSaved`                | Number of dataset rows saved.                                |
| 🔁 `duplicateCandidatesSeen`  | Number of duplicate candidates detected.                     |
| ♻️ `duplicatesSkipped`        | Duplicate candidates skipped when unique-job mode is on.     |
| 📅 `rowsExcludedByDate`       | Rows removed by freshness filter.                            |
| 💼 `rowsExcludedByJobType`    | Rows removed by hourly/fixed-price filter.                   |
| 🪜 `rowsExcludedByExperience` | Rows removed by experience-level filter.                     |
| 👥 `rowsExcludedByProposals`  | Rows removed by proposal-count filter.                       |
| 💰 `rowsExcludedByBudget`     | Rows removed by budget or hourly-range filters.              |
| 🎯 `rowsExcludedByTitle`      | Rows removed by title include/exclude filters.               |
| 🧱 `blockedRequests`          | Source responses that looked blocked, challenged, or denied. |
| ⚠️ `failedRequests`           | Requests that failed after retries.                          |
| ⏰ `nextRunAfter`             | Suggested time for a scheduled follow-up run.                |
| 📝 `warnings`                 | Human-readable warnings from the run.                        |

### 🧭 Practical notes

Upwork job listings change quickly. Treat each run as a point-in-time snapshot.
For monitoring, schedule repeated runs and compare rows by `source_job_id` or
`url`.

Activity fields come from public job detail data. They are collected when Upwork
exposes them for a job during the run. If Upwork does not expose a field, the
value remains `null`.

Some source responses may be blocked, challenged, rate-limited, or incomplete.
When that happens, the Actor records blocked and failed request counts in
`OUTPUT` instead of pretending every missing row was available.

For larger monitoring jobs, increase `maxItems` and `maxPagesPerSearch`
gradually, then use Apify schedules for recurring monitoring. This keeps source
access, costs, and result review manageable.

### ❓ Common questions

#### 🧲 Is this for finding freelance gigs or sales leads?

Mostly gigs first, leads second. Most users search Upwork jobs to discover fresh
work they can apply to, route to a specialist, or qualify as an agency
opportunity. Keyword choice controls the workflow: `web scraping` finds
freelance gigs, while phrases like `lead generation`, `Apollo enrichment`, or
`Shopify migration` can surface buyer intent for agencies and service teams.

#### 🔐 Does this need an Upwork login?

No. The Actor is designed around public Upwork job surfaces and does not ask for
an Upwork account, user cookies, or user-provided credentials.

#### 💳 Can it scrape client payment verification, total spend, or ratings?

Those richer client fields are not promised in the public output. The Actor
captures the public job and activity fields that have cloud-run evidence. If
Upwork exposes additional reliable client fields later, they should be added as
new stable columns rather than changing existing fields.

#### 🕳️ Why are some fields null?

Upwork does not expose every field for every job. The Actor uses `null` for
unavailable values instead of guessing.

#### 🔔 Can I run alerts from this Actor?

Yes. Use keywords, `sortBy: "recency"`, a freshness window such as `24h` or
`7d`, and scheduled Apify runs. Keep `saveOnlyUniqueItems` enabled and compare
saved rows by `source_job_id` or `url`.

#### 📈 Can I use it for high-volume Upwork monitoring?

Yes, but increase volume gradually. Start with a small run, inspect `OUTPUT`,
then raise `maxItems` and `maxPagesPerSearch`. Use schedules instead of one
very large run when you need ongoing monitoring.

# Actor input Schema

## `searchTerm` (type: `string`):

Enter one Upwork job keyword, skill, title, or phrase per line. Examples: web scraping, lead generation, data entry, AI automation, Shopify, Python.

## `postedWithin` (type: `string`):

Keep only jobs posted in this freshness window when publish time is available.

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

Choose newest first for job alerts and fast opportunity review, or relevance for broad research.

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

Maximum number of unique job listings to save across all keywords.

## `jobType` (type: `string`):

Keep hourly jobs, fixed-price jobs, or both.

## `experienceLevel` (type: `string`):

Keep one Upwork experience level, or leave as Any.

## `maxProposalCount` (type: `integer`):

Skip jobs above this proposal-count ceiling when proposal count is available. Use 0 to keep all.

## `minHourlyRate` (type: `integer`):

Keep hourly jobs whose visible max hourly rate is at least this value. Use 0 to keep all.

## `maxHourlyRate` (type: `integer`):

Keep hourly jobs whose visible min hourly rate is at most this value. Use 0 to keep all.

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

Keep fixed-price jobs where the visible budget is at least this value. Use 0 to keep all.

## `maxFixedBudget` (type: `integer`):

Keep fixed-price jobs where the visible budget is at most this value. Use 0 to keep all.

## `titleMustInclude` (type: `string`):

Optional. Enter one word or phrase per line. A job is saved only if its title contains one of these terms.

## `titleExclude` (type: `string`):

Optional. Enter one word or phrase per line. Jobs with these words in the title are skipped.

## `saveOnlyUniqueItems` (type: `boolean`):

Save each Upwork job once, even if it appears under more than one keyword or page.

## `maxPagesPerSearch` (type: `integer`):

How many result pages to check for each keyword. Increase this only when you need more jobs than the first pages return.

## Actor input object example

```json
{
  "searchTerm": "web scraping\nlead generation\ndata entry\nAI automation\nShopify\nPython",
  "postedWithin": "7d",
  "sortBy": "recency",
  "maxItems": 25,
  "jobType": "any",
  "experienceLevel": "any",
  "maxProposalCount": 0,
  "minHourlyRate": 0,
  "maxHourlyRate": 0,
  "minFixedBudget": 0,
  "maxFixedBudget": 0,
  "titleMustInclude": "",
  "titleExclude": "",
  "saveOnlyUniqueItems": true,
  "maxPagesPerSearch": 2
}
```

# Actor output Schema

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

No description

## `output` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "searchTerm": `web scraping
lead generation
data entry
AI automation
Shopify
Python`,
    "saveOnlyUniqueItems": true
};

// Run the Actor and wait for it to finish
const run = await client.actor("chronometrica/upwork-job-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "searchTerm": """web scraping
lead generation
data entry
AI automation
Shopify
Python""",
    "saveOnlyUniqueItems": True,
}

# Run the Actor and wait for it to finish
run = client.actor("chronometrica/upwork-job-scraper").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "searchTerm": "web scraping\\nlead generation\\ndata entry\\nAI automation\\nShopify\\nPython",
  "saveOnlyUniqueItems": true
}' |
apify call chronometrica/upwork-job-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Upwork Job Scraper - Fresh Jobs & Client Signals",
        "description": "Find fresh Upwork jobs by keyword, filter worthwhile gigs by budget, hourly or fixed type, experience level, proposal count, and title terms, then export clean rows for alerts, lead routing, market research, and workflows. No Upwork login or cookies required.",
        "version": "0.1",
        "x-build-id": "9ESZCWnoYefHqCtze"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/chronometrica~upwork-job-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-chronometrica-upwork-job-scraper",
                "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/chronometrica~upwork-job-scraper/runs": {
            "post": {
                "operationId": "runs-sync-chronometrica-upwork-job-scraper",
                "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/chronometrica~upwork-job-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-chronometrica-upwork-job-scraper",
                "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": {
                    "searchTerm": {
                        "title": "Keywords",
                        "type": "string",
                        "description": "Enter one Upwork job keyword, skill, title, or phrase per line. Examples: web scraping, lead generation, data entry, AI automation, Shopify, Python."
                    },
                    "postedWithin": {
                        "title": "Posted within",
                        "enum": [
                            "any",
                            "24h",
                            "3d",
                            "7d",
                            "14d",
                            "30d"
                        ],
                        "type": "string",
                        "description": "Keep only jobs posted in this freshness window when publish time is available.",
                        "default": "7d"
                    },
                    "sortBy": {
                        "title": "Sort by",
                        "enum": [
                            "recency",
                            "relevance"
                        ],
                        "type": "string",
                        "description": "Choose newest first for job alerts and fast opportunity review, or relevance for broad research.",
                        "default": "recency"
                    },
                    "maxItems": {
                        "title": "Jobs to save",
                        "minimum": 1,
                        "maximum": 10000,
                        "type": "integer",
                        "description": "Maximum number of unique job listings to save across all keywords.",
                        "default": 25
                    },
                    "jobType": {
                        "title": "Job type",
                        "enum": [
                            "any",
                            "hourly",
                            "fixed"
                        ],
                        "type": "string",
                        "description": "Keep hourly jobs, fixed-price jobs, or both.",
                        "default": "any"
                    },
                    "experienceLevel": {
                        "title": "Experience level",
                        "enum": [
                            "any",
                            "entry",
                            "intermediate",
                            "expert"
                        ],
                        "type": "string",
                        "description": "Keep one Upwork experience level, or leave as Any.",
                        "default": "any"
                    },
                    "maxProposalCount": {
                        "title": "Maximum proposals",
                        "minimum": 0,
                        "maximum": 1000,
                        "type": "integer",
                        "description": "Skip jobs above this proposal-count ceiling when proposal count is available. Use 0 to keep all.",
                        "default": 0
                    },
                    "minHourlyRate": {
                        "title": "Minimum hourly rate",
                        "minimum": 0,
                        "maximum": 1000,
                        "type": "integer",
                        "description": "Keep hourly jobs whose visible max hourly rate is at least this value. Use 0 to keep all.",
                        "default": 0
                    },
                    "maxHourlyRate": {
                        "title": "Maximum hourly rate",
                        "minimum": 0,
                        "maximum": 1000,
                        "type": "integer",
                        "description": "Keep hourly jobs whose visible min hourly rate is at most this value. Use 0 to keep all.",
                        "default": 0
                    },
                    "minFixedBudget": {
                        "title": "Minimum fixed budget",
                        "minimum": 0,
                        "maximum": 10000000,
                        "type": "integer",
                        "description": "Keep fixed-price jobs where the visible budget is at least this value. Use 0 to keep all.",
                        "default": 0
                    },
                    "maxFixedBudget": {
                        "title": "Maximum fixed budget",
                        "minimum": 0,
                        "maximum": 10000000,
                        "type": "integer",
                        "description": "Keep fixed-price jobs where the visible budget is at most this value. Use 0 to keep all.",
                        "default": 0
                    },
                    "titleMustInclude": {
                        "title": "Title must include",
                        "type": "string",
                        "description": "Optional. Enter one word or phrase per line. A job is saved only if its title contains one of these terms.",
                        "default": ""
                    },
                    "titleExclude": {
                        "title": "Skip titles containing",
                        "type": "string",
                        "description": "Optional. Enter one word or phrase per line. Jobs with these words in the title are skipped.",
                        "default": ""
                    },
                    "saveOnlyUniqueItems": {
                        "title": "Deduplicate jobs",
                        "type": "boolean",
                        "description": "Save each Upwork job once, even if it appears under more than one keyword or page.",
                        "default": true
                    },
                    "maxPagesPerSearch": {
                        "title": "Search depth",
                        "minimum": 1,
                        "maximum": 100,
                        "type": "integer",
                        "description": "How many result pages to check for each keyword. Increase this only when you need more jobs than the first pages return.",
                        "default": 2
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
