AdaptivMapr

Capability · FHIR

Already mapped. Now emit it as FHIR.

You mapped the file already. Ask for FHIR and the same run hands you R4 resources instead of rows — no second integration.

R4 resource types
14
Not a second product
A flag
Template fields mapped onto FHIR R4 resourcesPatientObservationClaimCoverageone engine

The job

Your data is mapped. The other system wants FHIR.

The registry, the exchange, the partner hospital — they take FHIR R4 and nothing else. Between your mapped rows and their endpoint sits a resource builder somebody has to write and then keep correct as templates change.

What changes

It is a flag on the output, not a product to integrate. Fourteen R4 resource types are built from each template’s own fhir_resource mapping, so when the template changes the resource follows it.

What you get

Not a demo. The thing that runs every day.

Resources

Straight to an R4 Bundle

Resolved rows become FHIR resources wrapped in a collection Bundle, served with the right content type. There is no intermediate transform for you to build and keep in sync.

HowrowsToFhirBundle() in lib/fhir.ts returns { resourceType: "Bundle", type: "collection", entry: [...] }, served as application/fhir+json.

Coverage

Fourteen resource types implemented

Patient, Observation, Medication, Appointment, Coverage, Practitioner, Claim, Claim.item, Encounter, Condition, Immunization, Organization, Location and AllergyIntolerance.

HowSUPPORTED_FHIR_RESOURCES is the whitelist, and it is checked before anything is built — a template pointing at a resource type we have not implemented is refused with fhir_resource_unsupported, naming the type.

Same engine

One cascade, FHIR at the end

You map to the template’s fields exactly as you would for a CSV export. Asking for FHIR is a flag on the output, not a different product.

Howemit() in lib/emit/index.ts treats fhir as one of nine output formats alongside json, csv, tsv, xml, sql, xlsx, xlsm and parquet.

Three doors

From a document, a file, or a commit

Turn an extracted PDF into resources, convert a spreadsheet in one shot, or emit a reviewed upload at commit time. Same output, wherever the rows came from.

Howoutput: "fhir" is accepted on POST /v1/convert, POST /v1/transform and POST /v1/uploads/{id}/commit — and on commit it can be delivered to a webhook rather than returned inline.

Validated

Checked before it is emitted

The codes inside a resource go through the same commit-time validators as any other field, so a malformed code is flagged rather than shipped inside a resource that looks well-formed.

Howloinc_code, icd10_code and fhir_reference run in validateRowsDetailed() before the bundle is assembled. An Observation with an unparseable LOINC code never gets built.

Honest

It refuses rather than invents

Ask for FHIR from a schema that has no resource mapping and you get a specific refusal — never a half-built resource with guessed fields.

How422 fhir_unavailable when the schema declares no fhir_resource, naming the schema. On the commit path the same case is 400 fhir_not_supported.

Reference

The templates that already carry a mapping

For healthcare workloads, mapping to your columns is only half the job — you often need FHIR out the other side. Any template that declares a fhir_resource can emit its resolved rows directly as R4 resources in a Bundle. The emit path itself is vertical-agnostic: it is a general output mode layered on the same cascade, not a walled-off healthcare gate.

  1. 01

    Map to the template

    Nothing special happens here. Your columns land on the template’s fields through the same six-layer cascade a CSV export would use.

  2. 02

    Validate the codes first

    loinc_code, icd10_code and fhir_reference run in the commit-time validator pass BEFORE assembly — an Observation with an unparseable LOINC code never gets built.

  3. 03

    Build against the whitelist

    The template’s fhir_resource is checked against SUPPORTED_FHIR_RESOURCES. A type we have not implemented is refused by name rather than emitted half-built.

  4. 04

    Serve, or deliver

    A collection Bundle served as application/fhir+json — or, from the commit path, POSTed to your webhook HMAC-signed with a deterministic idempotency key.

TemplateFHIR resourceRisk
patient_demographics_v1Patientmedium
lab_results_v1Observationmedium
lab_result_catalog_v1Observationlow
drug_formulary_v1Medicationmedium
claims_line_items_v1Claim.itemmedium
appointment_log_v1Appointmentlow
insurance_contracts_v1Coveragelow
provider_directory_v1Practitionerlow
A custom schema can declare its own fhir_resource, as long as it names one of the fourteen implemented resource types. Medium- and high-risk templates additionally return requires_hitl, so a human can gate the commit.

Try it

A scanned intake form, out as a Patient

Ask for FHIR on a template that carries a resource mapping, and the response is a Bundle instead of flat rows — served as application/fhir+json.

curl
curl https://api.adaptivmapr.com/v1/convert \
  -H "Authorization: Bearer $MAPR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "input":  { "format": "pdf", "data_base64": "JVBERi0xLjcK…" },
    "schema": { "ref": "patient_demographics_v1" },
    "output": "fhir",
    "mode":   "full-data",
    "phi_mode": true
  }'
