STOW-RS — Store Instances
The Store transaction (PS3.18 §10.5)
uses the POST method to store representations of studies, series, and
instances contained in the request payload.
| Method | Path | Description |
|---|---|---|
| POST | /studies |
Store instances |
| POST | /studies/{study} |
Store instances for a specific study |
The study path parameter corresponds to the DICOM attribute
StudyInstanceUID (0020,000D). When it is specified, any instance in the
payload that does not belong to that study is reported as a failure with
failure reason 272 (PS3.18 §6.6.1.2).
Authorization
Store requests are not subject to viewer-token authorization, even when it is enabled for the read interfaces. See JWT Authorization.
Request
Content-Type
The request payload must use one of the following Content-Type headers:
multipart/related; type="application/dicom"— one part per DICOM instance; use this to store multiple instances in one requestapplication/dicom— a single DICOM instance
A multipart/related payload that names no boundary results in
500 (Internal Server Error).
Required instance attributes
Each DICOM file must be parseable as a DICOM Part 10 file, and the following elements must be present:
| Tag | Attribute |
|---|---|
| (0020,000D) | StudyInstanceUID |
| (0020,000E) | SeriesInstanceUID |
| (0008,0018) | SOPInstanceUID |
| (0002,0010) | TransferSyntaxUID |
Notes:
SOPClassUID(0008,0016) is extracted on a best-effort basis; instances lacking it are still accepted- No UID format or length validation is performed beyond presence checks
- Files that fail parsing or are zero-length are reported in the
FailedSOPSequencewith failure reason272
Ingest-time transcoding
Unlike a pass-through store, the service may transcode pixel data at ingest time according to rules evaluated against the instance's metadata (modality, transfer syntax, frame parameters such as bits allocated/stored, rows, columns, and photometric interpretation).
By default, instances of modalities CR, CT, DX, MG, and MR — and
losslessly-encoded NM, OT, PT, RF, SM, and US instances — are transcoded to
High-Throughput JPEG 2000 with RPCL Options (Lossless Only,
1.2.840.10008.1.2.4.202). All other DICOM attributes are stored as provided.
See Transfer syntax support for the full list of
recognized transfer syntaxes and the rule table.
Transcoding can be disabled per request with the header:
| Header | Accepted values | Description |
|---|---|---|
x-kastoria-disable-transcode |
true |
Store instances in their original transfer syntax without transcoding |
Response
Responses are always returned as application/dicom+json, populated as a
DICOM dataset with the following elements:
| Tag | Name | Description |
|---|---|---|
| (0008,1190) | RetrieveURL |
The retrieve URL of the study, if StudyInstanceUID was provided and at least one instance was stored successfully |
| (0008,1198) | FailedSOPSequence |
The sequence of instances that failed to store |
| (0008,1199) | ReferencedSOPSequence |
The sequence of stored instances |
Each dataset in FailedSOPSequence has the following elements:
| Tag | Name | Description |
|---|---|---|
| (0008,1150) | ReferencedSOPClassUID |
The SOP class UID of the instance that failed to store |
| (0008,1155) | ReferencedSOPInstanceUID |
The SOP instance UID of the instance that failed to store |
| (0008,1197) | FailureReason |
The reason code why this instance failed to store |
Each dataset in ReferencedSOPSequence has the following elements:
| Tag | Name | Description |
|---|---|---|
| (0008,1150) | ReferencedSOPClassUID |
The SOP class UID of the instance that was stored (omitted when unavailable) |
| (0008,1155) | ReferencedSOPInstanceUID |
The SOP instance UID of the instance that was stored |
| (0008,1190) | RetrieveURL |
The retrieve URL of this instance on the service |
Retrieve URLs
RetrieveURL tags are omitted entirely when the base URL cannot be determined.
The authoritative base URL for retrieval from the DICOMweb service is configured
in the service deployment. As RetrieveURL is dereferenced by whoever receives
it, it will never be built from an unverified request header.
If the base URL is not configured for a deployment, store responses from that
service will carry no (0008,1190) at either level. The store itself still
succeeds and the response is otherwise unchanged — the instances are stored and
listed in the ReferencedSOPSequence, without a URL to fetch them back by.
For POST /studies (without a study UID in the path), the top-level study
RetrieveURL is only included when all stored instances belong to a single
study.
Failure reason codes
| Code | Description |
|---|---|
272 (0x0110) |
Processing failure — used for all store failures, including parse failures, zero-length parts, storage errors, and instances whose StudyInstanceUID does not match the study UID stated in the request path |
Status codes
| Code | Description |
|---|---|
200 (OK) |
All the SOP instances in the request were stored successfully |
202 (Accepted) |
Some instances were stored successfully, others failed. Details are in the response body |
400 (Bad Request) |
The provided Content-Type is neither multipart/related nor application/dicom |
409 (Conflict) |
None of the instances in the store transaction request were stored |
500 (Internal Server Error) |
The server encountered an unexpected error, including a multipart/related Content-Type that names no boundary |
Examples
Store a single instance
curl -X POST "http://localhost:3000/studies" \
-H "Content-Type: application/dicom" \
-H "Accept: application/dicom+json" \
--data-binary @instance.dcm
Store multiple instances into a specific study
curl -X POST "http://localhost:3000/studies/1.2.840.113619.2.55.3.604688119.868.1234567890.1" \
-H 'Content-Type: multipart/related; type="application/dicom"; boundary=BOUNDARYZ' \
-H "Accept: application/dicom+json" \
--data-binary $'--BOUNDARYZ\r\nContent-Type: application/dicom\r\nContent-Transfer-Encoding: binary\r\n\r\n' \
--data-binary @file1.dcm \
--data-binary $'\r\n--BOUNDARYZ\r\nContent-Type: application/dicom\r\nContent-Transfer-Encoding: binary\r\n\r\n' \
--data-binary @file2.dcm \
--data-binary $'\r\n--BOUNDARYZ--\r\n'
Successful response
All instances stored. The study-level RetrieveURL is present when the base
URL is configured for the deployment:
{
"00081190": { "vr": "UR", "Value": ["https://dicom.example.com/studies/1.2.840.113619.2.55.3.604688119.868.1234567890.1"] },
"00081199": {
"vr": "SQ",
"Value": [
{
"00081150": { "vr": "UI", "Value": ["1.2.840.10008.5.1.4.1.1.2"] },
"00081155": { "vr": "UI", "Value": ["1.2.840.113619.2.55.3.12345.1"] },
"00081190": {
"vr": "UR",
"Value": [
"https://dicom.example.com/studies/1.2.840.113619.2.55.3.604688119.868.1234567890.1/series/1.2.840.113619.2.55.3.604688119.868.1234567890.2/instances/1.2.840.113619.2.55.3.12345.1"
]
}
}
]
}
}
Partial-failure response
202 (Accepted) — one instance stored, one failed. The failure appears in
FailedSOPSequence with failure reason 272:
{
"00081190": { "vr": "UR", "Value": ["https://dicom.example.com/studies/1.2.840.113619.2.55.3.604688119.868.1234567890.1"] },
"00081198": {
"vr": "SQ",
"Value": [
{
"00081150": { "vr": "UI", "Value": ["1.2.840.10008.5.1.4.1.1.2"] },
"00081155": { "vr": "UI", "Value": ["1.2.840.113619.2.55.3.12345.2"] },
"00081197": { "vr": "US", "Value": [272] }
}
]
},
"00081199": {
"vr": "SQ",
"Value": [
{
"00081150": { "vr": "UI", "Value": ["1.2.840.10008.5.1.4.1.1.2"] },
"00081155": { "vr": "UI", "Value": ["1.2.840.113619.2.55.3.12345.1"] },
"00081190": {
"vr": "UR",
"Value": [
"https://dicom.example.com/studies/1.2.840.113619.2.55.3.604688119.868.1234567890.1/series/1.2.840.113619.2.55.3.604688119.868.1234567890.2/instances/1.2.840.113619.2.55.3.12345.1"
]
}
}
]
}
}
Transfer syntax support
The following transfer syntaxes are recognized for ingest-time transcoding decisions. Transfer syntaxes not in this list are stored as-is (no transcoding is attempted). The same set governs retrieve-time transcoding.
Uncompressed:
| UID | Name |
|---|---|
1.2.840.10008.1.2 |
Implicit VR Little Endian |
1.2.840.10008.1.2.1 |
Explicit VR Little Endian |
1.2.840.10008.1.2.2 |
Explicit VR Big Endian |
Compressed:
| UID | Name |
|---|---|
1.2.840.10008.1.2.5 |
RLE Lossless |
1.2.840.10008.1.2.4.50 |
JPEG Baseline Process 1 |
1.2.840.10008.1.2.4.57 |
JPEG Lossless, Non-Hierarchical |
1.2.840.10008.1.2.4.70 |
JPEG Lossless, Non-Hierarchical, First-Order Prediction |
1.2.840.10008.1.2.4.80 |
JPEG-LS Lossless |
1.2.840.10008.1.2.4.81 |
JPEG-LS Lossy |
1.2.840.10008.1.2.4.90 |
JPEG 2000 Lossless Only |
1.2.840.10008.1.2.4.91 |
JPEG 2000 |
1.2.840.10008.1.2.4.110 |
JPEG XL Lossless |
1.2.840.10008.1.2.4.112 |
JPEG XL |
1.2.840.10008.1.2.4.201 |
High-Throughput JPEG 2000 Lossless Only |
1.2.840.10008.1.2.4.202 |
High-Throughput JPEG 2000 with RPCL Options Lossless Only |
1.2.840.10008.1.2.4.203 |
High-Throughput JPEG 2000 |
Ingest transcoding rules
At store time, the first matching rule determines the target transfer syntax. If the instance is already in the target syntax (or no rule matches), it is stored unchanged:
| Modality | Condition | Target transfer syntax |
|---|---|---|
| CR, CT, DX, MG, MR | Always | 1.2.840.10008.1.2.4.202 (HTJ2K RPCL Lossless Only) |
| NM, OT, PT, RF, SM, US | Source transfer syntax is lossless | 1.2.840.10008.1.2.4.202 (HTJ2K RPCL Lossless Only) |
Transcoding can be disabled per request with the
x-kastoria-disable-transcode: true header.
See also
- WADO-RS — Retrieve Instances — the stored instances are retrieved by reference using the URLs returned here
- QIDO-RS — Search for Instances — note that a stored study becomes searchable only after background processing has completed