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.
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.
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:
lead, more scraping will only bury the good ones.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.
yourname@engineered.works. When the docs say "use
your alias", they mean "use that email address instead of your personal
one". Full explainer at /alias.
+something inside it, like
reply+42@engineered.works. The app uses that extra tag to
know which card a reply belongs to. Explained on /alias.
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.
yourname@engineered.works). Pick one you are happy with
before you use it anywhere. ⚠ Do not rename it later — the
old address stops routing replies the moment you change it.
You get one profile for now. Multi-profile (say backend + data analyst for the same person) is planned but not shipped yet.
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.
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.
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:
scraping — how many jobs each source returnedquality_filter — which jobs got dropped and why (KYC, compliance, nationality-only, etc.)location_filter — jobs dropped because the location did not matchllm_filter — each job's yes/no AI verdictpersisting — survivors being saved into your triage queueapollo_search — contacts found per companyapplication — triage cards created for you to reviewIf 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.
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:
lead → shortlisted → applied →
in_conversation → interview → rejected
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).
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.
The app tries to be useful without being annoying. You'll get two kinds of automated email at your real inbox:
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.
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).
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.
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.
Every run goes through seven phases, logged live on the run detail page:
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.
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.
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.
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.
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.
/admin gives you everything in one page:
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.
rejected first if that is the honest final state,
then archive them — one card, one column, or the whole board.
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.