How this works

Read this top to bottom once. After that you will know exactly where every piece of the app lives and why it is there. Written in plain English on purpose — no jargon, no fluff.

The 10-second version
  1. The app scrapes job boards for you on a schedule.
  2. An AI filter that has read your CV keeps only the jobs that match you.
  3. For every survivor, Apollo finds the real humans at that company (hiring managers, founders, recruiters).
  4. Survivors land in triage on your board with a short AI brief so you can accept or reject each one in a few seconds.
  5. When a company replies to one of your applications, the app reads the reply and moves the card for you — interview, rejection, or "we're still talking".

You set it up once on /me, /profile, and /pipeline. After that the scraper runs on its own, new companies show up in triage on your board, and you work down the list.

The one idea that matters: volume × focus

Most job-search tools push you to apply to as many jobs as possible. This one pushes you the other way: fewer, better applications. Scraping is cheap. Your attention is not. The filters exist so that when a card lands on your board, it is worth reading.

The balance you want:

Every reminder banner you see across the app (on the board, on /scraper, on /pipeline) is nudging you back toward this balance. They exist so you do not drown in 300 unreviewed companies.

Quick glossary for the few technical words you will see
Step 1 — tell the app about yourself

Two pages to fill before you start. Both take about five minutes each.

/me — your reusable facts.

Name, phone, city, LinkedIn, GitHub, target role, target salary, and a short pitch paragraph. None of this is sent anywhere automatically — it is here so you do not have to hunt for it every time you write a cold email or fill in an application form.

/profile — your scraper identity.

You get one profile for now. Multi-profile (say backend + data analyst for the same person) is planned but not shipped yet.

Step 2 — tune the scraper

Go to /pipeline. The page is split into four stages, in the order the scraper runs them.

One rule makes the whole page easy: pick from the shipped list first, type only what is missing. For every list field, the left side is a set of curated checkboxes and the right side is a "not in the list?" box. You never have to guess what format the app wants.

  1. Scrape. What to search for and where. Search term, locations, which job boards (Indeed, LinkedIn, Google), how many results per board, max posting age, and the Indeed country hint.
  2. Location filter. After scraping, drop any job whose location doesn't match your allowed list. Leave it empty to turn this filter off.
  3. AI relevance filter. An AI model reads each job and decides whether it fits you. Your CV is automatically fed in as context. Use the prompt builder to compose region + role track + seniority, or turn the filter off entirely.
  4. Apollo contact search. For each surviving company, Apollo looks up the people you pick (CTO, hiring manager, founder, etc.) in the regions you allow. Paid email reveals happen later, one card at a time.

What each field actually means in plain language:

Each stage has its own "Save stage" and "Reset this stage to profile preset" buttons. There is also a raw JSON editor at the bottom if you ever need to poke at the stored config directly.

The profile preset at the top of the page applies to all four stages at once. Pick it when you are starting fresh, then tune individual stages.

Step 3 — run the scraper

Go to /scraper and click Run now. Your config and your cap are the only things that matter — runs are scoped to your profile.

Click any run in the history to see its phased log:

If you turned the scheduler on in /profile, all of this happens on its own at the cadence you picked. No clicking required.

When a run finishes with zero new cards, it is flagged as needs attention with a short reason — "scraper found 0 raw jobs", "filters dropped everything", or "every survivor matched a card you already had". Admins see the same warning on /admin.

Step 4 — work your board

Your board has two layers:

Triage sits at the top — these are the scraped companies you have not personally picked yet. Below it is the real kanban — the jobs you actively chose to work.

The kanban has six columns, left to right:

leadshortlistedappliedin_conversationinterviewrejected

Scraped companies start in triage. When you promote one it enters lead. Manual adds skip triage and go straight into lead because you already picked them yourself.

You can move any kanban card manually with the / arrows, but most moves happen automatically — see the next section.

Triage cards show: company, job title, location, a short AI brief, and whether a contact was already found. Kanban cards show: company, job title, location, click count (once you have opened the posting), and the latest reply intent (once someone has replied to you).

Step 5 — smart auto-moves (this is the good part)

The board moves cards for you in three situations:

1. You clicked the job posting. Every card title is a tracked link. Clicking it opens a new tab to the real job URL AND bumps the card from lead to shortlisted. The click also shows as a counter on the card. That way your board reflects what you actually looked at, not just what the scraper dumped in.

2. A reply arrived and looks like a rejection. The card moves to rejected. A small reply: rejection badge shows on the card. The full reply is stored and a copy is forwarded to your real inbox.

3. A reply arrived and looks like an interview invite. The card moves to interview. Same storage, same forwarded copy.

Ambiguous replies (neither clearly a rejection nor a clear interview) bump lead, shortlisted or applied forward to in_conversation but stop there. Replies the AI can't match at all land on /replies for you to match by hand.

Non-email replies still count. If a recruiter calls you, messages you on LinkedIn, or tells you something in person, open the card detail page and record it manually. The same reply-intent logic runs and the card can still auto-move.

Guardrail: a card already in interview is never auto-moved to rejected on the next reply — that is ambiguous enough to leave for you to decide. A card already in rejected is never moved at all.

Notifications and check-ins — the feedback loop that pulls you back

The app tries to be useful without being annoying. You'll get two kinds of automated email at your real inbox:

  1. Reply heads-up. When an inbound reply auto-matches one of your cards and the AI is confident it is an interview invite or a rejection, you get one short email telling you what happened, who it is from, and a link straight to the card. The original email is also forwarded to your real inbox as usual, so you can reply to the sender like normal mail. The heads-up is a notification — it is not replyable to the sender.
  2. Daily check-in. Once a day at your local check-in hour, if you have not touched the board in the last 24 hours, the app sends a short status email: triage count, new replies, yesterday's sends. Neutral and unclear replies that did not get an instant heads-up are rolled into this same email so you never miss anything important, but you also never get pinged for noise.

You can turn either stream on or off, change the local hour of day, and set your timezone on your notification settings. There is also a master switch that turns everything off in one click.

If too many automated sends fail in a row (for example because the email provider hiccups), the app will automatically pause your notifications and show a banner on the settings page so you can resume them once things look healthy. This is the self-healing circuit breaker — it is there to protect your inbox from runaway loops.

Your alias email — the one-sentence version

Every profile gets an email address like yourname@engineered.works. Use it as your contact email when you apply to jobs, and when the company writes back the app catches the reply, figures out which card it belongs to, and moves the card for you. The original email also lands in your normal inbox so you can reply like normal mail.

The full walkthrough — how to use it, what happens behind the scenes, how to reply to someone, and a troubleshooting checklist — lives on its own page: /alias. Read that once and you are set.

Two quick rules to remember without clicking: paste your alias into application forms instead of your personal email, and do not rename your alias once you have started using it (the old address stops routing the moment you rename it).

When the app isn't sure which card a reply belongs to

Most replies get matched to a card automatically (see /alias for how that works). But some replies cannot be matched with enough confidence — for example when a company's auto-responder comes from a different domain, or when the reply is so short the AI can't tell which card it relates to.

Those replies land on /replies, your personal inbox inside the app. For each one you see the sender, the subject, the body, and — when the AI had a guess — its best pick pre-selected in a one-click match form. Attach it to the right card, or dismiss it if it was spam or misdirected.

The board shows a counter: "N replies waiting". That is your cue to check /replies before you wonder whether anyone has replied.

Adding a lead the scraper missed

Not every good job shows up in a scrape — some are hidden on company pages, some come from word of mouth, some a friend forwarded you. On your board there's an "Add a lead manually" form at the top:

Manual cards are tagged "manual" on the board and follow every other rule — you can send outreach from them, replies come back to your alias, smart kanban moves them automatically. The only difference is how they got on the board.

What happens during a scraper run — and what "enrichment" means

Every run goes through seven phases, logged live on the run detail page:

  1. building_config — load your profile's settings and presets into the job that is about to run.
  2. scraping — ask LinkedIn, Indeed, and Google for your search term across each location and collect the raw jobs.
  3. quality_filter — drop obvious misfires (KYC, compliance, actuarial, HR-generalist, nationality-only roles) using a plain pattern blocklist. No AI here, just rules.
  4. location_filter — drop jobs whose location does not match any of your allowed locations. Remote-flagged jobs pass when "Remote" is in the list.
  5. llm_filter — send each survivor's title, company and location (plus your CV) to the AI with your prompt. Yes or no. Most jobs get rejected here — that is the point. This is the focusing step.
  6. persisting — save the survivors to your board. The app deduplicates automatically so re-running the same scrape never doubles cards.
  7. apollo_search — for every company that made it this far, ask Apollo "who works here in the titles I care about?". Returns names, titles, LinkedIn profiles, seniority. No emails yet.

