---
type: "doc"
source: "source/operations.html"
---
\[%settitle Operations Framework (RESTful API)%\] \[%file newheader%\] \[%file newnavbar%\]
## Extended Operations on the RESTful API
| Responsible Owner: [\[%wgt fhir%\]]([%wg fhir%]) Work Group | [Standards Status](versions#std-process):[Normative](versions#std-process) |
| --- | --- |
The [RESTful API](http) defines a set of common interactions (read, update, search, etc.) performed on a repository of typed resources. These interactions follow the RESTful paradigm of managing state by **C**reate/**R**ead/**U**pdate/**D**elete actions on a set of identified resources. While this approach solves many use cases, there is some functionality that can be met more efficiently using an RPC-like paradigm, where named operations are performed with inputs and outputs (**E**xecute).
Operations are appropriately used where:
- The server needs to play an active role in formulating the content of the response, not merely return existing information
- The intended purpose is to cause [side effects](https://en.wikipedia.org/wiki/Side_effect_(computer_science)) such as the modification or creation of resources not transmitted as part of the RESTful call (e.g., triggering the generation of an invoice), or other changes out of scope of the RESTful interface (e.g., merging patient records)
- The task involves business rules to be enforced across multiple different resources and/or
- the task involves updating several resources in a coordinated manner (note: this can also be done by a [Transaction](http#transaction), but an operation can be more focused on the task
This specification describes a lightweight operation framework that seamlessly extends the RESTful API. The framework covers both how to execute such an operation (this page) and how to [define an operation](operationdefinition).
Operations have the following general properties:
- Each operation has a name
- Each operation has a list of 'in' and 'out' parameters
- Parameters are either resources, datatypes, or search parameters
- Operations are subject to the same security constraints and requirements as the RESTful API
- The URIs for the operation end-points are based on the existing RESTful API address scheme
- Operations may make use of all types of resources existing in the repository
- Operations may be performed on a specific resource, a resource type, or a whole system
### Executing an Operation
Operations are executed using a URL derived from the FHIR endpoint, where the name of the operation is prefixed by a "dollar sign" ('$') character. For example:
POST http://fhir.someserver.org/fhir/Patient/1/$everything
When an operation has affectsState = false, and the parameters are all primitive datatypes with no extensions (as is the case with the example above), it MAY be invoked using GET as well. (Note: A HEAD request can also be used - see [Support for HEAD](http#head)).
Operations can be invoked on three types of FHIR endpoints:
- The "base" FHIR service endpoint (e.g., http://fhir.someserver.org/fhir): These are operations that operate on the full scale of the server. For example, "return me all extensions known by this server"
- A Resource type (e.g., http://fhir.someserver.org/fhir/Patient): These are operations that operate across all instances of a given resource type
- A Resource instance (e.g., http://fhir.someserver.org/fhir/Patient/1): These are operations that involve only a single instance of a Resource, like the $everything operation above does
The body of the invocation contains a special infrastructure resource called [Parameters](parameters), which represents a collection of named parameters as pairs, where the value may be any primitive or complex datatype or even a full Resource. It may also include strings formatted as search parameter types. A FHIR operation can take a set of zero or more input parameters; in the case where there is zero parameters, the resource may be omitted, and the body will be empty (see below).
Upon completion, the operation returns an HTTP status code indicating what the outcome of performing the operation, and optionally another `Parameters` resource, containing ne or more output parameters. If there is a single output parameter named 'return' with a maximum cardinality of 1, with a type corresponding to a resource, then the response SHALL be the resource that is the return value, with no wrapping Parameters resource. If there is zero output parameters (possibly because the operation failed), then the resource can be omitted, and the body will be empty.
Both the body of the POST and the returned result are always a Resource if any body is present, except in the case that the server supports multi-part/form-data (see below).
Operations MAY be invoked using a `GET`, with parameters as HTTP URL parameters, if:
1. the only parameters being passed are ones whose data type has a corresponding search type (i.e., datatypes like `Identifier` or `Reference` which have a search type of 'token' are permitted, while `Address` and `HumanName` are not)
2. the operation does not [affect the state of the server](operationdefinition-definitions#OperationDefinition.affectsState)
If the response is a [Bundle](bundle), the [Bundle.type](bundle-definitions#Bundle.type) will typically be '[collection](codesystem-bundle-type#bundle-type-collection)', though it could be one of the other types. For eample, if the operation has [search semantics](http#search), such as matching resource counts, and [page links (next etc.) then the](http#paging) [Bundle.type](bundle-definitions#Bundle.type) will typically be '[search-set](codesystem-bundle-type#bundle-type-search-set)'.
#### Operations with no parameters
Executing operations without any parameters is a special case. For an operation that doesn't cause any state change, the operation is invoked in a straight forward fashion:
GET \[base\]/Composition/example/$document
For operations that call state changes, they must be invoked by a POST. There is no parameters resource in this case because a parameters resource cannot be empty. So the operation is invoked with a POST with an empty body:
POST \[base\]/Claim/example/$submit
Content-Length: 0
### FHIR defined Operations
See [the list of defined operations](operationslist).
### Implementation Defined Operations
Implementations are able to define their own operations in addition to those defined here. Name clashes between operations defined by different implementers can be resolved by the use of the server's [Capability Statement](capabilitystatement).
Also, the definition of these or additional run time operations does not prevent the use of other kinds of operations that are not dependent on and/or not integrated with the RESTful API, provided that their addressing scheme does not clash with the scheme defined here.
### Defining an Operation
Each Operation is defined by:
- A context for the Operation - _system_, _resource type_, or _resource instance_
- A name for the Operation
- A list of parameters along with their definitions
For each parameter, the following information is needed:
- Name - the name of the parameter. For implementer convenience, the name should be a valid token in common implementation languages
- Use - In | Out | Both
- Type - a datatype or a Resource type
- Search Type - for parameters with a data type can be expressed on the URL using the search parameter syntax, identifies the [search type](search#type-mapping) to use when passing the parameter in the URL. NOTE: search type modifiers cannot be used when invoking an operation. Explicit separate parameters are required.
- Profile - a [StructureDefinition](structuredefinition) that describes additional restrictions about the parameter - only used if the parameter type is a resource or datatype
- Documentation - a description of the parameter's use
Parameters may be nested into multi-part parameters. Each part has the same information as a parameter, except for use, which is taken from the parameter it is part of.
The resource [Operation Definition](operationdefinition) is used to provide a computable definition of the Operation.
### Extending an Operation
Implementations are able to extend an operation by defining new named parameters. Implementations can publish their own extended definitions using the [Operation Definition](operationdefinition) resource, and this variant definition can use OperationDefinition.base to refer to the underlying definition. See additional discussion in [Derived OperationDefinitions](operationdefinition#base)
Note that the FHIR specification will never define any parameter names starting with "x-".
### Executing an Operation Synchronously
Operations are typically executed synchronously: a client sends a request to a server that includes the operation's _in_ parameters and the server replies with the operation's _out_ parameters.
The URL for an operation end-point depends on its context:
- system: the URL is \[base\]/$\[name\]
- resource type: the URL is \[base\]/\[type\]/$\[name\]
- resource instance: the URL is \[base\]/\[type\]/\[id\]/$\[name\]
#### Operation Request
An operation is generally invoked by performing an HTTP POST to the operation's end-point. The submitted content is the special [Parameters](parameters) format (the "in" parameters) - a list of named parameters. For an example, see [the value set expansion request example](op-example-request). Note that when parameters have a search type, the search modifiers are available and are used on the parameter name in the Parameters resource (e.g., "code:in").
Note that the same arrangement as for the RESTful interface applies with respect to [content types](http#mime-type).
If all the parameters for the operation are [primitive types](datatypes#primitive) and the operation has [`affectsState`](operationdefinition-definitions#OperationDefinition.affectsState) = false, the operation is also able to be invoked by performing an HTTP GET operation where all of the values of the parameters are appended to the URL in the search portion of the URL (e.g., after the '?' character). Servers SHALL support this method of invocation. E.g.
GET \[base\]/ValueSet/$expand?url=http://hl7.org/fhir/ValueSet/body-site&filter=abdo
When using the HTTP GET operation, if there is a repeating parameter for the extended operation the values for that parameter are repeated by repeating the named parameter. e.g., Observation $stats statistic parameter
GET \[base\]/Observation/$stats?subject=Patient/123&code=55284-4&system=http://loinc.org&duration=1&statistic=average&statistic=min&statistic=max&statistic=count
If an operation has exactly one input parameter whose type is a FHIR Resource and all other parameters a client intends to submit are [simple parameters](#executing), then the client MAY invoke the operation via POST with the input resource as the request body and additional parameters as query parameters. Servers SHALL support this means of invocation of the operation.
Servers MAY choose to support submission of the parameters represented in [multi-part/form-data](https://www.ietf.org/rfc/rfc2388.txt) format as well, which can be useful when testing an operation using HTML forms.
#### Operation Response
If an operation succeeds, an HTTP Status success code is returned. Servers SHALL return the appropriate status code. This will usually be a 2xx code, though it may also be a 303 See Other. Other kinds of 3xx codes should be understood to indicate that the operation did not proceed, and the client will need to re-issue the operation if it can perform the redirection (e.g., may get redirected to an authentication step). User agents should note that servers may issue redirects, etc. to authenticate the client in response to an operation request. An HTTP status code of 4xx or 5xx indicates an error, and an [OperationOutcome](operationoutcome) SHOULD be returned with details. Note that an OperationOutcome indicating a failure returned by one of these HTTP codes is not wrapped in a Parameters resource.
In general, an operation response uses the same [Parameters](parameters) format whether there is only one or there are multiple named _out_ parameters.
If there is only one _out_ parameter, which is a single Resource with the parameter name "return" then the parameter format is not used, and the response is simply the resource itself. Note that this is true when the expected response is an OperationOutcome.
The result of an operation is subject to [content negotiation like any other interaction](http#mime-type). Specifically, if the returned resource is a Binary, the response SHALL behave in the same manner as if a 'read' operation had been performed on the resource. i.e., The content will be returned as either a FHIR resourse with base64-encoded content or as a raw binary, depending on the Accept header specified when invoking the operation (see [Serving Binary Resources using the RESTful API](binary#rest) ).
The resources that are returned by the operation may be retained and made available in the resource repository on the operation server. In that case, the server will provide the identity of the resource in the returned resources. When resources that are not persisted are returned in the response, they will have no `id` property.
### Executing an Operation Asynchronously
Use the [standard RESTful API Asynchronous pattern](async) to execute operations asynchronously.
\[%file newfooter%\]