Ashesh Srivastava
← home

JobFairy — a job-search copilot that researches every role, tailors the resume, fills the application, and reaches the hiring team

JobFairy is for anyone running a serious job search. You set your filters once — title, seniority, remote or a place, salary — and the system does the grind: it pulls live openings, researches each role, rewrites your resume for it, fills the application with a browser agent, and drafts personalized outreach to the people who will actually read it, sent through Instantly so it lands in the inbox and through Waalaxy on LinkedIn. The sharpest filter is the H-1B one: JobFairy carries five years of US Department of Labor filing data, so H-1B candidates can restrict the whole search to companies with a verified record of sponsoring — a filter inside the system, not the product itself.

Job-search copilotH-1B smart filterAgent researchResume tailoringAgent-filled applicationsEmail + LinkedIn outreachSolo build
Role
Designed, built, and shipped solo.
Timeline
confirm
Status
In beta testing — the multi-user build in these screenshots is live and iterating week to week.
Tech
TypeScript + Next.js · Supabase · Trigger.dev · Railway · research agents with a verifier gate · Browserbase fill agent · python-docx resume tailoring · DOL LCA data pipeline · TheirStack job ingest · Apollo.io, Instantly & Waalaxy outreach.

The problem

This one started at home. My wife holds an H-1B, and I watched the job search eat her evenings for months. Anyone who has hunted for a job knows the loop; her visa just made every lap of it longer. The manual version goes like this:

  1. Open LinkedIn and the job boards. Again. →
  2. Stack the filters and scroll. →
  3. Research each interesting company — does it actually sponsor H-1B? The “visa sponsorship: yes” checkbox is self-reported, the lookup sites carry stale data, and half the time you end up with partial information and no answer. →
  4. Rewrite the resume for the role. There goes the evening. →
  5. Fill the application form by hand, field by field. →
  6. Hunt down the hiring manager and write something personal. →
  7. Send it from a personal Gmail — where cold mail gets flagged fast and sits in spam.

Every step is manual, every step repeats for every single role, and the chain breaks anywhere. JobFairy runs that whole chain as one system — for any job seeker. The H-1B check becomes one filter inside it, answered from government filing data instead of guesswork.

The product, in screenshots

Filters — set once

Preferences hold the whole search: the titles you actually apply to, seniority, years of experience, remote or on-site, employment type, country, how fresh a posting has to be, and target salary. On top of them sits the H-1B sponsor filter — every company downstream carries verified sponsorship filings, not a self-reported checkbox.

JobFairy's Preferences screen: H-1B sponsor chips on top, then job titles, seniority, years of experience, work arrangement, employment type, country, posting age, and target salary filters.
real product — Preferences in the beta build, captured 2026-08-12: the H-1B sponsor filter above the profile filters that drive every scan.

Jobs — everything live, in one place

The Jobs tab is every live opening that matches your preferences across the tracked companies, deduped and freshest first. The beta adds a reveal step — titles come free, and a daily allowance of reveals goes to the ones worth a closer look, which is what keeps per-user data costs sane.

JobFairy's Jobs tab listing 307 matched product-management postings with posted dates and Reveal / Pass actions on each row.
real product — the Jobs tab in beta, captured 2026-08-12: 307 matched postings, Reveal or Pass.

Companies — each with its sponsorship record

The Companies tab carries the H-1B filing history for every company in your search, filterable by filing volume. A company page puts its live jobs on top — and the people who matter underneath.

JobFairy's Companies tab: thirteen companies with per-company LCA filing counts, pending/applied/passed job columns, and an LCA min/max filter bar.
real product — Companies in beta, captured 2026-08-12: each company with its LCA filing count, filterable by volume.
A JobFairy company page for RealPage, Inc. showing a verified H-1B sponsor badge with 82 LCAs since 2021, two live product-management openings with salaries, and the top of a 138-person key-decision-makers list.
real product — a company page, captured 2026-08-12: the verified “H-1B sponsor · 82 LCAs since 2021” badge, live jobs with salary, and 138 key decision makers underneath, each one click from a workspace.

