SQL on FHIR, published by HL7 International / FHIR Infrastructure. This guide is not an authorized publication; it is the continuous build for version 3.0.0-ballot built by the FHIR (HL7® FHIR® Standard) CI Build. This version is based on the current content of https://github.com/HL7/sql-on-fhir/ and changes regularly. See the Directory of published versions
| Page standards status: Informative |
This document defines a standard HTTP API for interacting with SQL on FHIR systems, including FHIR servers and ViewDefinition runners.
This is a normative specification that defines conformance requirements for implementing ViewDefinition functionality in compliant systems.
The following list of API endpoints are defined:
Both data operations act on a subject: a ViewDefinition, a SQLQuery Library or a SQLView Library. The subject is named by a parameter rather than by the request path, so one operation serves all three artifact kinds.
Clients can discover supported capabilities of the server by requesting the CapabilityStatement resource
on standard FHIR server endpoint - /metadata.
An analytics team maintains a reporting bundle of ViewDefinitions that flatten FHIR resources into tables, and SQLQuery Libraries that join and aggregate those tables. The whole bundle is exported as one job.
The point of one job is the shared snapshot. Every subject in a job is computed against a single consistent view of the data, so a view output and a query output can be joined on a shared key without a skew window - which two separate export jobs, seeing the data at two different points in time, cannot offer. One job also means one set of filters, one polling loop, one export identifier and one manifest.
Flow:
$sql-export request naming every artifact as a
repetition of the subject parameter, with patient, group and _since
stated once for the job and Prefer: respond-async.202 Accepted with a Content-Location header pointing to
one status URL.303 See Other with the result URL.output entry per subject, correlated by name.Clients can efficiently transform and export FHIR data in flattened format (csv, parquet, ndjson) described in ViewDefinitions into file storage (like S3, GCS, Azure Blob Storage, etc). And use standard tools like Apache Spark, AWS Athena or other tools to analyze data or load data into data warehouses.
Flow:
Prefer: respond-async header.202 Accepted with Content-Location header pointing to status URL.202 Accepted while processing (MAY include interim results)303 See Other with a Location header carrying the result URL when the export has finished200 OK.Client can request real-time evaluation of ViewDefinition and process streamed results. For example, AI applications can use this to process patient data in real-time by requesting flat conditions, observations and medications as they are recorded.
Flow:
Developers or developer tools can test and refine ViewDefinitions interactively by evaluating them in real-time.
Flow:
Client can submit an asynchronous job to the server to build views and run queries to produce reports, quality dashboards and analytics. What's going on server is abstracted from the client. Administrative bodies can request bulk reports for different populations and metrics from hospital systems.
Flow:
Behavior shared by the two data operations ($sql-run and $sql-export) - the
output format set, subject naming, filtering, context matching, return
representation, content negotiation, transfer framing, the error contract and
the asynchronous delivery flow - is specified once in
Common Operation Behavior. The operation pages below
reference it rather than restating it.
Server SHALL support CapabilityStatement API for discovery of supported operations.
See CapabilityStatement for SQL-on-FHIR API
The $sql-run operation provides real-time, synchronous evaluation of a single
subject, returning the result in the requested output format. Where the subject
is a ViewDefinition it is evaluated directly, over server data or over resources
supplied inline; where it is a SQLQuery or SQLView Library its dependency graph
is resolved first and the SQL is executed against the resulting tables. The
operation suits interactive development, debugging and real-time data streaming.
It is invoked at the system level ([base]/$sql-run), with the subject named by
subjectCanonical, subjectReference or subjectResource. Both GET and
POST are supported: GET is available whenever every supplied parameter is
primitive, which is what keeps the operation usable from a browser or a command
line.
The operation supports the shared output formats (json, ndjson, csv, parquet) plus fhir, selected by the _format parameter or, where _format is absent, derived from the Accept header. See Output Formats.
It can process either resources provided directly in the request or resources available on the server, with optional filtering by patient, group, or time parameters. The operation may use chunked transfer encoding for large result sets and includes comprehensive error handling through FHIR OperationOutcome resources for validation and processing errors.
See Operation $sql-run and the shared Common Operation Behavior.
The $sql-export operation is the asynchronous counterpart to $sql-run,
exporting the results of one or more subjects into formats such as CSV, NDJSON or
Parquet using the FHIR Asynchronous Interaction Request Pattern. It suits
large-scale extraction where results are delivered to file storage for analysis,
reporting or loading into a data warehouse.
It is invoked at the system level ([base]/$sql-export) with POST, since it
creates a job. Each repetition of the subject parameter names an artifact by
canonical URL, by a literal reference, or supplies it inline, and any mixture of
ViewDefinitions, SQLQuery Libraries and SQLView Libraries may be named in one
request. Every subject is computed against a single snapshot of the data, under
one set of filters, and produces exactly one entry in one manifest.
The export process consists of four main endpoints: start export, get export status, cancel export, and get export results. The server processes the subjects asynchronously and provides progress updates through polling mechanisms, making it suitable for handling large datasets without blocking the client.
See Operation $sql-export and the shared Common Operation Behavior.