# Upwork job-board API — live freelance jobs from upwork.com in clean JSON: title, full brief, fixed or hourly budget, required skills, experience level, project length, posting timestamp, proposal count, and the client's country, spend, hire count and rating. Search with Upwork's own filters or pull one job in full. No login required.

> Search live Upwork jobs by keyword and Upwork's own filters — category and subcategory, contract type, experience level, project length, weekly workload, client location, how many people the client has hired, client timezone — plus a posted-within-N-hours cut. Returns title, full description, budget, skills, posting timestamp and coarse client signals for each job, with the total match count.
> ReefAPI engine `upwork` · 3 endpoints · clean JSON, no scraping or browsers to manage.

## How to call
- **Endpoint:** `POST https://api.reefapi.com/upwork/v1/<action>` with a JSON body.
- **Auth:** header `x-api-key: <YOUR_REEFAPI_KEY>` — create one free (1,000 credits, no card): https://reefapi.com/signup
- **Response (every call):** `{ ok: boolean, data: ..., meta: { record_count, credits, ... }, error: { code, message } }` — branch on `ok`. Failed calls are free except verified SHEIN NOT_FOUND on product/detail and price (4 credits).
- **One key + one shared credit pool** across every ReefAPI API. Per-call credits are listed on each endpoint below.
- **Use it from an AI agent (MCP):** connect `https://api.reefapi.com/mcp` (remote streamable-http). Send the key as `Authorization: Bearer <key>`, or put it in the URL (`?key=<key>`) when the client has no header field, as ChatGPT does.

## Endpoints

### POST https://api.reefapi.com/upwork/v1/search — 1 credit
Search live Upwork jobs by keyword and Upwork's own filters — category and subcategory, contract type, experience level, project length, weekly workload, client location, how many people the client has hired, client timezone — plus a posted-within-N-hours cut. Returns title, full description, budget, skills, posting timestamp and coarse client signals for each job, with the total match count.

