Skip to content
Developer documentation

Build against a vault that answers.

HL7 FHIR R4, OAuth 2.0 and SMART on FHIR scopes, signed webhooks and first-party SDKs in TypeScript, Python and Java. Sandbox tenants provision in under five minutes with synthetic Swiss patient data.

Standard
FHIR R4
Resources
23
Median read
38 ms
Deprecation window
12 months
An engineer at a multi-monitor workstation beside a server rack, in near-darkness.
Build against the API

Nobody in a call centre
wrote this API.

The engineers who built the FHIR endpoints run the infrastructure behind them, in a room like this one. Provision a sandbox tenant, exchange an OAuth token and read a FHIR R4 resource with an audit signature you check yourself — before anyone from our team is involved.

< 5 min
Sandbox provisioning
23
FHIR R4 resources
38 ms
Median read, p50
12 mo
Minimum deprecation window
Integration platform overview

Four calls to a
verified read.

From nothing to an authorised, audited FHIR read with a signature you can verify yourself. Most teams finish this in an afternoon.

01

Create a sandbox tenant

Self-serve, synthetic patient data, full API surface. No commercial commitment and no credit card.

curl -X POST https://api.medivaultzurich.site/v1/sandbox \
  -H "Content-Type: application/json" \
  -d '{"label":"my-first-tenant","dataset":"synthetic-ch-500"}'
02

Get an access token

OAuth 2.0 client credentials. Tokens are short-lived (15 minutes) and scoped per integration.

curl -X POST https://auth.medivaultzurich.site/oauth2/token \
  -d grant_type=client_credentials \
  -d client_id=$MV_CLIENT_ID \
  -d client_secret=$MV_CLIENT_SECRET \
  -d scope="patient/*.read audit/*.write"
03

Make an authorised read

Purpose of use is mandatory on every clinical request. Omitting it returns 403, not a default.

curl https://api.medivaultzurich.site/fhir/r4/Patient/pat_8f2c41ba \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-MV-Purpose-Of-Use: TREATMENT" \
  -H "Accept: application/fhir+json"
04

Verify the audit event

Every response carries the id of the audit entry it generated. Fetch it and verify the signature yourself.

curl https://api.medivaultzurich.site/fhir/r4/AuditEvent/evt_01JKX9Q4C7YB \
  -H "Authorization: Bearer $TOKEN" \
  -H "Accept: application/fhir+json"

Typed clients,
maintained by us.

Each SDK handles retries, pagination, token refresh and purpose-of-use propagation, so those are not things every integrator reimplements slightly wrong.

TypeScriptv4.2.1
npm install @medivault/sdk
Pythonv4.2.0
pip install medivault
Javav4.2.1
implementation 'site.medivault:sdk:4.2.1'

Twenty-three resources.
Eight you will use daily.

Patient

Demographics, identifiers (AHV, insurance, internal), contact data and administrative status.

Encounter

Admissions, visits and episodes of care, including the care relationship the policy engine evaluates.

Observation

Vitals, laboratory results and measurements with LOINC coding and reference ranges preserved.

DocumentReference

Clinical documents with content pointers, classification, authorship and version chain.

DiagnosticReport

Radiology, pathology and laboratory reports with links to their supporting observations.

Consent

Patient directives, restrictions and revocations — read by the policy engine on every request.

AuditEvent

The signed audit ledger, readable by authorised compliance roles and streamable to your SIEM.

Practitioner & PractitionerRole

Clinical identities, their roles, their organisations and their current authorisation scope.

The full conformance statement is served at /fhir/r4/metadata and validated against the HL7 Touchstone suite on every release. If our behaviour diverges from the statement, that is a bug and we will treat it as one.

Refusals are
specific on purpose.

A generic 403 tells an integrator nothing and pushes them toward retry loops. MediVault names the reason, because the reason changes what you should do next.

400 invalid_request
Malformed FHIR payload or missing required element. The OperationOutcome names the exact path that failed validation.
401 unauthenticated
Missing, expired or malformed token. Tokens live 15 minutes; refresh rather than retrying the same one.
403 purpose_required
The X-MV-Purpose-Of-Use header is absent. There is no default purpose — the caller must declare intent.
403 no_care_relationship
Authenticated and authorised in role, but no active care relationship exists with this patient. Use break-glass if clinically justified.
403 consent_restricted
The patient has restricted this record class for this requester. The refusal itself is recorded in the audit ledger.
409 version_conflict
Optimistic concurrency failure. Re-read the resource, reapply your change and retry with the current version id.
429 rate_limited
Per-tenant limit exceeded. Retry-After is always present; SDKs honour it automatically with exponential backoff.
503 vault_unavailable
The vault is failing closed rather than serving a possibly stale record. Safe to retry; never returns partial data.
Developers

Get a sandbox
in five minutes.

Synthetic Swiss patient data, the full API surface and no commercial commitment. Talk to an integration engineer only when you actually want to.

Date-based API versioning · 12-month minimum deprecation window