Migrating data to & from Mercurie
Move your clinic's clinical records from your current EMR into Mercurie — or keep another system in sync. Mercurie stores everything as standard FHIR R4 resources, so migration runs over a standard API. This guide starts with what you, as an admin, need to do, then gives your IT team or EMR vendor the exact commands.
1. How it works (the short version)
There are three things you might want to do, all over the same API:
- Import — load your existing patients, encounters, problems, medications, labs, and documents into Mercurie.
- Export — pull a copy of everything back out (for a backup, an audit, or to hand a patient their record).
- Sync — keep a downstream system continuously up to date as records change.
As an admin your job is small: create an API keyand give it to whoever runs the migration (your in-house IT or your current EMR vendor). They map your old data to FHIR and run the commands below. You don't need to do anything technical yourself.
2. Step 1 — create an API key
Go to Organization settings → API Keys and click Generate Key. A key is bound to one provider and carries its own permissions — every action it performs is recorded in the audit log as that person, via the key, so access stays transparent.
Pick settings to match the job:
- Acts as — the provider the key represents (usually a clinic admin who is a provider).
- Role · Access = Provider · Read & write — for an import. This can write every clinical resource type.
- Read-only — for ongoing export/sync to another system, so the key can never change records.
- Expiry — optional; set one for a one-off migration so the key auto-disables when you're done.
3. Step 2 — hand it to your integrator
Give your IT team or EMR vendor two things: the API key and this guide. Everything runs against https://www.mercurie.ai(the same host for every organization). Everything below is for them. They'll map your source records to FHIR R4 resource types — patients → Patient, visits → Encounter, problems → Condition, meds → MedicationRequest, and so on — then run the import.
Every request authenticates with just the key as a bearer token — no other headers:
Authorization: Bearer merc_org_<secret>
Quick connectivity check (lists the server's capabilities):
curl -s https://www.mercurie.ai/fhir/R4/metadata \ -H "Authorization: Bearer $KEY"
4. Importing data (commands)
For a large migration use bulk $import— it's asynchronous: you submit the data and poll for progress. It accepts a FHIR Bundle or NDJSON (one resource per line — the same format $export produces).
# Kick off — returns 202 + a status URL in the Content-Location header curl -X POST "https://www.mercurie.ai/fhir/R4/\$import" \ -H "Authorization: Bearer $KEY" \ -H "Content-Type: application/fhir+ndjson" \ --data-binary @patients.ndjson # Poll until status is "completed" curl -s https://www.mercurie.ai/fhir/R4/bulk-import/<id>/status \ -H "Authorization: Bearer $KEY"
The status response reports per-resource succeeded /failed counts and an errors list (with the input index + reason) so you can retry just the failures. Needs a read-write key.
For a small, referentially-linked set that must all land together (or not at all), POST a transaction Bundle instead — it's atomic, and urn:uuid:references between entries resolve automatically:
curl -X POST https://www.mercurie.ai/fhir/R4 \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/fhir+json" \
--data @bundle.json # { "resourceType":"Bundle", "type":"transaction", "entry":[ ... ] }- transaction = all-or-nothing: one bad entry aborts the whole Bundle and nothing is saved.
- batch (and
$import) = per-entry: failures are reported individually; partial progress is kept. - Put a stable identifier (e.g. your old MRN) on each resource so re-runs find-or-create instead of duplicating.
5. Exporting & keeping in sync
Bulk $export mirrors $import — kick off, poll, download NDJSON files:
curl -s "https://www.mercurie.ai/fhir/R4/\$export?_type=Patient,Condition,MedicationRequest" \ -H "Authorization: Bearer $KEY"
To keep another system continuously in sync, poll the change feed with a moving timestamp — it returns everything (including deletes) changed since then:
curl -s "https://www.mercurie.ai/fhir/R4/_history?_since=2026-01-01T00:00:00Z&_type=Patient,Observation" \ -H "Authorization: Bearer $KEY"
For a single patient (e.g. a transfer of care), GET /fhir/R4/Patient/{id}/$everythingreturns their whole chart as one Bundle.
6. Limits & getting help
- Up to 20 active API keys per organization (revoked keys don't count).
- A key only ever reads/writes records within its own organization.
- Keep individual Bundles modest (hundreds, not tens of thousands, of entries); use
$importfor the bulk.