# Recruitment funnel metrics: fixed-horizon cohort workbook

Metix AI editorial team, October 26, 2026. The example is entirely synthetic.
This asset runs without Metix, an ATS connection or a network request. Use Python
3 and keep the calculator and example CSV in the same local folder. Inspect the
script before running it. Use pseudonymous IDs; this tool does not need names,
email addresses, resumes or sensitive attributes. Keep the identity mapping in
your own authorized system. The file is not a supported Metix import format.

## Run the worked example

```sh
python3 recruitment-funnel-metrics.py recruitment-funnel-example.csv --role DEMO-ROLE --start 2026-10-01 --end 2026-10-25 --as-of 2026-10-26 --days 14 > results.csv
```

Expected counts: 10 unique contacts in the entry window, 2 immature contacts
withheld, then 8 contacted / 6 replied / 4 interested / 3 booked / 2 held /
1 offered / 1 accepted within fourteen calendar days of each contact. Compare
with recruitment-funnel-expected.csv. P09 already accepted but lacks fourteen
days of observation, so it is withheld along with P10. P02's offer and P03's held
interview happen after their respective deadlines and do not count within day14.

## Field dictionary

Each row is one person-role pair. Record first reached dates, not message,
interview-session or reschedule counts. Required headers:

| Field | Definition |
|---|---|
| person_id | Stable pseudonym for one person across sources. Resolve duplicate identities before export. |
| role_id | Stable opening ID. One person on two roles is two pairs; this calculator filters one role. |
| contacted | First outbound message actually sent for this role, not draft approval or profile discovery. Required. |
| replied | First human reply, including refusal or a question. Delivery notices and auto-replies do not count. |
| interested | First explicit agreement to explore this actual role. A clarification question alone does not count. This is not proof of qualification. |
| booked | First confirmed interview slot, irrespective of later rescheduling. |
| held | First interview that actually took place. A booking or cancellation does not count. |
| offered | First formal offer issued for this role. |
| accepted | First accepted offer for this role. This does not establish an employment start or retained hire. |

Enter ISO dates (YYYY-MM-DD), with every event converted to one documented local
calendar/timezone before export. Blank means no recorded event as of the cutoff,
not a negative outcome. Do not put "unknown" in a date cell. If history is missing,
repair it or describe the missingness; do not treat this calculator as a complete
conversion report. Use your own file name, role, dates and follow-up length.

## Calculation and limitations

Entry dates are inclusive. A pair matures when contacted + days <= as-of. Every
stage uses that pair's same deadline. Dates on the deadline count. A stage event
after the deadline is excluded even if known by the as-of date. This reports
fixed-horizon conversion; it does not estimate eventual conversion, survival,
average time in stage, source attribution or quality of hire. A shorter horizon
will miss more late-stage outcomes. Write the horizon beside every number.
Every clock starts at contact. An offer issued on day13 has only one day left
before this deadline. For acceptance after an offer, use a separate offer-entry
cohort and offer-based follow-up; that is a different question and calculation.

Adjacent rate = people reaching next stage within the horizon / people reaching
the preceding stage within the horizon, restricted to the same mature contact
cohort. Always retain both counts. Contact-to-accepted uses mature contacts as its
denominator. A zero denominator returns unknown, while 0 successes from a known,
nonzero denominator returns 0.0%. A rate of 1/1 is not a stable benchmark.

All input rows are validated, including rows for other roles. Identical repeated
person-role rows are ignored and counted in an audit row. Conflicting duplicate
rows, future events, missing predecessor stages and reverse chronology stop the
calculation. Combine real first-stage dates in your own records first. If your
process legitimately skips stages or starts with inbound applicants, define a
different map; do not invent a reply or interest date to satisfy this one. The
script cannot detect two pseudonyms for one person or verify the underlying events.

Compare cohorts with the same role context, definitions and observation horizon.
Show small counts. A fall in a ratio prompts case review; it is not evidence that
a recruiter, channel or tool caused the change. Pair conversion with elapsed time
and actual hiring evidence before changing selection standards.

More explanation: https://metix.ai/blog/recruitment-funnel-metrics