Open a job — the homework is already done

Click into a job and the agent research is waiting: what the ideal candidate looks like, company intel, interview intel — every bullet verified and cited before it is allowed to persist. A keyword scan shows what the posting asks for that your resume doesn't say yet, and the resume pane on the right is where tailoring lands: rewords stay fact-anchored, and you accept or reject each change.

A researched job workspace for Product Manager, Billing at Omada Health: the job description and verified agent-research bullets with source links on the left, the resume.docx tailoring pane on the right.
real product — a researched job workspace, captured 2026-08-12: six verified ideal-candidate bullets plus company and interview intel, every one cited; the resume pane sits on the right.
The same job workspace further down: a keyword gap showing 13 posting keywords missing from the resume, the Apply card, and the Fill-application-with-agent section with a provider comparison and a Fill via Browserbase button.
the same workspace, further down — the keyword gap, the Apply card, and the fill agent. The agent fills but never submits: you review, and the application is only marked Applied when a real confirmation email arrives.

People — outreach that lands in the inbox

Even a strong application can sit unread, so JobFairy works the human side too. Pick a person and the agent researches them first, then drafts the outreach: a three-touch email sequence and a LinkedIn note, personalized from cited findings and capped at lengths a human would actually write. Nothing sends without your approval. Email goes out through Instantly — because a personal Gmail blasting cold mail gets flagged within days, and deliverability infrastructure is the difference between an inbox and a spam folder. LinkedIn outreach runs through Waalaxy.

A JobFairy person workspace: cited person-research findings on the left, and on the right a drafted Day 1/4/10 email sequence and a LinkedIn connection note, with Save for later and Schedule send buttons and the line “Nothing sends without your approval.”
real product — a person workspace, captured 2026-08-12: cited person research on the left; the drafted Day 1 / 4 / 10 email sequence and LinkedIn connection note on the right. “Nothing sends without your approval.”

The H-1B data underneath

The filter is built on the US Department of Labor's own LCA disclosure files: 2,630,454 filings distilled to 31,926 companies with at least five filings across the last three fiscal years in tech-adjacent roles. That's the difference between a checkbox that says “sponsors visas” and a public record that proves it.

JobFairy's company list rendering 2,630,454 LCAs across 31,926 companies, with per-company H-1B filing counts for FY2021 through FY2025 and track buttons.
real output — the full asset: “2,630,454 LCAs across 31,926 companies,” per-company filings FY2021–FY2025 (Puppeteer capture from the 2026-07-18 verification pass).

How it's built

TypeScript end to end on Next.js, Supabase for data and auth, Trigger.dev for every long-running job, deployed on Railway. Jobs arrive through TheirStack, which watches the ATS platforms so I don't have to. The research agents run behind a verifier that gates every bullet before it persists. Resume tailoring is the one Python exception — python-docx doing run-level edits inside a Trigger.dev task, because nothing in TypeScript edits a .docx in place without reflowing it.

