> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cds.marmar.life/llms.txt
> Use this file to discover all available pages before exploring further.

# FHIR Integration

## Overview

Marmar exposes a pragmatic FHIR v4 surface so tenants can synchronize clinical data without bespoke
transformers. We currently support the following resource types in both directions:

* Patient
* MedicationStatement
* MedicationRequest
* Condition
* AllergyIntolerance
* Observation
* Encounter

All endpoints require the tenant slug and API key via the `X-Tenant-Code` and `X-API-Key` headers and return
standard FHIR JSON payloads (`application/fhir+json`).

## Submit clinical bundles

Use `POST /v1/fhir/$submit` to ingest a FHIR Bundle (`collection`, `batch`, or `transaction`). Each entry
is validated, normalized, and persisted. The response contains an `OperationOutcome` and per-resource
counters so you can reconcile successes versus failures.

```bash theme={null}
curl -X POST https://cds.marmar.life/v1/fhir/$submit \
  -H "Content-Type: application/fhir+json" \
  -H "X-Tenant-Code: acme-oncology" \
  -H "X-API-Key: $MARMAR_API_KEY" \
  -d @bundle.json
```

### Supported resources

* **Patient** → updates the Marmar patient profile (external IDs are honoured).
* **MedicationStatement** → upserts active medications that power assessment inputs.
* **MedicationRequest, Condition, AllergyIntolerance, Observation, Encounter** → stored as raw FHIR JSON
  and retrievable through the search/read API.

If a resource fails validation, the response includes an `OperationOutcome.issue` with `severity=error`
and the offending resource remains untouched.

### Patient auto-creation

When a resource references a patient that does not yet exist in Marmar (e.g. `subject.reference: "Patient/pat1"`),
Marmar automatically creates a stub patient record for that ID so the data is never dropped. You can enrich
the patient's demographics at any point by submitting a `Patient` resource with the same ID — either in the
same bundle or a later request. Existing demographics are never overwritten by a stub.

**Facility assignment.** The stub's `externalId` (used to associate the patient with a facility) is resolved in this order:

1. The `identifier[0].value` of a `Patient` resource with the same ID included in the same bundle.
2. The `externalId` of the tenant's default facility — the oldest active, FHIR-enabled facility on record.
3. `null` if no facility is configured yet.

## Retrieve a resource

Use `GET /v1/fhir/{resourceType}/{id}` for direct reads. Marmar returns the latest copy of the resource
in native FHIR form or an `OperationOutcome` with `404` if it is missing.

```bash theme={null}
curl -H "X-Tenant-Code: acme-oncology" \
  -H "X-API-Key: $MARMAR_API_KEY" \
  https://cds.marmar.life/v1/fhir/Patient/2b9f1b5a-...-6d7c
```

## Search resources

`GET /v1/fhir/{resourceType}` returns a FHIR search bundle (`type=searchset`). Available filters vary per
resource:

| Resource            | Query params                  |
| ------------------- | ----------------------------- |
| Patient             | `identifier`                  |
| MedicationStatement | `patient`, `status`           |
| MedicationRequest   | `patient`, `status`           |
| Condition           | `patient`, `status`           |
| AllergyIntolerance  | `patient`, `status`           |
| Observation         | `patient`, `category`, `code` |
| Encounter           | `patient`, `status`           |

```bash theme={null}
curl -H "X-Tenant-Code: acme-oncology" \
  -H "X-API-Key: $MARMAR_API_KEY" \
  "https://cds.marmar.life/v1/fhir/Observation?patient=Patient/123&category=vital-signs"
```

The response includes `total` and individual bundle entries so you can page client-side. For larger data
sets, apply filtering early or request resources in batches.

## Error handling

* Validation failures → `400` with `OperationOutcome` explaining the first failure.
* Missing resources → `404` with `OperationOutcome`.
* Authentication failures → `401` with `OperationOutcome`.

Always validate the returned `OperationOutcome` before assuming a bundle was fully processed.
