How I Built a Job Radar That Checks Careers Pages So Students Don't Have To

Nicolas Dangg
How I Built a Job Radar That Checks Careers Pages So Students Don't Have To

TL;DR

I'm currently a student, and I know the burden of opening Greenhouse, Workday, LinkedIn and multiple companies' careers pages to find an internship where I can learn and grow. On top of that, I'm always scared I won't be up to date with the changes on the ATS portals and careers pages.

So one Tuesday morning, while scrolling X for new ideas and people to connect with, I came across a thread about the TinyFish Student Program. I checked it out, and lucky me: one of its bounties was exactly the problem I'd been facing. I build tools to automate most of the repetitive stuff in my daily life, but I'd never thought about building one for this. That's where the idea for Openings popped up.

Openings is a job radar for students. You tell it the role you want, internship or new grad, up to three cities (remote counts), your class year, whether you need visa sponsorship, and the companies you want to watch.

TinyFish, the web platform for AI agents, goes to the websites, pulls real postings and gives you a ranked shortlist with the term, the pay, the class year they want, whether they sponsor visas and a direct link to apply. I also built a feature I really like: Rescan, which shows what's new since your last scan, so you don't have to remember what you've already read.

It runs on three TinyFish products: TinySearch finds the postings, TinyFetch reads them, and TinyAgent handles the careers portals that only work in a real browser.

What I'm proudest of is that it's honest. Every ranking comes with reasons, every dropped role says why it was dropped, and a posting that never mentions visas is marked "not stated", never "no".

A production scan takes about 28 seconds and returns around 15 ranked matches. Openings won 1st place in Student Bounty Drop 001.

The Openings radar: ranked internship matches with term, pay, visa status and where each result came from
"TinySearch finds the doors, TinyFetch walks through the open ones, TinyAgent picks the locks."

The problem

The jobs are public. They're just scattered, and nothing tells a student what they actually need to know.

  • They're spread across different job systems. One company uses Greenhouse, the next Lever, the next Ashby or Workday, each with its own search box and filters.
  • Some hide their jobs behind JavaScript. A Workday posting that comes back as a 425-character shell to a normal fetch turns out to be 7,600 characters of real posting once it's rendered in a browser.
  • Aggregators are stale. They're full of reposts and closed roles, and they mix internships with senior jobs.
  • The two questions that matter are buried. Can I apply if I graduate in 2027? And will they sponsor my visa? They're somewhere in paragraph nine, if they're there at all.
  • There's no memory. Nothing tells you which postings are new since you last looked, so you end up rereading the same ones every week.

I didn't need another job board. I needed something that goes and checks for me.

What I built

Openings has three screens.

1. A landing page that explains what it does, using real results from my own scans as the illustrations.

2. A four-step onboarding:

  • Role and level (internship or new grad)
  • Where: up to three locations, and "Remote" counts
  • About you: class year, whether you need a visa, skills to boost
  • Companies to watch, and a Deep search switch that lets TinyAgent work on the harder sites

Preferences are saved in your browser: no accounts and nothing to sign up for.

3. The radar, which starts the first scan on its own. It has three tabs:

  • Matches: four tiles (matches, sponsor visas, want your class year, on your watchlist) and a ranked table. Click a row to see a one-line summary, "why it matched" chips, the skills the posting asks for, where the result came from, and an Apply button that goes straight to the real application page.
  • Run log: each stage of the scan ticking off live. When TinyAgent is working, you can watch its browser as it uses a company's careers portal.
  • Filtered out: every role that was dropped, with the reason. For example, "Located in London, England", "Says it won't sponsor visas" or "Targets 2026 graduates; you graduate 2027".

Every scan after the first marks new postings with a New badge, shows "+N new" on the Matches tab and has a New-only filter.

Where TinyFish fit

I used three TinyFish products. TinySearch and TinyFetch are free, so they do the heavy lifting. TinyAgent is metered, so it only runs where nothing else works.

How Openings works: find with TinySearch and TinyFetch, read with TinyFetch and TinyAgent, then rank
Find, read, rank: each TinyFish product has one job.

1. TinySearch: discovery

I don't know every company that's hiring interns, but TinySearch does. Openings runs one plain query per location and level (for example "software engineer intern New York"), restricted with include_domains to the job systems companies actually use: Greenhouse, Lever, Ashby and Workday. That returns around 38 real postings in about 3 seconds, including companies the user never named.

TinySearch also has a second job. When a watchlist company isn't on Greenhouse or Lever, it finds where that company's jobs actually live, so TinyAgent knows which portal to open.

2. TinyFetch: reading

TinyFetch reads in two ways:

  • Postings, 10 per call, in parallel. The page is where the details live: location, pay, term, class years and visa wording.
  • Whole company boards in one call. For the watchlist, TinyFetch reads Greenhouse's board feed and Lever's board page directly. Roblox's whole board, 230 roles, comes back in a single call, and Openings keeps only the titles that match your level and role.

3. TinyAgent: the hard sites

Some careers sites are JavaScript apps (Ashby boards, Workday, custom company sites) where a plain fetch only gets an empty shell. For those, TinyAgent opens the portal in a real browser, types into its search box (for example, "software engineer intern") and returns the postings as JSON. It also reads individual postings that only render in a browser.

TinyFish gives a live view URL for each TinyAgent run, and the Run log shows it, so you can watch the agent work through Notion's board while the scan runs.