DOL filings → 31,926 companies → one run per job
How JobFairy runs, end to end
data pipeline — builds the sponsor-company + job assetper-job pipeline — one run per applicationemail corroboration — no agent self-certification
JobFairyNEXT.JS 15 · TS STRICT · RAILWAY · TRIGGER.DEVDOL LCA disclosure files pulled into the sourcing ingestQualified sponsor companies written to Supabase31,926 COMPANIESTheirStack job search results pulled by the ingest taskDeduped postings upserted to SupabaseLIVE POSTINGSA pending posting enters the per-job pipelineNEXT PENDING JOBVerified research feeds the resume tailoring paneThe tailored DOCX artifact is what the fill run attachesA succeeded fill run moves the application to awaitingThe fill run's browser agent fills the live ATS application formFILLS THE LIVE FORMA matched confirmation email promotes awaiting to appliedUS DOL · OFLC — LCA disclosure files · bulk .xlsx downloads · 2,630,454 filingsGOVT FILINGSUS DOL · OFLCLCA disclosure filesbulk .xlsx downloads2,630,454 filingsTheirStack — POST /v1/jobs/search · 28,723-domain rosterJOBS APITheirStackPOST /v1/jobs/search28,723-domain rosterSupabase — Postgres · Auth · Storage · companies · postings · research bullets · fill runs · artifactsDATA · AUTH · FILESSupabasePostgres · Auth · Storagecompanies · postingsresearch bulletsfill runs · artifactsevery stage persists hereGmail API — OAuth inbox read · poll every 15 minCORROBORATIONGmail APIOAuth inbox readpoll every 15 minATS — Workday · Greenhouse · · Lever · more vendorsLIVE ATSATSWorkday · Greenhouse ·Lever · more vendorsthe real application formIngest & qualify — FY files → SAX parse, ≥5 filings across 3 FYs, tech SOC codes (15-12xx)Ingest & qualifyFY files → SAX parse≥5 filings across 3 FYstech SOC codes (15-12xx)Pull jobs — daily 06:00 cron + button, paced blurred queries, dedupe + upsert postingsPull jobsdaily 06:00 cron + buttonpaced blurred queriesdedupe + upsert postingsResearch — 3 agents — ideal → gemini-3.5-flash, company + interview → sonar-pro, verifier gates every bulletResearch — 3 agentsideal → gemini-3.5-flashcompany + interview → sonar-proverifier gates every bulletTailor resume — reword set + fabrication guard, python-docx run-level edits, tailored .docx artifactTailor resumereword set + fabrication guardpython-docx run-level editstailored .docx artifactFill run — startFillRun(posting, provider), Trigger.dev fill task, cost + replay persistedFill runstartFillRun(posting, provider)Trigger.dev fill taskcost + replay persistedConfirm — fill success ⇒ awaiting only, matched email ⇒ applied, agent never self-certifiesConfirmfill success ⇒ awaiting onlymatched email ⇒ appliedagent never self-certifies
Every box maps to the source tree: sourcing and job ingest build the data asset (blue); research, tailoring, the fill run and confirmation run once per application (orange). The dashed arrow is the honesty rule: a succeeded fill only writes awaiting — a matched confirmation email promotes it to applied.

The browser-agent bake-off

The fill step needed a browser agent, so I tested two providers head to head on the same live application — Browser Use and Browserbase + Stagehand — one real run each, through the real fill engine, with cost and step caps in force and every number persisted to the database. Browserbase won because it got the job done: the resume attached in one tool call, while Browser Use burned its entire step cap without ever attaching the file.

One live ATS application · one run per provider
The bake-off, as billed
Browser UseBrowserbase + Stagehand
Cost per task (USD)
$1.1356
$0.0196
Duration
4m 44s
9.3s
Outcome
Browser Use✕ failedhit the 60-step cap · resume never attached
Browserbase + Stagehand✓ succeededresume attached in 1 tool call
Read the multipliers as this run vs this run, not as a rate — one arm ran to its step cap, the other stopped after a single action. Total money that actually left the account: $1.1532.

What I learned

Don't reinvent the wheel. I spent the early weeks building job ingestion the hard way — going ATS by ATS, writing connectors and scrapers against roughly twenty vendors, fighting markup drift and rate limits, because most of them never expose a clean public API. Then I found TheirStack, which already aggregates live postings across the ATS world, and replaced my entire ingestion path with one integration. If someone has already solved the problem, build on top of them — the moat was never going to be the scraping.

Don't let the agent grade its own homework. A fill agent reporting submitted: true is the model's opinion, not a fact — at the API boundary it is indistinguishable from a hallucination. So the system never takes the agent's word: a finished fill run only moves an application to awaiting, and only a matching confirmation email in Gmail promotes it to applied. Any claim an agent makes about the world needs a verification path that doesn't run through the agent.

Beta
JobFairy is in beta testing right now — the multi-user build in these screenshots is live, and the surface changes week to week.