ediverse Explore the platform

Spotlight PEPPOL BIS Billing 3.0 The EU e-invoicing mandate is here — France Sept 2026, Belgium Jan 2026, Germany 2025.

OperationDefinition — Describing FHIR $operations

FHIR is not limited to REST CRUD. Complex business operations — fetch a whole record, expand a ValueSet, validate a resource — flow through standardised $operations declared by OperationDefinition.

Purpose

OperationDefinition is the technical metadata describing an operation a FHIR server can execute. It is the equivalent of a SQL stored-procedure signature: name (the $code), input and output parameters, invocation scope (system, type or instance).

Every standard FHIR operation ($validate, $everything, $expand, $lookup, $translate, $process-message...) ships with an OperationDefinition in the core spec. Implementations may publish their own private operations with a private canonical URL.

Key fields

FieldTypeCardinalityRole
urluri1..1Mandatory. Unique canonical URL.
versionstring0..1Operation version.
namestring1..1Machine name.
titlestring0..1Human title.
statuscode1..1draft | active | retired | unknown.
kindcode1..1operation (side effects) or query (read-only).
codecode1..1The code used in the URL (prefixed with $).
affectsStateboolean0..1Does the operation change server state? If false, GET is allowed.
resourcecode[]0..*Resource types in scope.
system / type / instanceboolean1..1 eachInvocation scope.
parameterBackboneElement[]0..*In/out parameters.
parameter.namecode1..1Parameter name.
parameter.usecode1..1in or out.
parameter.mininteger1..1Minimum cardinality.
parameter.maxstring1..1Maximum cardinality (* or integer).
parameter.typecode0..1Parameter type (Resource, Bundle, code, string...).

Kind and invocation scope

Three booleans define where an operation can be invoked:

  • system: true — invocable on the server endpoint, e.g. POST [base]/$process-message.
  • type: true — invocable on a resource type, e.g. POST [base]/Patient/$match.
  • instance: true — invocable on an instance, e.g. GET [base]/Patient/123/$everything.

An operation may be invocable at several levels. $validate for example is both type=true AND instance=true.

JSON example

The canonical OperationDefinition for Patient/$everything:

json operationdefinition-everything.json
{
  "resourceType": "OperationDefinition",
  "id": "Patient-everything",
  "url": "http://hl7.org/fhir/OperationDefinition/Patient-everything",
  "version": "5.0.0",
  "name": "Everything",
  "title": "Fetch Patient Record",
  "status": "active",
  "kind": "operation",
  "experimental": false,
  "date": "2026-05-14",
  "publisher": "HL7 (FHIR Project)",
  "description": "Returns every resource linked to a given Patient: the Patient itself, plus Encounter, Observation, Condition, MedicationStatement, etc.",
  "affectsState": false,
  "code": "everything",
  "resource": ["Patient"],
  "system": false,
  "type": false,
  "instance": true,
  "parameter": [
    {
      "name": "start",
      "use": "in",
      "min": 0,
      "max": "1",
      "documentation": "Earliest date of resources returned.",
      "type": "date"
    },
    {
      "name": "end",
      "use": "in",
      "min": 0,
      "max": "1",
      "documentation": "Latest date of resources returned.",
      "type": "date"
    },
    {
      "name": "_since",
      "use": "in",
      "min": 0,
      "max": "1",
      "documentation": "lastUpdated filter.",
      "type": "instant"
    },
    {
      "name": "_type",
      "use": "in",
      "min": 0,
      "max": "*",
      "documentation": "Restrict to listed resource types.",
      "type": "code"
    },
    {
      "name": "return",
      "use": "out",
      "min": 1,
      "max": "1",
      "documentation": "Searchset Bundle of linked resources.",
      "type": "Bundle"
    }
  ]
}

Common pitfalls

  • Missing affectsState — servers only allow GET when affectsState=false. Pure read operations MUST declare it.
  • Wrong scope — invoking $everything on /Patient without an id fails because the operation is instance=true only.
  • Resource-typed parameters without concrete type — a parameter of type: Resource accepts anything, avoid unless explicit (e.g. $validate).
  • No OperationDefinition for a private operation — without declaring it in the CapabilityStatement and publishing the OperationDefinition, no generic client can call it.