Upwork Application Session
SkillWeb & browsingUse when the user wants to search Upwork, qualify roles, draft proposals, submit applications, or continue an active Upwork application session. This skill uses a Chrome CDP workflow, payload JSON files, sequential browser actions, connect-budget tracking, and final success confirmation through Upwork proposal URLs.
Use Upwork Application Session in Claude, ChatGPT or Ahel Desktop
Free. Sign in, add Upwork Application Session and connect your AI. About a minute.
Also: Claude Code · Cursor · Codex
Then ask your AI: use the Upwork Application Session skill
Details
Instructions available. Your AI can read the instructions. Execution depends on the setup they require.
Account requirements not reviewed. Check the skill instructions before use; Ahel provides instructions and does not run this skill.
No other account needed.
Add Ahel to your AI once: Claude, ChatGPT, Cursor, Claude Code or Codex. Then ask it to use this.
What this skill tells your AI
The instructions your AI receives, as published by hashgraph-online/awesome-codex-plugins in plugins/klajdikkolaj/upwork-autopilot/skills/upwork-application-session/SKILL.md and read by Ahel’s review.
Use this skill for real Upwork application work. Prefer the Chrome CDP path. Only use Atlas if JavaScript execution is confirmed to work there.
Read first
- First try
../../config/applicant-profile.local.md - If that file does not exist in the cache copy, fall back to
$HOME/plugins/upwork-autopilot/config/applicant-profile.local.md - If that file does not exist, run
node ../../scripts/setup-applicant-profile.mjs - Then read
../../config/search-profile.local.jsonif it exists - If that file does not exist in the cache copy, fall back to
$HOME/plugins/upwork-autopilot/config/search-profile.local.json - If the local search profile does not exist, use
../../config/search-profile.template.json ../../references/search-strategy.md
Non-negotiables
- Start every cover letter with
Hi, - Tone: friendly, professional, specific, low-fluff.
- Never invent project examples, metrics, portfolio URLs, or domain history.
- Never include email, phone, Telegram, WhatsApp, Calendly, or any off-platform contact detail in a proposal.
- Never attach the CV in this workflow.
- Do not parallelize browser actions against the live Upwork session.
- Stop when available Connects drop below
15. - Skip jobs that are already applied, blocked by hard geography, citizenship, or security constraints, or clearly below the user's floor.
Setup
- Run
../../scripts/bootstrap.shonce from the plugin root. - Ensure the applicant profile exists. If it does not, run
node ../../scripts/setup-applicant-profile.mjs. - Run
../../scripts/launch-controlled-chrome.shby default to reuse the user's normal logged-in Chrome profile. - If the user explicitly wants a clean browser state, run
../../scripts/launch-isolated-chrome.shinstead. - Ask the user to log into Upwork only if the chosen browser mode is not already signed in.
- Run
node ../../scripts/upwork-session-probe.mjsto confirm login state. - Export a log path before submissions, for example:
export UPWORK_AUTOPILOT_LOG=$HOME/.codex/upwork-autopilot/logs/$(date +%F).jsonl
Search and qualification
- List search results:
node ../../scripts/upwork-search-plan.mjs
- A raw keyword is converted into the default filtered Upwork search URL.
- A full Upwork search URL is accepted as-is.
- If
upwork-search-plan.mjsreturns multiple URLs, iterate them sequentially. - To open a result and inspect the full job page:
node ../../scripts/upwork-search-inspect.mjs '<search-url-or-keyword>' detail 0
- To probe the apply flow for a specific job:
node ../../scripts/upwork-apply-probe.mjs '<job-url>'
Apply only if all of these hold:
- the client is payment verified
- the role is technically relevant
- the rate is compatible with the user's floor
- there is no hard location block
- the role is not already applied
- any requested proof, portfolio examples, or niche experience can be answered honestly from the profile or current context
Proposal writing
Create a payload JSON file with apply_patch. The scripts fill fields in DOM order.
{
"textareas": [
"Hi,\n\n..."
],
"inputs": []
}
Rules:
- Before drafting, extract the actual deliverable, stack, client pain point, any written questions, and any request for examples or proof.
- First paragraph: open casually and directly, and name the actual problem or fit in plain language within the first 2 sentences.
- Default structure: 3 to 5 short paragraphs in natural prose, not a bullet-heavy sales pitch.
- Weave relevant experience into the paragraphs instead of defaulting to bullets.
- Use bullets only when the client explicitly asks for list-style answers or when multiple written questions are easier to answer that way.
- Proof section: use relevant project evidence from the profile only when it actually matches the post.
- When the applicant profile includes named project examples, prefer dropping 1 to 3 of the strongest ones naturally into the prose instead of listing every example.
- If the applicant profile includes
Differentiators to mention when relevant, use at most 1 or 2 that genuinely strengthen this specific job. Do not force them into unrelated proposals. - Closing: use the profile's
Preferred closing CTAwhen present, or a close natural variant of it. - If the client asks for project examples, case studies, metrics, URLs, or niche background, answer with the closest truthful match from the profile.
- If the profile does not contain the proof the client is asking for, stop and ask the user for the missing details before submitting. Do not guess.
- Keep the proposal usually around
220to320words unless the page asks multiple written questions. - Answer written questions directly in field order. Do not dodge them with generic sales copy.
- Use conversational phrasing and contractions when natural. Avoid templated buzzwords, generic praise, AI-sounding filler, and overly heavy systems language unless the post clearly calls for it.
- If the applicant profile states tone or structure preferences, follow those over the generic defaults in this file.
- The first line must begin with
Hi,
Submission
Run:
node ../../scripts/upwork-submit-proposal.mjs '<proposal-url>' /abs/path/to/payload.json
Success is confirmed only when the final URL contains ?success.
The submit script:
- fills visible
textareafields in order - fills visible text, url, email, and number inputs in order
- clicks
Submit a proposal - extracts the success URL and proposal ID
- appends a JSONL log entry if
UPWORK_AUTOPILOT_LOGis set
Failure handling
- If the page opens a video interview flow, skip unless the user explicitly wants that path.
- If the apply button is disabled, read the probe output before deciding whether to skip.
- If the form asks for required information that is missing from the profile, stop and ask the user before submitting.
- If
net::ERR_ABORTEDappears, another command touched the same Upwork tab. Resume with single-threaded browser actions only. - If login, CAPTCHA, or 2FA appears, hand control to the user and resume after confirmation.
Signals
- GitHub stars
- 1k
- Forks
- 316
- Last commit
- Oct 2026
Advanced
- Item type
- skill
- Key
upwork-application-session- Source
- github.com/hashgraph-online/awesome-codex-plugins
github.com/hashgraph-online/awesome-codex-plugins
Related picks
Skill · thedaviddias
The pick for JavaScriptmodern-javascript-patterns
Skill · wshobson
The pick for JavaScriptops-whatsapp-biz
Skill · davepoon
The pick for Whatsappconfigure-whatsapp-group
Skill · humalike
The pick for Whatsappimage-to-data
Skill · leoyeai
The pick for Data Extractionagent-browser
Skill · 101-skills
The pick for Data Extraction