Enrichment is a separate step, and it is the one you pay for.

Apollo has two different actions that cost very different amounts:

The split is deliberate: search fills your board with candidates for free, and you only spend money when you actually want to email a specific person. A scraper run that surfaces 50 companies never auto-burns 50 email reveals.

Only the paid reveal step counts against your daily Apollo cap. Search can run as wide as you want.

Running the scraper — single run vs. target run

Two buttons on /scraper:

Target runs can surface many more companies and contacts, but they never spend paid reveal credits on their own. Spend only happens later when you click "Reveal email" on one specific contact.

What "Apollo" means on the banners — and the daily cap

Apollo.io is a contact database. Give it a company name and it returns the people who work there — name, title, LinkedIn, sometimes email. This app uses Apollo to find the right human at every company your scraper surfaces, so you can email an actual hiring manager or founder instead of careers@acme.com.

The cap is for paid email reveals, not for search. Scraper runs can still look up people at a company even when your cap is zero. The only thing the cap protects is the expensive step where you reveal a real email address for one specific person.

Default cap: 50 paid reveals per day. If you need more for a legitimate reason, tell whoever invited you and they can bump it from /admin. The cap resets at midnight UTC every day.

You can see exactly where you stand in three places:

Having 100 leads on the board and 100 contacts visible is fine. The protected step is revealing actual email addresses, not collecting names and titles.

Archiving — one card, one column, or the whole board

Three archive paths, each for a different situation:

Archive one card. Every active card has its own Archive button. Use this when one specific lead does not belong on the live board anymore, but you still want the record for later.

Archive a whole column. Your board has an "Archive a column in bulk" section. Use that when you want to clear an entire status column in one shot — for example a pile of rejected cards, or a batch of old leads you already dealt with.

Archive everything. When you are done with a whole phase of your search (you landed a job, you are taking a break, you want to start over), click "Archive this board" at the bottom of your board. Every active card gets frozen into /archive and your board becomes empty. Run a new scrape, add fresh leads, start clean.

Archived cards are read-only. You cannot change their status, add notes, or send outreach from them. You can still open the original job posting and see the card's full history — that is safe.

Restore an archived card by clicking Restore on /archive. This creates a new lead copy of the card. The original archived row stays put as the audit trail.

The archive page groups cards by month so it stays readable even if you archive things one by one over time.

Sending a cold email from a card

Click any card on your board. On the detail page you will see the company, the contact info, your notes, and a "Compose email" form. Fill in subject and body, then click send. The message goes out from your alias, with reply tracking baked in, and the card automatically flips to applied.

If you're the super admin

/admin gives you everything in one page:

Troubleshooting

Is the app running the latest code? Visit /healthz — it returns the short commit SHA of whatever is live. Visit /version for the full detail: SHA, build timestamp, process start time, uptime, environment, deployment id.

Did my scraper run actually do anything? /scraper lists every run. A run that finished with zero new cards is highlighted as needs attention with a short explanation. Click into it for the phased log.

Why did the AI reject a job I liked? Open the run's phased log, find the llm_filter entry — it shows the exact prompt used. Then go to /pipeline stage 3 and either soften the prompt or switch to a different preset.

Why isn't my CV feeding the AI? The file has to be readable. If /profile shows "no text could be extracted", your PDF is probably an image scan. Re-export it as a text-based PDF, or paste a written summary into /me's "Short bio" field instead.

A reply didn't auto-move a card. Two common reasons: the AI said "unclear" (the wording was ambiguous), or the reply could not be matched to any card at all and went to /replies. Check there first.

The whole app feels stuck. /healthz is your ground truth. If it is green and the SHA matches the latest commit, the app is alive — anything weird after that is config, not deployment.

Don't do these things

Still stuck? Tell me directly. This is a two-person system for now — I can fix things fast when you tell me they are broken.

95902d478db8 · healthz