Upwork data, ready when you are.
Job search from Upwork with its own filters.
- See the price before every call
- Pay only for records that come back
- No subscription. Your balance never expires
What you can get.
What the data looks like.
| jobTitle | jobType | fixedBudget | experienceLevel | projectLength | skills | applicants | posted | hourlyRateMin | hourlyRateMax | jobId | jobUrl | details |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Build a Shopify product feed sync | fixed | 800 | intermediate | 1 to 3 months |
| 10 to 15 | 2026-10-15 | null | null | 2355543097 | https://www.upwork.com/build-a-shopify-product-feed-sync-1000 |
|
| Shopify theme speed fixes | hourly | null | expert | Less than 1 month |
| 5 to 10 | 2026-10-14 | 30 | 60 | 2614115498 | https://www.upwork.com/shopify-theme-speed-fixes-1001 |
|
| Migrate store from WooCommerce to Shopify | fixed | 1,500 | expert | 1 to 3 months |
| 20 to 50 | 2026-10-13 | null | null | 1884115080 | https://www.upwork.com/migrate-store-from-woocommerce-to-shopif-1002 |
|
For developers
API reference.
One endpoint, POST /v1/upwork. Open an operation to see its fields.
Searchsearch
Search Upwork jobs with the marketplace's own filters. Every hit a full posting with budget, client profile and proposal counts.
| Field | Type | Meaning |
|---|---|---|
| query * | string · ≤300 chars | |
| sort | enum | relevance · newest |
| includeHourly | boolean | Keep hourly-rate jobs. Set both this and includeFixed false and nothing matches. |
| hourlyMin | integer · 0- | USD per hour. |
| hourlyMax | integer · 0- | USD per hour, the upper bound; only hourly jobs are affected. |
| includeFixed | boolean | Keep fixed-price jobs. |
| budgetMin | integer · 0- | USD, the fixed-price budget. |
| budgetMax | integer · 0- | USD, the fixed-price budget's upper bound; only fixed jobs are affected. |
| experienceLevel | list of enum | The level the client asked for. Any listed level matches; empty = all.entry · intermediate · expert |
| clientHistory | list of enum | How many jobs the client has hired for before: none, 1-9, or 10+. Empty = any client.0 · 1-9 · 10- |
| projectLength | list of enum | Expected duration: under a week, under a month, 1-6 months, or ongoing (6+). Empty = any length.week · month · semester · ongoing |
| hoursPerWeek | list of enum | Weekly commitment: part-time (under 30 h) or full-time (30 h+). Empty = either.part_time · full_time |
| clientLocation | list of string · each ≤60 chars | Client countries, as Upwork spells them ("United States"). |
| limit | integer · 5-100 |
Response fields, each row of data
| Field | Type |
|---|---|
| jobId | string |
| jobUrl | string |
| jobTitle | string |
| jobDescription | string |
| posted | string |
| deadline | string |
| jobType | string |
| projectType | string |
| projectLength | string |
| weeklyWorkload | string |
| hourlyRateMin | number |
| hourlyRateMax | number |
| fixedBudget | number |
| hourlyBudgetSource | string |
| experienceLevel | string |
| englishLevel | string |
| skills | any |
| skillGroups | list of string |
| category | string |
| categoryGroup | string |
| occupation | string |
| applicants | integer |
| interviewing | integer |
| invitesSent | integer |
| unansweredInvites | integer |
| hired | integer |
| positionsToHire | integer |
| jobStatus | string |
| jobAccess | string |
| contractToHire | boolean |
| featuredJob | boolean |
| localMarketJob | boolean |
| locationCheckRequired | boolean |
| risingTalentOk | boolean |
| minJobSuccessScore | number |
| freelancerType | string |
| requiredCountries | string |
| requiredRegions | string |
| requiredTimezones | string |
| requiredLanguages | string |
| client | any |
| clientOtherOpenPostings | any |
| similarJobs | any |
| resultRank | integer |
| details | object |
Every field is present on every row: a value the source had nothing for is null, an empty list is []. details is always the last field: everything else the source sent for that row, under our own field names. Its keys depend on the source that answered, so read them defensively; it is {} when there is nothing more.
curl -X POST https://apiforagents.dev/v1/upwork \
-H "Authorization: Bearer $AFA_KEY" \
-H "Content-Type: application/json" \
-d '{"op":"search","query":"shopify developer","sort":"newest","experienceLevel":["expert"],"clientLocation":["United States"],"limit":10}'Example response rows
[
{
"jobTitle": "Build a Shopify product feed sync",
"jobType": "fixed",
"fixedBudget": 800,
"experienceLevel": "intermediate",
"projectLength": "1 to 3 months",
"skills": [
"Shopify",
"Node.js",
"APIs"
],
"applicants": "10 to 15",
"posted": "2026-10-15",
"hourlyRateMin": null,
"hourlyRateMax": null,
"jobId": "2355543097",
"jobUrl": "https://www.upwork.com/build-a-shopify-product-feed-sync-1000",
"details": {}
},
{
"jobTitle": "Shopify theme speed fixes",
"jobType": "hourly",
"fixedBudget": null,
"experienceLevel": "expert",
"projectLength": "Less than 1 month",
"skills": [
"Shopify",
"Liquid",
"Web performance"
],
"applicants": "5 to 10",
"posted": "2026-10-14",
"hourlyRateMin": 30,
"hourlyRateMax": 60,
"jobId": "2614115498",
"jobUrl": "https://www.upwork.com/shopify-theme-speed-fixes-1001",
"details": {}
}
]An example to show the shape. The rows show the most used fields; a live row carries every field in the table above.
Historyhistoryfree
Stored proposal-count series of postings already held. Free.
| Field | Type | Meaning |
|---|---|---|
| subjects * | list of string · 1-10 items | |
| metric | enum | applicants · interviewing · invites_sent · hired |
| days | integer · 1-730 |