Build Your Own Upwork Tools: API Quickstart
Upwork's official API is closed to individual freelancers — who actually gets access is a short list you're probably not on. The practical substitute is the Vibeworker API: every Upwork job, parsed and scored by AI, queryable within seconds of going live. The free tier is 100 results a day with no card, which is enough to build and run a personal tool indefinitely.
This post goes from zero to a working script, then two tool ideas with tested starter code. Everything below was run against the live API before publishing.
Get a key and make your first request
Sign up free, then generate a key under Settings → Developer. Your first request:
curl "https://kttkatrmvlzsepgprqqd.supabase.co/functions/v1/public-jobs?jobType=fixed&minQuickWin=7&sort=quick_win&limit=3" \
-H "Authorization: Bearer vw_your_key"
The response is { "data": [...], "count": N } — plus quotaRemaining on free accounts. Each job comes fully parsed: title, description, budget, skills, client history (spend, hire rate, rating, payment verification), the Upwork URL, and the part you can't get anywhere else:
"scores": {
"quickWin": 8,
"scopeClarity": 9,
"redFlags": 10,
"effortHours": 14
}
The filters that matter: keywords, category, jobType, experienceLevel, minBudget, minQuickWin, sort, and limit. One behavior worth knowing: keywords is a partial title match, so react will also catch "reaction video" gigs — combine it with category=Web Development when you want precision. The API reference has the full parameter list and supported categories.
The scores are the point
Any job feed gives you titles and budgets. The four score fields are computed by an LLM the moment each job is ingested, which means your tool inherits the judgment without running its own AI pass: quickWin (clear, bounded, finishable in a session), scopeClarity (vague brief detection), redFlags (10 is a clean client), and effortHours (realistic time estimate). minQuickWin=8 with sort=quick_win is a one-request deal-finder.
Tool 1: a deal-finder cron (Node)
Prints new high-score jobs since the last run. No dependencies — save and run with any recent Node:
// deal-finder.mjs
import { readFile, writeFile } from 'node:fs/promises';
const ENDPOINT = 'https://kttkatrmvlzsepgprqqd.supabase.co/functions/v1/public-jobs';
const KEY = process.env.VIBEWORKER_API_KEY;
const seen = new Set(JSON.parse(await readFile('seen.json', 'utf8').catch(() => '[]')));
const params = new URLSearchParams({
jobType: 'fixed',
minQuickWin: '8',
sort: 'newest',
limit: '50',
});
const res = await fetch(`${ENDPOINT}?${params}`, {
headers: { Authorization: `Bearer ${KEY}` },
});
const { data, quotaRemaining } = await res.json();
for (const job of data.filter((j) => !seen.has(j.id))) {
console.log(`[${job.scores.quickWin}/10] $${job.budget} — ${job.title}`);
console.log(` ~${job.scores.effortHours}h · red flags ${job.scores.redFlags}/10`);
console.log(` ${job.upworkUrl}\n`);
seen.add(job.id);
}
await writeFile('seen.json', JSON.stringify([...seen]));
if (quotaRemaining !== undefined) console.log(`quota remaining today: ${quotaRemaining}`);
Real output from the run before this post went up:
[10/10] $50 — Quickbooks Desktop Assistance
~1h · red flags 10/10
[8/10] $30 — Need 2 new fields adding to Salesforce Lead/Contact
~2h · red flags 9/10
Put it on a cron every few hours. The seen.json dedup means each run only shows you what's new — three runs a day at limit=30 stays inside the free quota with room to spare.
Tool 2: an implied-rate screener (Python)
Here's an idea that's only possible because effort estimates exist in the data: divide a fixed price by the estimated hours and you get the implied hourly rate — what the job actually pays, regardless of what the budget looks like. We've written about why effective rate beats sticker price; this makes it executable. Standard library only, no pip install:
import json, os, urllib.parse, urllib.request
params = urllib.parse.urlencode({"jobType": "fixed", "minBudget": 200, "limit": 50})
req = urllib.request.Request(
f"https://kttkatrmvlzsepgprqqd.supabase.co/functions/v1/public-jobs?{params}",
headers={"Authorization": f"Bearer {os.environ['VIBEWORKER_API_KEY']}"},
)
with urllib.request.urlopen(req) as res:
jobs = json.load(res)["data"]
for job in jobs:
if not job["budget"] or not job["scores"]["effortHours"]:
continue
rate = job["budget"] / job["scores"]["effortHours"]
if rate >= 50:
print(f"${rate:.0f}/h implied — {job['title']}")
Sample of what it surfaced on a live run:
$300/h implied — US-based SaaS acquisition lawyer needed for APA review
$94/h implied — Full-Time AI Video Editor for E-commerce
$65/h implied — Book Cover Designer & Print Production Specialist
A $1,500 job estimated at 60 hours and a $300 job estimated at 3 hours are very different propositions — this screener makes the second kind jump out.
Pull vs push
Everything above polls. If you'd rather have jobs pushed to you the moment they match — no cron, no quota math — that's what webhooks are for: enable the Webhook channel on any filter and Vibeworker POSTs the full scored payload to your endpoint in real time. We have ready-made recipes for Slack and Discord, and the Apify actor covers scheduled runs with CSV export if you'd rather not host anything.
Limits and an open invitation
Free: 100 results per day per account (not per key), resetting midnight UTC. Pro: unlimited, plus webhooks.
Building something with this? Email me at mike@voyagerappstudio.com — the API grows in the direction people actually build. And if you'd rather I build it for you, that's a gig I'll take; I freelance too.
Query live, scored Upwork job data and build the tool you wish existed. Get a free API key →

Michael Watkins
Founder of Vibeworker. Helping freelancers win the Upwork game through speed and data.
Stop missing the jobs that matter
Vibeworker watches the Upwork feed and alerts you the moment a high-fit job appears — before the proposals pile up.
Start free trial →Keep reading
Vibeworker Webhook Quickstart: Real-Time Upwork Job Alerts
Set up Vibeworker webhooks in under five minutes. Full payload reference, security guide, and copy-paste receiver examples for n8n, Cloudflare Workers, Zapier, and curl.
5 Upwork Automations You Can Build This Weekend
Five practical Upwork automations — Slack and Discord job alerts, an n8n filtering bot, a deal-finder script, and a personal market tracker — each buildable in under an hour, with guides and tested starter code.
An Upwork Scraper With AI Scores Built In (Apify Actor)
Skip building your own Upwork scraper. This Apify actor returns fresh Upwork job listings with AI quality scores — quick-win, scope clarity, and red-flag ratings on every result. Free tier included.