**Parameters:**
- `query` (string, optional) — Keyword to search job titles and descriptions. Omit it to browse the whole open board (109k+ jobs) newest-first.
- `limit` (integer, optional, default 20) — How many jobs to return (1–200). Upwork serves 50 per page, so anything over 50 costs extra page fetches.
- `offset` (integer, optional, default 0) — Skip this many results before returning `limit` (0–5000).
- `category` (string, optional) — Only jobs in this Upwork category: its name ('Web, Mobile & Software Dev', 'Design & Creative') or its uid. Comma-separated for several (either matches). Call `filters` for all names and uids.
- `subcategory` (string, optional) — Only jobs in this Upwork subcategory: its name or uid. Comma-separated for several. Call `filters` for the list (each category's `subcategories`).
- `job_type` (string, optional) — Contract type. Accepts both, comma-separated. [one of: hourly, fixed]
- `experience_level` (string, optional) — Experience level the buyer asked for. Comma-separated for several. [one of: entry, intermediate, expert]
- `duration` (string, optional) — Project length: week = less than a month, month = 1–3 months, semester = 3–6 months, ongoing = more than 6 months. The spelled-out labels ('1_to_3_months', 'more_than_6_months') are accepted too. [one of: week, month, semester, ongoing]
- `workload` (string, optional) — Hours per week: as_needed (under 30) or full_time (30+). [one of: as_needed, full_time]
- `client_location` (string, optional) — Where the CLIENT is: a country ('Germany'), a region ('Europe') or a sub-region ('Northern Europe'). Comma-separated for several. Call `filters` for the exact 263 accepted values.
- `client_hires` (string, optional) — How many freelancers this client has ever hired: 0 (never hired), 1-9, or 10- (ten or more). [one of: 0, 1-9, 10-]
- `timezone` (string, optional) — Client timezone, as an IANA name. Call `filters` for the 72 values Upwork accepts.
- `skill_uid` (string, optional) — Require a specific Upwork SKILL, by its numeric uid. Take the uid from any job's `skills_detail[].uid` in a previous response — Upwork publishes no skill directory to a logged-out visitor, so that is where the values come from. Comma-separated for several.
- `sort` (string, optional, default "relevance") — Result order. `newest` sorts by posting time. [one of: relevance, newest]
- `posted_within_hours` (integer, optional) — Only jobs posted in the last N hours. Upwork gives a logged-out visitor no posted-date filter, so this one is applied by us: the search is forced to newest-first and paging stops at the first job older than the window. `filtered_out` in the response says how many rows the cut removed.

**Returns:** jobs[]{id, cipher_id, url, title, description, job_type, budget{type,amount|min|max,currency,weekly}, experience_level, duration_label, workload, skills[], skills_detail[]{name,uid}, posted_at, posted_at_epoch, published_at, renewed_at, freelancers_to_hire, is_premium, is_enterprise, client{payment_verified,country,total_spent,total_reviews,rating}}, total_count, returned, offset, filtered_out

**Example request body:**
```json
{
  "query": "python",
  "limit": 10
}
```

### POST https://api.reefapi.com/upwork/v1/job — 1 credit
Everything Upwork publishes about one job: the full brief, budget (fixed amount or hourly range), category and occupation, skills with mandatory/nice-to-have weighting, experience level, project length in weeks, freelancer requirements (countries, languages, minimum job-success score and hours), how many people have applied, been interviewed and been hired, and the client's history — country, city, timezone, total spend, jobs posted, hires, hours billed, review count, rating and member-since date. Plus Upwork's own list of similar jobs. Note that Upwork withholds a minority of listed jobs from anyone who is not signed in; those return NOT_FOUND. `search` already carries the full brief, budget, skills and posting time for every job, so this endpoint is for the ones you shortlist.

**Parameters:**
- `id` (string, required) — The job: its cipher id ('~02…' as `search` returns in `cipher_id`), a full Upwork job URL, or the bare numeric id.

**Returns:** job{...all search fields..., category, category_group, occupation, skills_detail[]{name,group,relevance}, duration_weeks, budget_hidden, positions_to_hire, is_contract_to_hire, proposals{total_applicants,total_hired,interviewing,invitations_sent,last_client_activity}, requirements{countries,languages,min_job_success_score,min_hours_worked,rising_talent_only}, client{payment_verified,country,city,timezone,total_spent,total_jobs_posted,total_hires,hours_billed,reviews,rating,member_since,industry,company_size}, similar_jobs[]}

**Example request body:**
```json
{
  "id": "~022103052334483241712"
}
```

### POST https://api.reefapi.com/upwork/v1/filters — 1 credit
The exact filter vocabulary Upwork's own job search ships — every accepted client location (263 countries, regions and sub-regions), timezone (72), contract type, experience level, project length, workload and client-hire band. Read straight off the live search page, so it cannot drift from what `search` accepts.

**Parameters:** none

**Returns:** filters{category[]{uid,label,subcategories[]{uid,label}}, client_location[]{value,label,type,region}, timezone[], job_type[], experience_level[], duration[], workload[], client_hires[], sort[]}, source

## At scale
- **Volume:** 5M+ requests a day, measured at 60 requests a second across the fleet with no
  central bottleneck. Per-key limits are raised for high-volume accounts; volume pricing on request.
- **Missing a source:** tell us a site we do not cover and it becomes an engine. A customer asked
  for bestprice.gr on 21 Sep 2026 and it was in the catalog on 22 Sep.
- **Support:** 2 minute median time from a question in the live chat to the first answer. Setup
  help included, no support tier to buy.
- **One key, one credit pool** across every API. No per-site plans, no separate subscriptions.

## More
- Try it live, no code: https://reefapi.com/playground?engine=upwork
- Human docs page: https://reefapi.com/docs/upwork
- Overview page: https://reefapi.com/upwork-api
- Every ReefAPI API in one file (for your AI): https://reefapi.com/llms-full.txt
