Employees CSV import API

employees_v1

high8 fields · 2 required · 3 validatedPack · HR & People

Import this template via API. Import an employee master CSV with email, national ID, and IBAN validation. PII-aware 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=employees_v1" \
  -F "file=@your_data.csv"
phi-cloud bundle required for full-data mode on this template. Schema-only mode (headers + ≤3 sample rows) is free and always available. Activate the bundle →

At a glance

Pack
HR & People
FHIR resource
Risk level
high
Fields
8 (2 required, 3 validated)

Why it exists

Why this template?

The Employees template is the canonical schema for an HR master record — the file an HRIS export, a payroll-system rollover, or a hand-assembled onboarding spreadsheet reduces to. Each row carries an employee_id (required), a legal_name (required), an optional validated email, an optional national_id, an optional IBAN, a hire_date parsed across locales, a department, and a status enum (active / terminated / on_leave). HR and people-ops teams reach for it when migrating between HRIS platforms, when onboarding a newly acquired company's headcount, and when running the daily delta from a system of record into a downstream tool. It is `high` risk because the row is employee PII — name, national ID, and bank detail. Schema-only mode is therefore the default ingress: raw employee records never leave the customer; only headers and clamped sample cells are processed to decide the mapping.

employee_id and legal_name are required. email runs an RFC-style regex; national_id is checked against a permissive ^[A-Za-z0-9.-]{4,20}$ shape so an AHV number, a Steuer-ID, or a codice fiscale all pass; IBAN runs mod-97 with a country restriction (CH, LI, DE, FR, IT, ES). status lands in {active, terminated, on_leave} or surfaces as an error in the dry-run. hire_date auto-detects ISO, US, and EU formats. Hints cover DE / FR / IT / ES / EN so a multilingual HRIS export does not fall through to the LLM.

Migration scenarios & common foreign headers

Migration scenarios for the Employees template: porting a headcount between HRIS platforms (Personio → Workday, Bamboo → HiBob), onboarding an acquired company's employee master into the parent system, running a daily delta from a system of record into provisioning or payroll, and consolidating multi-entity rosters into one directory. Foreign headers we see weekly: "Personalnummer / Matricule / Matricola / Número de empleado / Name / Nom / Nome / Nombre / E-Mail / Mail / Correo / Courriel / Ausweisnummer / AHV / Numéro national / Codice fiscale / DNI / IBAN / Compte / Konto / Eintrittsdatum / Date d'embauche / Data di assunzione / Fecha de contratación / Abteilung / Département / Dipartimento / Departamento / Status / Statut / Stato / Estado". The cascade catches all of these 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.

ColumnTypeRequiredValidatorsHints
employee_idstringyespersonalnummer · matricule · matricola · employee id · número de empleado
legal_namestringyesname · nom · nome · legal name · nombre
emailemailemailemail · e-mail · mail · correo · courriel
national_idstringregex (^[A-Za-z0-9.-]{4,20}$)ausweisnummer · ahv · numéro national · codice fiscale · national id · dni
ibanstringiban (CH, LI, DE, FR, IT, ES)iban · compte · konto · bank account
hire_datedateeintrittsdatum · date d'embauche · data di assunzione · hire date · fecha de contratación
departmentstringabteilung · département · dipartimento · department · departamento
statusenumstatus · statut · stato · estado

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=employees_v1" \
  -F "file=@your_data.csv"

The canonical template definition is read-only at GET /v1/templates/employees_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: "employees_v1",
  headers: ["employee_id", "legal_name", "email", "national_id"]
})
MCP install instructions →

Questions

FAQ — Employees CSV import

Does employee PII leave our environment during mapping?

No. Schema-only mode is the default: only headers and three clamped sample rows (≤80 chars each) are processed to decide the mapping. Full employee records never leave your environment unless you opt into full-data mode under an active subscription.

How does national_id validation work for different countries?

It uses a permissive shape check (^[A-Za-z0-9.-]{4,20}$) so an AHV number, a German Steuer-ID, a French NIR, and an Italian codice fiscale all pass. For a strict per-country format, fork the template and tighten the regex on that field.

What if my employees bank outside the IBAN country list?

Fork the template and broaden the `countries` array on the IBAN validator (default CH / LI / DE / FR / IT / ES). The validator otherwise rejects out-of-list IBANs at import.

How do I handle terminated employees in the same file?

Set status=terminated on those rows — the enum carries it natively. The canonical template captures the current and historical population in one shape; downstream queries filter by status.

Keep exploring

Browse other templates in the HR & People pack