Operations
The FHIR operations a DSP-FHIR server relies on. Each entry says what the op does for DSP data and why it's the right fit.
Canonical read — $graphql
What it does: returns a single, DSP-shaped projection of an encounter (conditions, orders, sections, provenance) from a published query document. See Canonical DSP read.
Why it fits: DSP is a rooted, encounter-scoped graph; a DSP client wants one call that returns that graph, not N typed searches. GraphQL is a FHIR base-spec operation and supports a profile-driven projection without inventing a DSP-specific wire protocol. Fallbacks for servers without GraphQL:
Encounter/$everything— one-call encounter bundle, universally implemented.Patient/$summary(IPS) — profile-driven canonical projection, the conceptual blueprint for DSP's encounter summary.Composition/$document— section-centric bundle, natural fit for DSP's document sections.- US Core
$docref— surfaces transcriptDocumentReferences by patient.
Change tracking — Encounter/$everything?_since=
What it does: returns a Bundle of everything in the encounter
compartment touched since a given instant. Consumers derive DSP's
NEW / UPDATED / DELETED flags from meta.versionId,
meta.lastUpdated, and accompanying
Provenance resources.
GET [base]/Encounter/enc-12345/$everything?_since=2026-04-23T14:00:00Z
=> 200 OK (Bundle, type=searchset)
// Derivation convention:
// NEW : meta.versionId == "1" AND meta.lastUpdated > _since
// UPDATED : meta.versionId > "1" AND meta.lastUpdated > _since
// DELETED : tombstone OR Provenance.activity code = DELETE
// (system http://terminology.hl7.org/CodeSystem/v3-DataOperation)
// Servers SHOULD emit a Provenance per mutation so DELETE is unambiguous. Why it fits: FHIR already layers three change-tracking
mechanisms at three granularities — $everything?_since=
for per-encounter deltas, Bulk Data $export?_since=
for patient-wide batches, _history for
resource-level audit. The IG only has to pin the
Provenance.activity vocabulary so DELETE is explicit.
Spoken-form lookup — CodeSystem/$lookup + ValueSet/$expand
What it does: resolves voice commands ("go to HPI", "open
subjective") to canonical LOINC section codes, and vice versa. The IG publishes
a spoken-form CodeSystem whose concepts carry
designations for each voice alias; the two standard
terminology ops cover both directions.
Forward (code → spoken forms):
GET [base]/CodeSystem/$lookup?system=http://loinc.org&code=10164-2&property=designation
=> 200 OK
{
"resourceType":"Parameters",
"parameter":[
{ "name":"display","valueString":"History of present illness Narrative" },
{ "name":"designation","part":[
{ "name":"use","valueCoding":{"system":"https://dsp-fhir.org/CodeSystem/spoken-form-use","code":"voice-alias"}},
{ "name":"value","valueString":"HPI" }
]},
{ "name":"designation","part":[
{ "name":"use","valueCoding":{"system":"https://dsp-fhir.org/CodeSystem/spoken-form-use","code":"voice-alias"}},
{ "name":"value","valueString":"history of present illness" }
]}
]
} Reverse (spoken form → code):
GET [base]/ValueSet/dsp-section-spoken-forms/$expand?filter=HPI&includeDesignations=true
=> 200 OK
{
"resourceType":"ValueSet",
"expansion":{
"contains":[
{ "system":"http://loinc.org","code":"10164-2","display":"History of present illness",
"designation":[
{ "use":{"system":"https://dsp-fhir.org/CodeSystem/spoken-form-use","code":"voice-alias"},
"value":"HPI" }
]
}
]
}
} Why it fits: "spoken form" is a designation — exactly
what CodeSystem.concept.designation was designed
for. Every FHIR terminology server already implements
$lookup and $expand; the
IG's contribution is the vocabulary, not a new wire protocol.
Materialize follow-up — ActivityDefinition/$apply
What it does: turns a DSP follow-up
ServiceRequest (carrying a
boundsDuration) into a proposed
Appointment.
1. Publish the template once, as an IG artifact:
{
"resourceType":"ActivityDefinition",
"id":"dsp-follow-up-appointment",
"url":"https://dsp-fhir.org/ActivityDefinition/dsp-follow-up-appointment",
"status":"active",
"kind":"Appointment",
"intent":"proposal",
"timingDuration":{"value":30,"unit":"min","system":"http://unitsofmeasure.org","code":"min"},
"participant":[
{ "type":"patient" },
{ "type":"practitioner" }
]
} 2. Invoke with the source ServiceRequest:
POST [base]/ActivityDefinition/dsp-follow-up-appointment/$apply
{
"resourceType":"Parameters",
"parameter":[
{ "name":"subject","valueReference":{"reference":"Patient/pat-67890"}},
{ "name":"encounter","valueReference":{"reference":"Encounter/enc-12345"}},
{ "name":"basedOn","valueReference":{"reference":"ServiceRequest/fu-001"}},
{ "name":"practitioner","valueReference":{"reference":"Practitioner/pract-001"}}
]
}
=> 200 OK
{
"resourceType":"Appointment","id":"appt-0042","status":"proposed",
"basedOn":[{"reference":"ServiceRequest/fu-001"}],
"participant":[
{ "actor":{"reference":"Patient/pat-67890"},"status":"needs-action" },
{ "actor":{"reference":"Practitioner/pract-001"},"status":"tentative" }
],
"extension":[
{ "url":"https://dsp-fhir.org/StructureDefinition/approximate-match","valueBoolean":true }
]
} Why it fits: $apply is FHIR's
purpose-built op for "turn a clinical intent into proposed action resources".
An ActivityDefinition with
kind=Appointment is exactly the template shape a
DSP follow-up needs.
$apply produces a proposed
Appointment — it does not find an open slot.
Slot-finding is a scheduling-service concern outside the IG; clients either
pass Appointment.start as a hint, run
Appointment.$find, or leave it to a human.
Accompanying party — RelatedPerson/$match
What it does: resolves DSP's free-string
accompanied_by ("Jane Doe, spouse") to a real
RelatedPerson resource.
POST [base]/RelatedPerson/$match
{
"resourceType":"Parameters",
"parameter":[
{ "name":"resource","resource":{
"resourceType":"RelatedPerson",
"patient":{"reference":"Patient/pat-67890"},
"relationship":[{
"coding":[{
"system":"http://terminology.hl7.org/CodeSystem/v3-RoleCode",
"code":"SPS","display":"spouse"
}]
}],
"name":[{"text":"Jane Doe"}]
}},
{ "name":"onlyCertainMatches","valueBoolean":false },
{ "name":"count","valueInteger":3 }
]
}
=> 200 OK
{
"resourceType":"Bundle","type":"searchset",
"entry":[
{ "fullUrl":"https://example.org/RelatedPerson/rp-5512",
"resource":{ "resourceType":"RelatedPerson","id":"rp-5512" },
"search":{
"mode":"match",
"score":0.88,
"extension":[
{ "url":"http://hl7.org/fhir/StructureDefinition/match-grade",
"valueCode":"probable" }
]
}
}
]
} Why it fits: the signature mirrors FHIR base
Patient/$match — the canonical pattern for
resolving a weakly-identified human to a real resource — so the shape is
immediately familiar to every FHIR implementer. Da Vinci HRex's
$member-match is the closest prior art.
RelatedPerson/$match is not in the base spec; the
IG profiles a parallel op rather than invent a DSP-specific name.
Turn-ref integrity — $validate
What it does: surfaces broken transcript turn-refs (integer indices that no longer resolve after the transcript is revised) as standard invariant violations on the resource.
Invariant on the transcript-turn-refs extension:
{
"resourceType":"StructureDefinition",
"url":"https://dsp-fhir.org/StructureDefinition/transcript-turn-refs",
"derivation":"constraint",
"differential":{
"element":[{
"id":"Extension",
"constraint":[{
"key":"turn-refs-resolve",
"severity":"error",
"human":"Every turn index MUST resolve in the referenced DocumentReference version.",
"expression":"<server-evaluated - see note>"
}]
}]
}
} Invocation:
POST [base]/MedicationRequest/med-001/$validate
=> 200 OK
{
"resourceType":"OperationOutcome",
"issue":[
{ "severity":"error","code":"invariant",
"diagnostics":"turn-refs-resolve: MedicationRequest/med-001 references turn 11; transcript revision 3 has only 9 turns.",
"location":["MedicationRequest.extension('transcript-turn-refs').extension('turn')[0]"] }
]
} Why it fits: "is this resource well-formed against a profile"
is what $validate does. The turn-ref rule is a
profile invariant, not a new operation. $validate
is on every FHIR server; the rule is discoverable via the profile; clients can
run it defensively. Normative rule
R1 carries the prevention side;
$validate surfaces violations when they slip
through.
$ground — transcript turn-join with context
What it does: given a resource with a
transcript-turn-refs extension, returns the
referenced turns (with an optional ±N context window) from the pinned
transcript version. The only DSP-specific operation in the IG.
GET [base]/MedicationRequest/med-001/$ground?include-content=true&context-window=1
=> 200 OK
{
"resourceType":"Parameters",
"parameter":[
{ "name":"transcript","valueReference":{"reference":"DocumentReference/dr-transcript-001/_history/3"}},
{ "name":"turn","part":[
{ "name":"index","valueInteger":10 },
{ "name":"speaker","valueCode":"provider" },
{ "name":"start-time","valueString":"00:01:40.1" },
{ "name":"end-time","valueString":"00:01:42.7" },
{ "name":"content","valueString":"So for the bronchitis..." },
{ "name":"role","valueCode":"context" }
]},
{ "name":"turn","part":[
{ "name":"index","valueInteger":11 },
{ "name":"speaker","valueCode":"provider" },
{ "name":"content","valueString":"Let's start azithromycin 250 daily for five days." },
{ "name":"role","valueCode":"grounding" }
]}
]
} Why it fits (and is custom): no base-spec or IG op dereferences
integer turn indices into turn content.
Provenance records the linkage but not the text;
$everything hands back the whole transcript and
leaves the join to the client. The server wrote the transcript and knows its
format — it's the natural owner of the join. Pinning
_history/3 in the response keeps normative rule
R1 (turn-index stability) end-to-end.
SearchParameters & capability advertisement
Three DSP concerns close with indexing + capability advertisement, not operations:
Low-confidence review — SearchParameter
Index the confidence-score extension and use FHIR's
cross-type search to build a review queue.
{
"resourceType":"SearchParameter",
"url":"https://dsp-fhir.org/SearchParameter/dsp-confidence",
"name":"confidence",
"base":["MedicationRequest","ServiceRequest","Condition","Observation"],
"code":"confidence",
"type":"number",
"expression":"extension('https://dsp-fhir.org/StructureDefinition/confidence-score').valueDecimal"
}
// Cross-type review queue — one call, multiple resource types:
GET [base]/?_type=MedicationRequest,ServiceRequest,Condition,Observation
&encounter=Encounter/enc-12345
&confidence=lt0.8
&_sort=confidence Payload-version negotiation — CapabilityStatement extension
Advertise accepted and emitted DSP payload versions on
CapabilityStatement.rest.resource.extension.
Clients read CapabilityStatement already.
{
"resourceType":"CapabilityStatement",
"rest":[{
"mode":"server",
"extension":[
{ "url":"https://dsp-fhir.org/StructureDefinition/dsp-payload-versions",
"extension":[
{ "url":"accepts","valueCode":"1.0.0" },
{ "url":"emits", "valueCode":"1.0.0" },
{ "url":"emits", "valueCode":"0.9.3" },
{ "url":"default-emit","valueCode":"1.0.0" }
]
}
]
}]
}
Servers denormalize the payload version to meta.tag
so baseline FHIR search works:
GET [base]/Encounter?_tag=https://dsp-fhir.org/CodeSystem/payload-version|1.0.0
Normative rule R3: servers MUST
advertise, MUST NOT auto-upgrade on read, and MUST reject unknown versions on
write with 422.
Search terms — SearchParameter
DSP synonyms / search terms index cleanly as
dsp-search-term (type
string) over the
search-terms extension.
Capability advertisement
A conformant DSP-FHIR server advertises the standard ops it relies on (so
clients can feature-detect) alongside its SearchParameters. The only
DSP-custom entry is $ground.
{
"resourceType":"CapabilityStatement",
"rest":[{
"mode":"server",
"operation":[
{ "name":"graphql", "definition":"http://hl7.org/fhir/OperationDefinition/Resource-graphql" },
{ "name":"everything", "definition":"http://hl7.org/fhir/OperationDefinition/Encounter-everything" },
{ "name":"lookup", "definition":"http://hl7.org/fhir/OperationDefinition/CodeSystem-lookup" },
{ "name":"expand", "definition":"http://hl7.org/fhir/OperationDefinition/ValueSet-expand" },
{ "name":"apply", "definition":"http://hl7.org/fhir/OperationDefinition/ActivityDefinition-apply" },
{ "name":"match", "definition":"http://hl7.org/fhir/OperationDefinition/Patient-match" },
{ "name":"validate", "definition":"http://hl7.org/fhir/OperationDefinition/Resource-validate" },
{ "name":"document", "definition":"http://hl7.org/fhir/OperationDefinition/Composition-document" },
// IG-profiled (same signature as Patient-match):
{ "name":"match", "definition":"https://dsp-fhir.org/OperationDefinition/RelatedPerson-match" },
// DSP-custom:
{ "name":"ground", "definition":"https://dsp-fhir.org/OperationDefinition/ground" }
],
"searchParam":[
{ "name":"confidence", "definition":"https://dsp-fhir.org/SearchParameter/dsp-confidence", "type":"number" },
{ "name":"payload-version", "definition":"https://dsp-fhir.org/SearchParameter/dsp-payload-version", "type":"token" },
{ "name":"search-term", "definition":"https://dsp-fhir.org/SearchParameter/dsp-search-term", "type":"string" }
]
}]
}