A backup for the rare page that still won't render. If a page comes back as a JavaScript shell, a backup scraper retries it before any TinyAgent credit is spent. The read order for a posting is TinyFetch, then the backup, then TinyAgent.

What worked

Four decisions paid off.

1. One job per tool, with cost as a priority

Free TinySearch and TinyFetch do almost everything. TinyAgent only runs on a budget: off by default, at most 2 runs at once, each stopped after 150 seconds, and a slot reserved before a run starts so parallel code can't overspend. Portals get the budget first, then pages that wouldn't render. On the public deploy, deep search needs a passcode, and each visitor gets 6 scans per 10 minutes, so strangers can't spend my TinyAgent credits.

2. Never treating "unknown" as "no"

Most postings never mention visas. Visa status has three states (sponsors, no sponsorship, not stated), and a role is only marked "no sponsorship" when the posting actually says something like "unable to sponsor". The same rule applies to location and graduation year. My first version dropped a Notion internship because it said "graduate before Summer 2028", which actually fits a 2027 grad. That's how I learned to drop a role only when you graduate after the year it mentions.

3. Rules first, LLM on top

Extraction starts with tested regex rules: free, instant and covered by tests built from real posting text. An LLM then corrects and fills in the result: it turns "Capitalone" into "Capital One" and catches "sponsor Visa's if needed", which my regex missed because of the typo. If the LLM fails, gets rate-limited or runs out of credits, the rules result stands and the scan still finishes. To stay within the free tier's rate limit, I batched 5 postings per LLM call, which cut extraction from 105 seconds of retries to 6 to 19 seconds.

4. Filtering before reading, and explaining everything

TinySearch results whose titles are plainly the wrong level ("Senior …", "Director …") and board postings in the wrong city are skipped before they use up a TinyFetch read. In one New York run, that skipped 30 postings, and the freed-up reads raised matches from 11 to 14. After extraction, every job gets a score from 0 to 100, and each point comes with a reason chip. Nothing is dropped silently.

Measurable outcome

From my recorded runs:

WhatResult
TinySearch~38 live postings in ~3 seconds, across Greenhouse, Lever, Ashby and Workday
TinyFetch (boards)Roblox's full board, 230 roles, in one call
TinyFetch (postings)10 postings per call; 15 read per scan by default
TinyAgentSearched Notion's Ashby board and found 3 internships (67 to 105 seconds per portal run)
Deep search scan45 postings found, 15 read, Notion's 3 internships ranked first (score 80), 2 pages rescued by the backup scraper, 2 filtered out with reasons
Production scan~28 seconds, 15 ranked matches, all parsed with the LLM
Filtering before reading30 off-target postings skipped in one New York run; matches went from 11 to 14
FreshnessA rescan 48 minutes later flagged exactly 2 new postings
Build timeAbout 4 hours from the first commit to the deployed app, with 28 tests

These numbers describe specific runs, not a benchmark. I haven't run a controlled time-saving study, but the comparison I care about is simple: what used to be a weekly hour of opening tabs is now one 30-second scan that also tells me what changed.

What I'd do differently

Test each endpoint on real sites before designing around it. I spent most of my time figuring out how each source actually behaves. Combining intern OR internship OR co-op with include_domains returned zero results, while separate plain queries took me from 10 results to 38. Ashby pages put the body in description instead of text. Greenhouse's feed came back in two different formats from the same URL. TinyAgent runs that said "COMPLETED" sometimes hadn't succeeded, so I now ask the agent to return an error field and check for it. I'd write a small spike against every source on day one.

Plan for slow, long-running work from the start. TinyAgent runs took 67, 105 and 145 seconds, not the "about a minute" I first wrote in the UI. I ended up streaming every stage to the browser as NDJSON, and I'd build that in from the beginning.

Parse locations properly. "New York" still matches New York State (one "new" result was a co-op in Rochester, NY). City-level location matching is the next thing I'd fix.

Use a stronger rate limit. My scan limit lives in memory, so it's per server instance. A firewall rule would be the sturdier version.

Advice for other builders

Give each tool one job, and keep it simple. Don't add an endpoint just to say you used it. Ask what TinySearch can do that TinyFetch can't, and what TinyAgent can do that neither can. Then call them cheapest first and save the slow, metered one for when it's the only thing that works.

Have a fallback for every step. Websites will time out, render as empty shells or change format. My rule was that a scan should never fail because one piece did: the LLM falls back to rules, and every page has a next way to be read.

Don't hide anything. Show why something ranked where it did, show what was dropped and why, and say "not stated" when you don't know. For something as important as a job application, people need to trust what they're reading.

Show the agent working. The live view of TinyAgent's browser is the moment people understand what the product does. If your tool gives you that, put it on screen.

Try it

Openings

Build your own

Want an agent that checks the live web for you? Sign up free at agent.tinyfish.ai.

More student builds are in the TinyFish Build Library.

Building as a student? Join the TinyFish Student Program with your school email for $35 in free credits.
AI disclosure

Content on this website may be created or refined with the assistance of AI tools and is subject to human editorial review.

FAQ

Questions, answered.

How does TinyFish power Openings?

Which TinyFish products do you need to build a job or internship finder?

How do you scrape Workday, Ashby and other JavaScript careers pages?

Can TinyFish read a whole Greenhouse or Lever job board in one call?

How do you keep costs down when an AI agent searches job sites?

What is Openings?

Get started

Start building.

No credit card. No setup. Run your first operation in under a minute.

Get $8 in Wallet fundsRead the docs