Intelligent Upwork proposal system that monitors job feeds, generates custom proposals via Claude API, and queues them for human approval before sending.
Human-in-the-loop by design — quality over volume.
RSS Feed Monitor → Job Filter → Claude Proposal Generator → Review Queue → Send
- Feed Monitor: Polls 5 Upwork RSS feeds every 30 minutes
- Job Filter: Scores jobs based on budget, keywords, and relevance
- Proposal Generator: Creates custom proposals using Claude API
- Review Queue: Human approves/rejects before sending
- Sender: Exports proposals for manual copy-paste to Upwork
- Backend: FastAPI + SQLite
- Frontend: Single-page HTML/CSS/JS (no build step)
- AI: Anthropic Claude API
- Scheduling: APScheduler (background jobs)
cd /Users/growthgod/.openclaw/workspace/upwork_scripting_app
pip install -r requirements.txtcp .env.example .env
# Edit .env and add your Claude API keyGet your API key from: https://console.anthropic.com/
python -c "from db.database import init_db; init_db()"This creates upwork.db with all tables.
python main.pyThis runs FastAPI on http://localhost:8000
open http://localhost:8000/dashboard/index.htmlOr navigate to the file directly in your browser.
Click "Run Cycle" button in dashboard (or API):
curl -X POST http://localhost:8000/api/run-cycleThis:
- Fetches all 5 RSS feeds
- Filters jobs (budget + keywords)
- Generates proposals for qualifying jobs
Queue tab shows all pending proposals:
- Job title + budget
- Your generated proposal text
- Action buttons
Keyboard shortcuts:
- A: Approve current proposal
- R: Reject current proposal
Click "Export" → exports approved proposals to /exports/YYYY-MM-DD/ folder
Each file contains:
- Job URL
- Proposal text (copy-paste ready)
- Budget & description for reference
To submit:
- Open the job URL
- Copy proposal text from export file
- Paste into Upwork's proposal form
- Submit
Edit config.py to customize:
Budget Filters (minimum thresholds):
BUDGET_FILTERS = {
"fixed_min": 150, # Minimum fixed price
"hourly_min": 25, # Minimum hourly rate
}Keyword Filtering:
KEYWORD_BLACKLIST = [
"wordpress theme",
"logo design",
"full-time",
]
KEYWORD_WHITELIST = [
"automation",
"python",
"api",
"scraping",
]Daily Limit:
LIMITS = {
"max_proposals_per_day": 20,
"poll_interval_minutes": 30,
}| Method | Endpoint | Purpose |
|---|---|---|
POST |
/api/run-cycle |
Trigger fetch + filter + generate |
GET |
/api/queue |
List pending proposals |
GET |
/api/jobs |
List all jobs |
POST |
/api/proposal/{id}/approve |
Approve a proposal |
POST |
/api/proposal/{id}/reject |
Reject a proposal |
PUT |
/api/proposal/{id} |
Edit proposal text |
GET |
/api/stats |
Dashboard statistics |
POST |
/api/export-approved |
Export approved proposals |
id— Upwork job ID (unique)title,description,budget,categoryurl,posted_at,fetched_atstatus— new | filtered_out | pending_proposal | proposal_ready
id— Auto-incrementjob_id— FK to jobsproposal_text— Your generated proposalstatus— pending | approved | rejected | sentgenerated_at,approved_at,sent_at
- Tracks each feed poll cycle
- New job count, duplicates, errors
Claude generates proposals with:
- Custom opening — References specific job details (not generic)
- Relevant experience — Mentions your automation platform background
- Specific question — Engages client about project details
- Concise — Under 200 words (clients don't read walls of text)
- Professional tone — Confident, direct, no fluff
Example generated proposal:
I see you need a Zapier workflow to sync leads between your CRM and email list —
I built an Instagram automation system that handles exactly this type of data
pipeline across 200+ accounts.
I can set this up in 1-2 days. What's your current lead volume, and do you need
any custom field mapping?
| Metric | Target |
|---|---|
| Proposals/day | 10 |
| Response rate | 10-15% |
| Close rate | 30-40% of responses |
| Avg project | $400 |
| Projects/week | 1-2 |
| Monthly revenue | $2,000-4,000 |
Ramp:
- Month 1: Test filters, optimize proposal tone
- Month 2: Build case studies from wins
- Month 3: Raise rates to $75-100/hr
- Month 4: Target $5-8K/month
- Playwright auto-fill for proposal submission (browser bot)
- Slack notifications for high-score jobs
- Multi-profile support (run for clients)
- Feedback loop: track which proposals get responses
- Category performance analytics
- Proposal opening effectiveness scoring
- Automated profile optimizer
- Multi-user dashboard
- Sell access to other freelancers at $49/month
- Revenue model: $5-10K/month
SQLite is blocking concurrent writes. Ensure only one API instance is running.
Check:
- Database is initialized
.envhas validCLAUDE_API_KEY- Jobs exist with status =
pending_proposal - Claude API account has credits
Check browser console (F12) for errors. Ensure backend is running on :8000.
upwork_scripting_app/
├── main.py # FastAPI backend
├── config.py # Configuration
├── requirements.txt # Dependencies
├── .env.example # Environment template
├── db/
│ ├── schema.sql # Database schema
│ └── database.py # DB helpers
├── modules/
│ ├── feed_monitor.py # RSS feed polling
│ ├── job_filter.py # Job filtering & scoring
│ ├── proposal_generator.py # Claude API integration
│ └── sender.py # Export proposals
├── dashboard/
│ └── index.html # React-less dashboard
├── exports/ # Approved proposals (auto-created)
└── upwork.db # SQLite database (auto-created)
MIT — Use for your own freelancing operations.
Built by Sp3ct3R for The Architect.