FHIR Data Formats for SDC Forms: NDJSON, Bundle, and When Each Works

FHIR Data Formats for SDC Forms: NDJSON, Bundle, and When Each Works

Diagram: FHIR Data Formats for SDC Forms: NDJSON, Bundle, and When Each Works. Diagram illustrating the article's core structure and decision points.

FHIR data exchange for SDC forms happens in three primary formats — Bundle transactions, NDJSON via $export, and individual QuestionnaireResponse POSTs. Each has a place; picking wrong makes downstream integration harder than it needs to be.

Bundle transaction for atomic form submission. When a form fill-in produces a QuestionnaireResponse plus one or more downstream Observations (via SDC $extract), all of them should land atomically. FHIR's Bundle transaction type provides this — one HTTP POST, server-side atomicity, rollback on any failure. Best for clinical workflows where partial success creates data integrity problems.

NDJSON for batch export and analytics. When exporting completed QuestionnaireResponses for reporting or ML training, Bulk Data IG NDJSON is the right format. Each line is a resource, streamable, easy to parse in Python/Spark/dbt. The tradeoff: no cross-resource references resolved at export; you need to stitch together QuestionnaireResponse → Patient → Practitioner downstream.

Individual REST POST for progressive save. Save-and-resume workflows benefit from POSTing partial QuestionnaireResponse status=in-progress records, updating with PUT as the user progresses. Requires the client to track resource versions (ETag/If-Match) to avoid overwriting concurrent updates.

Format decision matrix

Use case Best format Reason
Single form submission with extraction Bundle transaction Atomicity
Nightly export for reporting NDJSON $export Streamable, scalable
Progressive save-and-resume Individual POST/PUT Incremental updates
Cross-clinic sync Bundle batch Independent operations
ML training data pipeline NDJSON $export Streamable, no atomicity needed

Common mistakes:

- Using individual POSTs for form submission with extraction → race conditions, orphaned resources - Using Bundle for bulk export → server timeouts, over-atomicity - Mixing formats without a clear rule → integration confusion, downstream parsing errors

Picking the right format is a one-time decision that pays off for years. The three formats above cover essentially every SDC integration pattern.