ClinikAPI’s simplified API covers the most common operations — creating patients, recording observations, managing appointments — with a clean JSON interface. When you need capabilities beyond what the simplified API exposes, the FHIR passthrough routes your requests directly to the ClinikAPI FHIR gateway backed by AWS HealthLake.
Use the passthrough when you need custom FHIR search parameters, FHIR operations like $everything or $validate, or resource types not yet in the simplified SDK. Tenant isolation is still fully enforced in passthrough mode.
The passthrough returns raw FHIR R4 resources — not the simplified format used by the SDK methods. You’ll need to work with FHIR resource structures directly.
When to use passthrough vs. the simplified API
| Use case | Recommended approach |
|---|
| Standard CRUD on patients, encounters, etc. | Simplified SDK methods (clinik.patients.create()) |
| Custom FHIR search parameters | clinik.fhir.request('GET', ...) |
FHIR operations ($everything, $validate) | clinik.fhir.request('POST', ...) |
| Resource types not in the SDK | clinik.fhir.request(...) |
| Complex FHIR queries with chaining | clinik.fhir.request('GET', ...) |
Read a FHIR resource
curl https://api.clinikehr.com/v1/fhir/Patient/pt_abc123 \
-H "x-api-key: clk_live_abc123"
Using the SDK:
const { data: patient } = await clinik.fhir.request('GET', '/Patient/pt_abc123');
Create a FHIR resource
curl -X POST https://api.clinikehr.com/v1/fhir/Patient \
-H "x-api-key: clk_live_abc123" \
-H "Content-Type: application/fhir+json" \
-d '{"resourceType":"Patient","name":[{"family":"Smith"}]}'
Using the SDK:
const { data } = await clinik.fhir.request('POST', '/Patient', {
resourceType: 'Patient',
name: [{ family: 'Smith', given: ['John'] }],
gender: 'male',
birthDate: '1990-01-15',
});
Patch a FHIR resource
Use JSON Patch (RFC 6902) to apply partial updates:
curl -X PATCH https://api.clinikehr.com/v1/fhir/Patient/pt_abc123 \
-H "x-api-key: clk_live_abc123" \
-H "Content-Type: application/json-patch+json" \
-d '[
{ "op": "replace", "path": "/gender", "value": "female" },
{ "op": "add", "path": "/birthDate", "value": "1990-01-15" }
]'
Using the SDK:
const { data } = await clinik.fhir.request('PATCH', '/Patient/pt_abc123', [
{ op: 'replace', path: '/gender', value: 'female' },
]);
Delete a FHIR resource
curl -X DELETE https://api.clinikehr.com/v1/fhir/Observation/obs_xyz789 \
-H "x-api-key: clk_live_abc123"
Using the SDK:
await clinik.fhir.request('DELETE', '/Observation/obs_xyz789');
Search with custom FHIR parameters
The passthrough exposes the full FHIR search API, including parameters the simplified SDK doesn’t surface:
curl "https://api.clinikehr.com/v1/fhir/Observation?code=8867-4&date=ge2024-01-01&_sort=-date&_count=50" \
-H "x-api-key: clk_live_abc123"
Using the SDK:
const { data: bundle } = await clinik.fhir.request(
'GET',
'/Observation?code=8867-4&date=ge2024-01-01&_sort=-date&_count=50'
);
FHIR CapabilityStatement
The /v1/metadata endpoint returns a FHIR R4 CapabilityStatement describing all supported resource types, search parameters, and operations. No authentication is required:
curl https://api.clinikehr.com/v1/metadata
Tenant isolation
Even in passthrough mode, tenant isolation is enforced at the gateway level:
- Creates: your tenant tag is automatically injected into
meta.tag.
- Searches: a
_tag filter is automatically appended to every query.
- Reads, updates, and deletes: resource ownership is verified before the operation proceeds.
You cannot bypass tenant isolation through the FHIR passthrough.
Do not attempt to manually set meta.tag on creates or override the _tag search parameter. The gateway will reject requests that conflict with tenant isolation rules.