Upwork reviews every API key and bars commercial use. We already hold an approved Business Manager, so your code does not need one. 40 operations, from the job match to the booked meeting.
15 million jobs analysed since 2021.That is the index behind your key.
15M+Upwork jobs analysed
6M+Proposals sent through GigRadar
$45M+Earned by our users
800Agencies bidding through GigRadar today
Bring your own model and your own wiring.
The API does not replace the auto bidder. It sits on top of it, so you can experiment with bidding in ways the interface was never going to let you.
Keep bidding in the product where the product is better. Reach for the key when you want your own model writing the letter, your own experiments running across scanners, or the market data underneath both.
Set the filters.Your agent does the bidding.
This is the real filter set on GET /gigs. Change one and watch the queue your code would wake up to.
Simulated bench. The request shapes, the filter names and the limits are the real ones. The counts and the sample job are illustrative.
The request your scanner is built from
GET /gigs?q="AI agent" OR "LLM integration"?q="React" OR "Next.js"?q="Shopify" OR "Liquid"?q="contract review" OR "legal automation"?q="dbt" OR "data pipeline"&paymentVerified=true&minClientSpend=10000&minHireRate=50
of 27 filters set
Payment verified clients reply about four times more often. That is one boolean in the scanner.
This is the raw queue. The filters are where the money is.
The jobs left in this queue reply about four times more often. Fewer bids, more replies, same Connects.
Every client left has spend or hires on record. Fewer bids, same Connects.
The bar is the share of the unfiltered queue that survives your client filters. The number above it is what is left. Switch one on and both move.
Next match in the queue
Build an LLM agent for support triage
budget
$4,500
client spend
$42,000
payment verified
yes
hire rate
41 percent
matchScore
0.86
In the queue
Filtered out before your code woke up
Marketing site rebuild in Next.js
budget
$2,800
client spend
$6,400
payment verified
yes
hire rate
67 percent
matchScore
0.71
In the queue
Filtered out before your code woke up
Migrate a Shopify Plus theme
budget
$3,200
client spend
$118,000
payment verified
no
hire rate
88 percent
matchScore
0.79
In the queue
Filtered out before your code woke up
Automate NDA review with an LLM
budget
$6,000
client spend
$27,000
payment verified
yes
hire rate
74 percent
matchScore
0.91
In the queue
Filtered out before your code woke up
Build a dbt pipeline into Snowflake
budget
$9,000
client spend
$310,000
payment verified
yes
hire rate
46 percent
matchScore
0.83
In the queue
Filtered out before your code woke up
Tighten one filter and a named job stops arriving. Nothing in the API reports what it dropped, so the filter set is the thing to get right before you ship it.
This is a reconstruction, not a live console. The clock and the costs are what one match adds up to when it arrives and nobody is at the desk.
02:14:03Webhook in. opportunity.create, scanner "AI integration, verified clients", matchScore 0.86.
02:14:03Your endpoint answers 200 in 240ms. The five second window never gets close.
02:14:04Your agent reads the brief and the client history, then drafts the letter.
02:14:06Claude Code writes a proposal page built for this one job and deploys it to Vercel.
02:14:09The deployed link goes back to GigRadar. POST /opportunities/{id}/application, and we put the bid on Upwork through the approved Business Manager. 200 OK, status submitted.
02:14:11Room opens in the CRM. Stage set to new, updatedByUserId is your agent, not a person.
06:52:40Client replies. Webhook again, and your endpoint answers 200.
06:52:58Agent answers through POST /crm/rooms/{id}/messages, which sends immediately. Stage moves to interested, and you have not opened a browser yet.
Upwork's own API cannot tell you any of this.Yours can.
Upwork lets you read a job. It will not tell you what the market is doing, which categories are drying up, or how your own agency is performing inside it. The same key that submits your proposals queries fifteen million jobs we have indexed since 2021, and every conversation your team has had. Below are real examples of the data that comes back.
Is the category you built your agency on still growing?
Web Development lost 40% of its jobs in nine months.
-39.7%Aug 2025 to Apr 2026
Aug 25OctDecFeb 26Apr
19,593 jobs / mo11,818 jobs / mo
GET /gigs
Upwork carried 11,818 Web Development postings in April 2026, against 19,593 in August 2025. If you bid web dev on the same volume you did last summer, you are fighting for a pool that shrank by a third. You would only see it if something counted every month. That is one scheduled call.
Real Upwork job counts by subcategory, Aug 2025 to Apr 2026. Pulled with the same filters GET /gigs exposes.
Example: market data you can pull through the API
Legal, Engineering and Sales briefs reply 1.5 to 3 times more often than Web Development. The niche you size next does not have to be the one you are in.
Is this niche big enough to build a scanner for?
Size a niche before you commit to it.
q "AI agent" OR "LLM integration"
1,092avg monthly matches
POST /scanners
Every create, update and duplicate returns avgMonthlyMatches. You find out the niche is too thin before you spend a month bidding into it.
Are you selling the skills clients are actually asking for?
Close the gap between your profile and the brief.
Reacton profile
Next.json profile
LangChainmissing
RAGmissing
Node.json profile
GET /gigs-insights
Returns the top skill and ontology keywords clients used in your niche. Diff that against what your profiles claim and you get a rewrite list, not an opinion.
Example: your own agency, queried through the API
Where do your leads actually die?
Your funnel, by stage, per profile.
new412
interested194
booked78
qualified45
converted21
GET /crm/rooms/search
Search by stage and by date range, and each stage change carries updatedAt and updatedByUserId. So you get time in stage and who moved it, split by connected account.
Which scanners are earning their Connects?
Audit every scanner, including the deleted ones.
AI integration, US, verified340
Shopify, any budget214
React, no min spend116
Wordpress, $10+ deleted44
GET /scanners?status=all
Soft deleted scanners are kept for historical reporting, so you can see the one someone switched off in March and what it was catching before they did.
Charts above are illustrative except the market trend, which is real Upwork data. The API reads the market and your own team. It has no access to other agencies' numbers, so it cannot benchmark you against a peer cohort, and it cannot read Upwork profile internals like rates or portfolio items.
One job match, four calls.You write the code between them.
Press Run and the loop plays through in front of you. Or click any move and read that call on its own. Both do the same thing, one is just faster to watch.
Elapsed 0.3s0 Connects spentRunning total for this one match
A scanner match wakes your code.You did not poll for it.
Three webhook events, up to 20 destinations per team. The payload carries the scanner that caught it, the score, and whether GigRadar thinks it qualifies.
Your endpoint has five seconds to answer 200. Delivery lands between one and ten seconds after the match.
Your text goes out on our rails.Upwork sees an approved Business Manager.
Your agent writes the cover letter. GigRadar submits it and reports back what it cost in Connects. There is a minimum of 20 characters on the letter and the spec sets no maximum.
The request and the response, field for field
POST /opportunities/{id}/application
{
"coverLetter": "Read your triage spec. Here is a working…",
"bidAmount": 65
}
200 OK
{ "status": "submitted", "connectsSpent": 12 }
Turn the auto bidder off in any scanner where the API bids, or the same job gets two proposals. An opportunity has to be under 28 days old to accept one.
The client answers at 4am.So does your code.
Every Upwork conversation is a CRM room you can search by date and by stage, filtered down to one profile or one connected account. Write into it, or queue the reply for a civilised hour.
The search call and the message write
GET /crm/rooms/search?stages=interested
POST /crm/messages
{
"roomId": "rm_8f21…",
"body": "Tuesday 15:00 UTC works. Calendar link…",
"scheduledAt": "2026-04-18T09:00:00Z"
}
A scheduled message can sit at most twelve hours out. Longer than that and you hold it on your own side.
The stage moves and the clock starts.Both are readable.
Each lead stage carries when it changed and who changed it, so time in stage and human against agent are both computable. Meetings and senders close the loop, and the next match is already in the queue.
The whole loop runs inside 30 requests a minute and 1,000 a day. That is the ceiling on every call above, added together.
Payloads above are trimmed for reading. The field names, the limits and the status codes are the real ones. The values inside them are illustrative.
A use case you can copy today.Ned ships a website with every bid.
A scanner match wakes his coding agent. It writes and deploys a site for that one job, then submits the bid with the link already inside it. The whole build is four stages and we published every one of them, so you can rebuild it against your own scanners this afternoon.
A conversation withNed ThomasGigRadar customer, building against the Public API
I have my scanner set up, so my Claude Code can analyse and pivot my campaigns. Every proposal ships with a page built for that one job.
What now exists that did not.
A live page attached to the proposal before the proposal is sent.
One scanner match and one deploy, with no human step between them.
A campaign the agent can read back and change on its own.
We asked for a win rate and revenue. We have neither, so there is no number here.
One key.Every step from the job match to the booked meeting.
Gigs
Twenty seven filters over every job on Upwork.
Scanners
Every write returns avgMonthlyMatches.
Opportunities
The job that matched, its score, and its application.
Applications
Your letter, your bid, and the Connects it cost.
Webhooks
Three events, twenty destinations per team.
CRM Rooms
Every conversation, searchable by stage and date.
CRM Messages
Read the thread and write back into it.
Scheduled Messages
Queue the follow up, at most twelve hours out.
Meetings, Files, Senders
Propose times and pick the sending profile.
Forty operations across thirty two paths. Every path, parameter and response shape is in the reference.
A hundred dollars a month.Roughly what 42 bids cost in Connects.
A bid costs 4 to 16 Connects and a Connect costs $0.15. So the API prices out between 42 and 167 bids' worth of Connects, and it is the part that stops a person from placing any of them by hand.
What the key gets you that the product alone does not
Your own model in the loop. Bring Claude, a fine tune, or your own scoring, and let it decide how a proposal gets written.
Experiments the interface cannot run. A and B test cover letters, bid amounts, reply timing and follow ups across scanners, then read the outcome per connected profile.
Read and write the whole conversation. Not only the bid. Answer clients, queue follow ups and move stages from your own code.
The data moat. Fifteen million Upwork jobs indexed since 2021, queryable with the same twenty seven filters, so you can measure your agency against the market instead of guessing.
The Public API
$100a month, on top of your GigRadar subscription
Or $960 a year, which is $240 less than paying monthly.
One key, all 40 operations
30 requests a minute and 1,000 a day
20 webhook destinations per team across three events
The parts that will annoy you.Written down before you buy.
Is any of this allowed by Upwork?
Upwork's createJobProposal mutation exists, and Upwork bars commercial use of its API, reviews every key by hand and offers no sandbox. Proposals from this API go out through GigRadar's own approved Business Manager, so your key never has to clear that review.
GigRadar is not an Upwork partner and has no affiliation with Upwork. We are not going to tell you the risk is zero, because it is not ours to promise.
What can the API simply not see?
Other agencies. You cannot benchmark yourself against a peer cohort, and you cannot read another user's profile internals, their rates, specialized profiles or portfolio items. That is their data, not yours.
Your own agency is fully open to you: every scanner, every connected profile, every conversation and every stage change on the account you already pay for, plus the whole Upwork market on top.
Can I pull the proposals I already sent?
No endpoint lists opportunities. There is GET /opportunities/{id} and nothing that enumerates them, so proposal history is forward only from the day you start catching webhooks.
GET /webhooks/deliveries gives you the metadata of what fired: job id, scanner name, date, event type. It does not give you the payloads back. Store them when they arrive.
What happens if I leave the auto bidder on?
Whichever is faster gets there first, and that is usually the API, because your code reacts to the webhook. Upwork only accepts one proposal per job, so you are not double bidding and you are not double spending Connects.
Which raises the real question: there is no reason to rebuild your whole bidding setup through the API. The auto bidder already does that with an interface built for it. Use the API for the parts the interface cannot do, your own model, your own experiments, your own data.
What are the hard limits?
30 requests a minute and 1,000 a day. Webhooks expect a 200 inside five seconds and deliver one to ten seconds after the event, with 20 destinations per team across three events.
scheduledAt tops out at twelve hours. An opportunity has to be under 28 days old to take an application. coverLetter has a minimum of 20 characters and the spec sets no maximum, which means the length discipline is yours.
Who can actually use this?
Agencies with an active GigRadar subscription. The key reads and writes against your GigRadar account, so there has to be one, with at least one connected Upwork profile and one scanner running.
A solo freelancer without an Upwork agency cannot use it. Proposals go out through a Business Manager connected to an agency account, and without that account there is nothing for the key to bid from.
What do I need before day one?
An active plan, the API add on at $100 a month, at least one connected Upwork profile and one scanner. Then a public endpoint that answers 200 in under five seconds.
Sizing a niche is the cheapest first call: create a scanner, read avgMonthlyMatches off the response and delete it again if the queue is too thin to bother with.
The next match fires whether your code is listening or not.Point it at your own account.
Proposal history is forward only, so every month before you connect is data you cannot get back. A demo is a person walking your own scanners and filters with you, then handing you a key. Thirty minutes, and you can bring the code you have already written.