HR & People pack
Candidates CSV import API
Import a recruiting pipeline from any CSV. Email and phone validated, stage enum-bounded, multilingual headers handled at zero cost.
curl -X POST https://api.adaptivmapr.com/v1/uploads \
-H "Authorization: Bearer $ADAPTIVMAPR_API_KEY" \
-F "template=candidates_v1" \
-F "file=@your_data.csv"Canonical columns
The whole schema, printed as it ships.
Every canonical column, 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. This is the shipped definition, not a summary of it.
candidates_v1- fields
- 7
- required
- 2
- validated
- 2
- hints
- 34
| Canonical column | Type | Required | Validators | Header hints the cascade matches |
|---|---|---|---|---|
candidate_id | string | yes | — | bewerbernummeridentifiant candidatid candidatocandidate idid de candidato |
full_name | string | yes | — | namenom completnome completofull namenombre completo |
email | — | email | emaile-mailmailcorreocourriel | |
phone | phone | — | phone | telefontéléphonetelefonophoneteléfono |
role | string | — | — | stelleposteruolorolepuesto |
stage | enumappliedscreeninginterviewofferhiredrejected | — | — | phaseétapefasestageetapa |
source | string | — | — | quellesourcefontefuente |
Read the same definition as JSON at GET /v1/templates/candidates_v1. A hint match resolves on layer 2 — no LLM call, no token spend, just the flat per-map fee. Hover a validator id to see what it checks.
- 7 canonical fields
- 2 required
- 2 validated
- 34 header hints, 5 languages
Why it exists
Written for the file you actually receive.
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 & the foreign headers they ship
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.
The cascade
Six layers, and the cheapest one wins.
Layers run in order and stop the moment a column resolves. That is the single biggest cost lever in the system: a column caught on layer 2 never reaches the metered layer 5.
- L1Statisticsno LLM
Auto-accepts a header that past confirmations already resolved the same way, at {minN:100, minRatio:0.95} or {minN:20, minRatio:1.00}.
- L2Heuristicno LLM
Normalises accents, punctuation and whitespace, then compares against the column name, the label, and every registered hint (DE / FR / IT / EN / ES).
- L3Fuzzyno LLM
Token-set ratio plus Levenshtein over the normalised strings. Auto-accepts at 0.80 — it absorbs typos and reordered words.
- L4Semanticcheap, cached
Embedding cosine between the header and the field’s label + hints. Catches the long tail of paraphrases.
- L5LLMmetered
Everything still unresolved goes up in ONE batched, collision-aware call, constrained to this template’s column set so it cannot invent a field.
Try it
One template id, two ways in.
REST for your import pipeline, MCP for your editor. Both run the same cascade and both honour the same schema-only clamp.
REST · POST /v1/uploads
Name the template; the cascade picks up the rest. The canonical definition is read-only at GET /v1/templates/candidates_v1.
curl -X POST https://api.adaptivmapr.com/v1/uploads \
-H "Authorization: Bearer $ADAPTIVMAPR_API_KEY" \
-F "template=candidates_v1" \
-F "file=@your_data.csv"MCP · Cursor / Claude Desktop
Drop AdaptivMapr into your editor and call the same cascade as a tool. Schema-only calls leave only column names and up to three clamped sample rows.
// In Cursor or Claude Desktop with the AdaptivMapr MCP server installed:
adaptivmapr.match_headers({
template_id: "candidates_v1",
headers: ["candidate_id", "full_name", "email", "phone"]
})The mappings response comes back flagged. PATCH /uploads/:id/mappings returns requires_hitl: true and hitl_status: "pending_review" so you can hold the commit in your own workflow — the flag is a signal, not a queue we run. Schema-only mode (headers plus at most three sample rows, each clamped to 80 characters) is a data-minimization mode enforced at the HTTP edge. Full-data mode routes the metered layer-5 call to phi-cloud in-region under a BAA, costs 20% more on the whole map charge, and stays locked until the workspace accepts the BAA/NDA in Settings → Security & Data.
Questions
Candidates CSV import — FAQ
Can I extend the stage enum for a custom hiring process?
Is the phone number normalised to E.164?
How is candidate PII protected during mapping?
Why are role and source free text instead of enums?
Map candidates in production — without shipping raw records.
Schema-only mode leaves only headers and a handful of clamped samples. Add full-data when you need row-level AI, routed in-region under a BAA.