Skip to main content
DoneThat

AI Adoption GuideHRSource

ATS candidate rediscovery

Re-ranks past applicants in the existing ATS against new requisitions using embedding similarity.

HR processPlanSourceSelectHireOnboardDevelopRewardExit

By Don, DoneThat’s AI coach · updated

Load the past application and the new requisition as citeable records

Rediscovery is useful only when both sides are ATS records you can point to. Load the candidate's stored application: resume text, questionnaire answers, stage history, source, timestamps, and recruiter notes already used for matching. Load the new requisition: must-haves, location, seniority, team, and hiring-manager notes. Rank after those two objects exist. Do not rank from a sourcer's memory of someone similar last year.

Greenhouse, Lever, Ashby, and Workday all keep applications against jobs. Treat the ATS you already run as the system of record. Do not stand up a second candidate index from a careers-page scrape. If the person applied, the application is in the ATS. If they never applied, they are out of scope for rediscovery and belong in multi-source semantic candidate search.

Run structured gates before similarity. Work authorization, location, license, and clearance are ATS fields. Similarity answers whether this past application looks like this new job. It does not answer whether the person is allowed to do the job.

When the application is a name, an email, and a PDF that never parsed, stop. Do not fill the gap from a public profile. Empty stays empty.

Rank only what you can cite on both sides

The output a recruiter can use is an ordered list of past applicants. Each kept row cites the past application (job title, requisition id, date, stage reached) and the new requisition (job title, requisition id, the requirement language that drove the overlap), plus the passages that actually overlapped.

A row that cannot name the application is not a match. Returning "strong fit" with no application id is the first failure mode. It looks like a shortlist and it is the fastest way to lose recruiter trust. Discard the row.

Do not invent a fit score as a measured percent. Rank is an ordering, not a quality KPI and not a conversion figure. Labeling the row with a percent match implies you measured something you did not measure. Show rank position and the cites. If you need a second, evidence-backed pass on resume quality against the new req, run structured resume scoring as its own step, not as a fake percentage on this list.

Here is the shape of a real pass, not a scored case. A recruiting-ops lead opens a Staff backend requisition for payments, NYC or remote-US. The ATS still holds closed applications for nearby titles. One returned row is a Senior backend applicant from a cancelled fintech requisition. The cite is last March's application, stage onsite, notes that mentioned card-processing APIs, set against the new req's payments and staff-level ownership lines. The recruiter reads those notes, sees the person withdrew after hiring paused, and decides to email. A second row has no application id and a paraphrase of a public headline. That row is dropped. A third row is an intern apply with two sentences in the resume field. The match stays blank rather than guessed.

Thin ATS rows stay blank

Leave the match empty when the ATS row is too thin to cite. Thin rows include applications with no resume attached, parser failures, agency name-only submissions, and quick-apply records that captured contact fields and nothing else.

If you cannot cite a passage from the stored application against a passage from the new requisition, do not emit a match. A short list with cites is the quality outcome. A long list of nameless likely fits is the quality failure.

Do not backfill from career-site chat, from a CRM note outside the ATS, or from an outreach draft. Those are other workflows. A conversational career site agent may collect a new inbound later. It does not complete last year's empty application.

In the recruiter UI, show insufficient application text rather than a low rank. A low rank still looks like a decision. A blank does not.

The recruiter contacts; the rank does not send

The rank is a reading order. Treating it as a send is the second failure mode. Auto-emailing rediscovered applicants turns a quality workflow into a reputation problem. People who applied a year ago did not agree to a blast for a different job. Some now work at customers. Some declined an offer. Some asked not to be contacted.

The recruiter who owns the requisition, or the recruiting-ops lead reviewing the pass, still decides: whether the cite is real, whether the person is still eligible, and whether to contact, with context that names the old application and the new job. The ATS email may be stale. That is another reason a human opens the record before anything leaves the building.

If you generate outreach after that decision, keep it a separate, human-triggered step such as a personalized outreach sequence generator. Do not wire rank position to an email send.

Write the decision back on the ATS person or application: contacted; skipped because the record was thin; skipped for location; skipped for do-not-contact. That log is what you audit. You do not audit a similarity score.

Keep the live ATS as the system of record

Run rediscovery against the ATS you operate, not a shadow spreadsheet. Greenhouse, Lever, Ashby, and Workday differ in how they expose applications, custom fields, and activity. The operating rule is the same: read applications and requisitions from that system, and write the shortlist and the recruiter decision back using a tag, pool, note, or related-job link the product already supports. Do not invent a capability for any of them.

Scope the text you embed to fields recruiting already uses for matching: resume, application answers, structured skills, public notes. Exclude compensation, diversity questionnaires, and anything collected for another purpose. A sourcer who cannot see offer letters should not see them inside a match snippet.

The same person may have three applications. Rank applications, then collapse to a person with the best-cited application visible. Do not triple-contact.

Rejection reason is a recruiter gate, not an embedding feature. If the stored reason was ineligible for US work and the new req is US-only, filter before you rank.

Inspect a sample with the req owner before you call it live

Before the shortlist is treated as production, sit with the requisition owner and walk a sample:

Every kept row cites an application and the new requisition. Rows that do not are defects, not lower confidence.

Thin ATS rows are blank, not paraphrased from somewhere else.

No auto-send is attached to rank.

No percent fit is displayed as if it were measured.

Structured must-haves ran before similarity.

Decisions are written back so the next requisition does not rediscover someone who just said no.

If those hold, you have the quality outcome: a match that names the past application and the new requisition, a blank where the ATS row could not support a cite, and a recruiter who still decides to contact.

Is this worth automating for you?

Whether this pays back depends on how much time it takes your team today. Most teams estimate that from memory, and the estimate is usually wrong in one direction or the other.

DoneThat reconstructs where the time actually went, with no timers to forget, so you can measure the baseline before committing to a project and check the gain afterward.

Measure the baseline first