response
{
  "resourceType": "Bundle",
  "type": "collection",
  "entry": [
    { "resource": {
        "resourceType": "Patient",
        "name":      [{ "given": ["Ada"], "family": "Lovelace" }],
        "birthDate": "1815-12-10",
        "gender":    "female",
        "telecom":   [{ "system": "email", "value": "ada@example.org" }]
    } }
  ]
}
→ application/fhir+json · Bundle/collection · built from patient_demographics_v1
  • The implemented set is Patient, Observation, Medication, Appointment, Coverage, Practitioner, Claim, Claim.item, Encounter, Condition, Immunization, Organization, Location and AllergyIntolerance.
  • FHIR emit is metered like any other map — the flat per-map fee, plus AI tokens only if the cascade actually needed the metered layer to place a column.
  • On the commit path, output: "fhir" can be POSTed to your webhook instead of returned, HMAC-signed and carrying a deterministic idempotency key so a retry is safe to dedupe.

The surface

Every route this page actually has.

FHIR is not its own endpoint. It is one of nine values of `output`, accepted on every surface that produces rows — so the door you already use is the door.

  • POST/v1/convertA document in, a Bundle out — the scanned-intake-form path. Needs the PHI entitlement, because unstructured input is full-data.transform scope
  • POST/v1/transformA spreadsheet or pasted text to a Bundle in one shot, up to 10 000 rows inline.transform scope
  • POST/v1/uploads/{id}/commitEmit a reviewed upload as FHIR — returned inline, or delivered to your webhook instead.commit scope
  • POST/v1/reshapeUntangle a messy workbook first, then emit the clean result as R4 resources.commit scope
  • GET/v1/templatesWhich templates declare a fhir_resource, and which resource type each one builds.no key

Limits & failure modes

What it refuses to do — and the code it says it with.

The whole point of this surface is that it refuses rather than invents. A half-built resource with guessed fields is worse than an error, because it validates downstream and is wrong.

422 fhir_unavailable

The schema you named declares no fhir_resource.

The refusal names the schema. Add a fhir_resource to your own schema — it just has to name one of the fourteen implemented types.

400 fhir_not_supported

The same case, on the commit path.

Two codes because the two planes answer in their own vocabulary; both refuse before anything is built.

fhir_resource_unsupported

A template points at an R4 resource type outside the implemented fourteen.

Checked against the whitelist first, and the refusal names the type — so you learn what is missing rather than getting an empty resource.

type: "collection"

You need a transaction or batch Bundle to POST at a FHIR server.

We emit a collection Bundle. Wrap it yourself, or write the mapped rows through a destination connector instead.

loinc_format

A code fails its format check inside a row destined for a resource.

Flagged in the validator pass, before assembly. The bundle is never built around a code that already failed.

R4 only

You are on STU3, or already moving to R5.

The emit path targets R4, which is what the fourteen implemented resource types are built against. We would rather name the version than imply all of them.

What it costs

One prepaid wallet, drawn down per call.

No free tier. Top up from $10 — the balance is shared across the phi-cloud suite — and every operation draws it down at the rate below. An optional $6/mo plan grants a credit that resets each billing cycle instead; overage falls back to the wallet.

Every FHIR emit

$0.001

Metered exactly like any other map — the flat per-map fee. Asking for FHIR instead of CSV costs nothing extra by itself.

Bundle assembly

Free

Pure compute. The only AI cost on this path is the cascade’s metered layer, and only if a column could not be placed deterministically.

From a PHI document

+20%

A scanned form is full-data and PHI-routed, so the whole charge carries the uplift — flat fee, extraction tokens and all.

A PHI/enterprise-routed run multiplies the whole charge by 1.2 (+20%), flat fee included — and only when the run genuinely got that routing. PHI stays locked until the workspace accepts the BAA in Settings → Security & Data. Full pricing

Questions

The ones asked before signing.

What it costs, what leaves your network, and the claims we will not make.

Do I have to write the FHIR mappings myself?
No. A template that supports it declares a fhir_resource, so once your rows are mapped to that template’s fields the resource is derived for you. You ask for output: "fhir"; the template already knows how its fields become an R4 resource.
Is FHIR only for the healthcare pack?
The emit path is vertical-agnostic — it is one of nine output formats, not a special gate. In practice it is the healthcare templates that declare a fhir_resource, because that is where FHIR is the target format. A custom schema can declare one too.
Which resources are supported?
Fourteen: Patient, Observation, Medication, Appointment, Coverage, Practitioner, Claim, Claim.item, Encounter, Condition, Immunization, Organization, Location and AllergyIntolerance. A template pointing at anything outside that list is refused by name rather than emitted half-built.
Are the values inside a resource validated?
Yes — the same commit-time validators apply, including loinc_code, icd10_code and fhir_reference, and they run before the bundle is assembled. A code that fails its check is flagged instead of shipped inside a resource that otherwise looks correct.

Keep reading

The rest of the same engine.

One key, from a messy file to your schema.

Top up a $10 prepaid wallet and start mapping. In schema-only mode only your headers and three clamped rows ever leave you.

FHIR R4 emit — AdaptivMapr — AdaptivMapr