Candidates CSV import API
candidates_v1
Import this template via API. Import a recruiting pipeline from any CSV. Email and phone validated, stage enum-bounded, multilingual headers handled at zero cost.
30-second curl
curl -X POST https://api.adaptivmapr.com/v1/uploads \ -H "Authorization: Bearer $ADAPTIVMAPR_API_KEY" \ -F "template=candidates_v1" \ -F "file=@your_data.csv"
At a glance
- Pack
- HR & People
- FHIR resource
- —
- Risk level
- medium
- Fields
- 7 (2 required, 2 validated)
Why it exists
Why this template?
The Candidates template is the canonical schema for a recruiting pipeline — the file an ATS export, a job-board download, or an agency long-list reduces to. Each row carries a candidate_id (required), a full_name (required), an optional validated email, an optional validated phone, a role being applied for, a stage enum that walks the applicant through applied → screening → interview → offer → hired → rejected, and a source. Talent and recruiting-ops teams reach for it when migrating between ATS platforms, when bulk-importing an agency or job-fair candidate list, and when consolidating pipelines after a hiring-tool switch. It is `medium` risk because the row is applicant PII — name and contact detail. Schema-only mode is therefore the default ingress: raw candidate records never leave the customer; only headers and clamped sample cells are processed to decide the mapping.
candidate_id and full_name are required. email runs an RFC-style regex; phone is validated as a phone shape (digits, plus sign, separators) but not E.164-normalised — that is downstream. stage lands in {applied, screening, interview, offer, hired, rejected} or surfaces as an error in the dry-run. role and source are free strings because job titles and sourcing channels are too varied to enum-bound. Hints cover DE / FR / IT / ES / EN so a multilingual ATS export does not fall through to the LLM.
Migration scenarios & common foreign headers
Migration scenarios for the Candidates template: porting an active pipeline between ATS platforms (Greenhouse → Lever, Workable → Ashby) so in-flight applicants keep their stage, bulk-importing an agency long-list or a job-fair badge-scan CSV, refreshing a talent-pool list before a hiring push, and consolidating pipelines after a recruiting-tool switch. Foreign headers we see often: "Bewerbernummer / Identifiant candidat / ID candidato / ID de candidato / Name / Nom complet / Nome completo / Nombre completo / E-Mail / Mail / Correo / Courriel / Telefon / Téléphone / Telefono / Teléfono / Stelle / Poste / Ruolo / Puesto / Phase / Étape / Fase / Stage / Etapa / Quelle / Source / Fonte / Fuente". The cascade resolves every one through the registered hints without an LLM call.
Canonical columns
Schema
The canonical column set, with the type each row carries, whether it is required, the field-level validators that fire on commit, and the multilingual header hints the cascade resolves against.
| Column | Type | Required | Validators | Hints |
|---|---|---|---|---|
| candidate_id | string | yes | — | bewerbernummer · identifiant candidat · id candidato · candidate id · id de candidato |
| full_name | string | yes | — | name · nom complet · nome completo · full name · nombre completo |
| — | email · e-mail · mail · correo · courriel | |||
| phone | phone | — | phone | telefon · téléphone · telefono · phone · teléfono |
| role | string | — | — | stelle · poste · ruolo · role · puesto |
| stage | enum | — | — | phase · étape · fase · stage · etapa |
| source | string | — | — | quelle · source · fonte · fuente |
The cascade
How AdaptivMapr maps your headers to this template
Five layers run in order, cheapest first. Layer 1 (Statistics) auto-accepts headers that have been mapped the same way across past uploads. Layer 2 (Heuristic) compares your header to the column name, the optional label, and every registered hint (DE / FR / IT / EN / ES) after a Unicode-and-punctuation-normalising pass. Layer 3 (Fuzzy) catches typos and reordered words. Layer 4 (Semantic) uses cached embeddings to catch the long tail of paraphrases. Layer 5 (LLM) only fires on genuinely ambiguous columns, constrained to the template’s allowed column set so it cannot invent a field. When a layer auto-accepts, the lower-cost layers below it never run — that is the cost lever.
REST · POST /v1/uploads
Pass the template_id; the cascade picks up the rest.
curl -X POST https://api.adaptivmapr.com/v1/uploads \ -H "Authorization: Bearer $ADAPTIVMAPR_API_KEY" \ -F "template=candidates_v1" \ -F "file=@your_data.csv"
The canonical template definition is read-only at GET /v1/templates/candidates_v1.
MCP · Cursor / Claude Desktop
Drop AdaptivMapr into your IDE. Schema-only calls are free and unlimited.
// In Cursor or Claude Desktop with the AdaptivMapr MCP server installed:
adaptivmapr.match_headers({
template: "candidates_v1",
headers: ["candidate_id", "full_name", "email", "phone"]
})MCP install instructions →Questions
FAQ — Candidates CSV import
Can I extend the stage enum for a custom hiring process?
Yes — fork the template and edit enum_values. The canonical set (applied → screening → interview → offer → hired → rejected) is the cross-ATS intersection; custom stages like "take-home" or "onsite" are first-class in the workspace fork.
Is the phone number normalised to E.164?
No — the phone validator checks shape (digits, plus sign, separators) but does not enforce strict E.164. A downstream libphonenumber pass normalises cleanly because the cascade guarantees a parseable shape.
How is candidate PII protected during mapping?
Schema-only mode is the default: only headers and three clamped sample rows (≤80 chars each) are processed to decide the mapping. Full candidate records never leave your environment unless you opt into full-data mode under an active subscription.
Why are role and source free text instead of enums?
Job titles and sourcing channels vary too widely to enum-bound without breaking imports. The canonical row keeps them as strings; teams that want a controlled vocabulary normalise them downstream against their own taxonomy.