Education & Workforce
Candidate-Job Matching API
Matching is easy to build badly. The difficulty is building one that explains itself, ignores everything it must not consider, and still ranks usefully.
- Job boards
- Applicant tracking vendors
- Staffing firms
- Internal mobility platforms
- Apprenticeship matching services
What your customers would see
example interfaceMockupIllustrative mockup of the interface we would build. Figures shown are examples, not results from a live deployment.
The problem this solves
Recruiters spend most of their time reading. A vacancy attracts two hundred applications, of which perhaps fifteen are worth a conversation, and finding those fifteen is manual work repeated for every role. Matching software exists to compress that, and when it works it genuinely does — shortlisting becomes a review of a ranked list rather than a trawl through a folder.
When it does not work, the failure mode is specific and serious. A model trained on who was hired previously learns who the organisation has historically preferred, which is not the same as who can do the job. University name, postcode, employment gaps, name morphology and years-since-graduation all act as proxies for protected characteristics. A system that optimises for resemblance to past hires will reproduce past exclusion, and it will do so while presenting a confident score.
Regulation has caught up with this. Automated employment decision tools now face specific obligations in several jurisdictions — independent bias audits, published summaries of those audits, candidate notification, and in some cases a right to an explanation or to request human review. That shapes the architecture from the start: the matching has to be feature-transparent, every score has to decompose into stated requirements, and the system must support a human decision rather than make one.
Who buys this
Job boards, Applicant tracking vendors, Staffing firms, Internal mobility platforms, Apprenticeship matching services
What the API returns
What comes back
- Ranked candidate lists per vacancy, and ranked vacancy lists per candidate
- Per-match requirement-by-requirement breakdown showing what was met, partially met and missing
- A plain-language explanation of each match, generated only from the matched requirements
- Transferable-skill reasoning showing which adjacent skills were credited and why
- Explicit gap list a candidate could act on
- Confidence value with the reason for low confidence stated
- Excluded-feature manifest listing what the model was not permitted to see
- Audit record for every scored match, retained for bias auditing and dispute handling
Endpoints
| Method | Path | Returns |
|---|---|---|
| POST | /v1/match/vacancy/{id}/candidates | Rank a candidate pool against one vacancy |
| POST | /v1/match/candidate/{id}/vacancies | Rank open vacancies for one candidate |
| GET | /v1/match/{match_id}/explanation | Full requirement-level explanation for one match |
| POST | /v1/profiles/parse | Extract structured skills and experience from a CV or profile |
| GET | /v1/audit/bias-report | Selection-rate statistics across groups for an audit period |
| POST | /v1/feedback | Record recruiter decisions and outcomes for monitoring |
Request and response
illustrativeRequest
{
"vacancy_id": "vac_9120",
"candidate_pool": "applicants",
"top_n": 20,
"explain": true,
"require_human_review": true
}Response
{
"vacancy_id": "vac_9120",
"title_normalised": "data-engineer",
"scored": 214,
"excluded_features": ["name", "age", "date_of_birth", "photo", "gender",
"nationality", "address", "postcode", "institution_prestige",
"employment_gap_length", "graduation_year"],
"matches": [
{
"match_id": "m_4a19c",
"candidate_id": "cand_41822",
"score": 81,
"confidence": "high",
"requirements": [
{ "requirement": "SQL — intermediate", "status": "met",
"evidence": "assessment scaled 612; 4 years stated use" },
{ "requirement": "Python — working", "status": "met",
"evidence": "stated on profile; 3 projects described" },
{ "requirement": "Airflow or equivalent orchestration", "status": "partial",
"evidence": "Dagster experience credited as adjacent" },
{ "requirement": "dbt", "status": "missing", "evidence": null }
],
"explanation": "Meets the SQL and Python requirements with assessment and stated experience. Orchestration credited from Dagster rather than Airflow. No dbt evidence found.",
"gaps": ["dbt"],
"decision": { "state": "awaiting_human_review", "decided_by": null }
}
],
"notice": "Scores rank candidates for human review. No application is rejected by this API."
}Where the data comes from
| Your vacancy records | Requirements as the employer stated them — the match is against stated requirements, not against a profile of previous hires |
| Candidate profiles and CVs | Held under your own privacy notice and lawful basis; we process what you are permitted to process and no more |
| Occupational and skill taxonomies | ESCO, O*NET or a national framework, which is what lets adjacent skills be credited defensibly |
| Assessment results | Where available, as objective skill evidence rather than self-report — see the Skills Assessment API |
| Recruiter decision feedback | Used to monitor the system and detect drift, deliberately not used as a training target for who should be preferred |
| Voluntary demographic data | Held separately from the matching pipeline, inaccessible to the model, and used only to compute aggregate selection rates for bias auditing |
The intelligence layer
The difference between a demo and a service is mostly in this section. These are the parts that keep the answer trustworthy once real traffic is hitting it.
- Matching against the vacancy's stated requirements, scored requirement by requirement, so the total is a sum of defensible parts rather than an opaque similarity figure
- A hard feature exclusion list covering protected characteristics and their common proxies — name, photo, address, institution prestige, graduation year, employment-gap length — enforced at the pipeline level, not by model convention
- Proxy leakage testing: we train probes that attempt to recover protected attributes from the feature set, and remove features the probes succeed on
- Transferable-skill credit from taxonomy relationships rather than learned from hiring history, which is what keeps adjacency from becoming a prestige channel
- Deliberate avoidance of past-hire outcomes as a training label; the target is requirement satisfaction, because 'resembles who we hired before' is the mechanism by which exclusion is automated
- Explanations generated only from the matched requirement records, validated against them before release, so the text cannot assert a reason the score did not use
- Selection-rate monitoring across groups with four-fifths-rule reporting, run continuously rather than once at launch, and surfaced whether or not the result is flattering
- Full audit logging of inputs, scores and decisions so an independent bias audit can be performed on real traffic and a candidate's explanation request can be answered
What it changes for the business
Shorter shortlisting
Recruiters review a ranked list with reasons attached instead of reading every application end to end.
Defensible process
Requirement-level explanations and continuous selection-rate monitoring give you something to show an auditor or a tribunal.
Wider candidate pool
Crediting transferable skills from a taxonomy surfaces people a keyword filter would have discarded.
Candidate experience
A stated gap list is something an applicant can act on, which is a better outcome than silence.
How it fits into your product
How it embeds
- REST ranking endpoints called from your ATS at shortlist time, with explanations returned in the same payload
- A review state machine that requires a named human decision before any outcome is recorded, so the API cannot be used as an auto-reject
- Candidate-facing explanation endpoint if you want to support a right-to-explanation request directly in your product
- Deployment inside your infrastructure where candidate data must not leave your environment or jurisdiction
- Bias-audit export in a form an independent auditor can work from without bespoke engineering
- Configurable requirement weighting set by the employer, versioned, so a change in weighting is visible in the audit trail
Included in every build
- Authentication, scoped API keys and per-customer rate limiting
- Input validation with predictable, documented error responses
- Versioned endpoints so your integration never breaks without notice
- Request and response logging for audit and dispute resolution
- Latency, error-rate and usage monitoring with alerting
- OpenAPI specification, sandbox environment and client examples
- Backups, failover design and a documented recovery procedure
- An agreed support arrangement once the service is live
How we would build it
about 20 weeksDiscovery and feasibility
Weeks 1–3
This one depends heavily on data access, so we start by proving the sources exist, can be licensed for your use, and actually carry the signal the model needs. If they do not, you find out here.
Architecture and baseline model
Weeks 4–6
A written architecture and a baseline model measured against a holdout period, so you know what accuracy you are buying before the full build starts.
Production build
Weeks 7–16
Data pipelines, model training and serving, historical archive, validation harness, API, security, monitoring and documentation.
Validation and integration
Weeks 17–20
Backtesting against held-out history, accuracy reporting your team can audit, integration support and an agreed retraining cadence.
Commercial models
There is no fixed price list, because the cost is driven by data complexity, integration count, model requirements, request volume and the support level you need. Scope is agreed in writing before development starts.
Fixed-scope prototype
A defined slice of the service, built and priced as one piece of work. The usual first step when the business case needs proving internally.
Fixed-price build
An agreed scope against a written architecture, delivered for an agreed price. Best when the requirements are already clear.
Build then retainer
We build the service, then operate and improve it under a monthly agreement covering monitoring, updates and model maintenance.
White-label product
The service runs under your brand, your domain and your pricing, with MLPivot invisible to your customers.
Questions buyers ask
Will you build an automatic rejection system?
No. We will build ranking, explanation and monitoring; the decision stays with a person. That is partly ethics and partly law — several jurisdictions now regulate automated employment decision tools directly, with bias audit, notice and human-review obligations. A system that rejects applicants on a score, with no human in the loop and no explanation, is the exact thing that regulation targets.
What stops it discriminating?
Several things working together, none sufficient alone. Protected characteristics and their proxies are excluded at the pipeline level. We run probes that try to recover those attributes from the remaining features and strip whatever leaks. The model is not trained on who was hired before, because that label encodes historical preference. And selection rates are monitored across groups continuously, with four-fifths-rule reporting. We would not claim the result is bias-free — we would claim it is measured, and that you will see it when it moves.
Can a candidate ask why they were not shortlisted?
Yes, and the architecture assumes they will. Every match retains its requirement-level breakdown, so the answer is specific: these requirements were met, this one was partially met from adjacent experience, this one had no evidence. Where your jurisdiction grants a right to an explanation or to human review, the audit record is what lets you honour it.
Why not just use embedding similarity between CV and job description?
Because it works well in a demo and badly in an audit. Similarity bundles everything in the document — writing style, institution names, phrasing associated with particular backgrounds — into one number nobody can decompose. You cannot explain it to a candidate, you cannot show an auditor which features drove it, and you cannot tell whether it is measuring skill or class. We use embeddings for skill-term normalisation, not for the ranking decision.
Does more feedback data make it better?
For monitoring, yes. As a training target, deliberately not. Recruiter decisions are exactly the signal that teaches a model to prefer who the organisation already preferred. We keep that data for drift detection and audit, and we would push back if asked to optimise against it.
Related blueprints
Skills Assessment API
Standardised skill tests, scoring and gap analysis delivered as an API your HR or learning platform embeds under its own brand.
Job Market Intelligence API
Structured labour-market signal — salary ranges, skill demand and hiring trends — as a data layer inside your HR, recruitment or education product.
Salary Benchmarking API
Role, level and region specific pay ranges with stated provenance, as a compensation layer inside HR, payroll or recruitment software.
Want this built for your platform?
Tell us what your product does today and what you want another system to be able to ask it. We will come back with an approach, a scope and a price.