Healthcare pack
Appointment log CSV import API
Import past appointments from CSV into a FHIR Appointment-shaped schema. Locale-tolerant date parsing.
curl -X POST https://api.adaptivmapr.com/v1/uploads \
-H "Authorization: Bearer $ADAPTIVMAPR_API_KEY" \
-F "template=appointment_log_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.
appointment_log_v1FHIR · Appointment- fields
- 4
- required
- 2
- validated
- 0
- hints
- 9
| Canonical column | Type | Required | Validators | Header hints the cascade matches |
|---|---|---|---|---|
patient_id | string | yes | — | patientpatient_idpid |
start_at | date | yes | — | terminrendez-vouscita |
duration_min | number | — | — | dauerduréeduración |
status | enumbookedarrivedfulfilledcancellednoshow | — | — | matched on the column name |
Read the same definition as JSON at GET /v1/templates/appointment_log_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.
- 4 canonical fields
- 2 required
- 0 validated
- 9 header hints, 5 languages
- FHIR Appointment
Why it exists
Written for the file you actually receive.
The Appointment log template is for past appointments, not future ones — the use case is backfilling an EMR with historical visit data, building a no-show-rate dashboard, or migrating from a vendor that is sunsetting its calendar product. Each row carries a patient_id (foreign key to the demographics table), a start_at timestamp, an optional duration in minutes, and a status from a fixed set (booked / arrived / fulfilled / cancelled / noshow). The template emits FHIR Appointment with the participant slot populated from patient_id. It is `low` risk because past appointments without diagnoses are not PHI in most jurisdictions — though the medium-risk treatment kicks in if you pair this with the demographics template in a full-data pipeline. The cascade picks up Termin, Rendez-vous, Cita, Appuntamento at zero cost.
duration_min is optional because many source systems carry end_at instead — fork the template and derive duration downstream, or leave it null. The status enum reflects FHIR Appointment.status values that make sense for historical data; "proposed" and "pending" are excluded because past appointments are not proposed or pending.
Migration scenarios & the foreign headers they ship
Migration scenarios for the Appointment log: building a no-show-rate dashboard that needs a year of history to be meaningful, EMR backfill where the new system needs the old appointment history to display in the patient timeline, replacing a sunset vendor calendar with a modern alternative, and ad-hoc analytics imports for capacity planning. Foreign headers seen in the wild: "Patient ID / Patientennr / PID / Termin / Rendez-vous / Cita / Appuntamento / Start / Beginn / Heure / Inicio / Dauer / Durée / Duración / Durata / Status / Statut / Stato / Estado". The cascade picks up multilingual time and duration vocabulary at zero cost — appointment data is one of the highest-volume historical imports in healthcare and the heuristic layer carries the bulk of the work without LLM escalation.
The cascade
Five 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/appointment_log_v1.
curl -X POST https://api.adaptivmapr.com/v1/uploads \
-H "Authorization: Bearer $ADAPTIVMAPR_API_KEY" \
-F "template=appointment_log_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: "appointment_log_v1",
headers: ["patient_id", "start_at", "duration_min", "status"]
})Questions
Appointment log CSV import — FAQ
Ready when you are
Map appointment log 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.