Skip to content

DICOM Conformance Statement for Kastoria Health DICOMweb Service

Introduction

This document describes the DICOM conformance statement for the Kastoria Health DICOMweb Service. A DICOM Conformance Statement is a technical document that describes how a device or software implements the DICOM standard.

The Kastoria Health DICOMweb Service supports a subset of the DICOMweb Standard for medical imaging data management. Support includes:

  • Studies Service
  • Store (STOW-RS)
  • Retrieve (WADO-RS)
  • Search (QIDO-RS)

The service exposes a REST API following the DICOMweb standard (DICOM PS3.18).

Service Base URL

The service base URL follows the pattern:

https://{host}/

A GET /health endpoint is provided for liveness checks, and GET / returns basic server information.

Authorization

The Retrieve (WADO-RS) and Search (QIDO-RS) transactions support study-scoped access with viewer JSON Web Tokens (JWTs). Authorization is off by default and is enabled per deployment. When it is enabled:

  • Every WADO-RS and QIDO-RS request must carry Authorization: Bearer <jwt>. A missing, malformed, invalid or expired token is refused with 401 (Unauthorized).
  • The token's studyInstanceUIDs claim is the authorization scope. A request whose path names a Study Instance UID outside that scope is refused with 403 (Forbidden).
  • Study search (GET /studies) returns only studies within the scope; a token whose scope is empty receives an empty result.
  • A scope containing * grants every study.

Store (STOW-RS) requests are not subject to viewer-token authorization.

See JWT Authorization for the token format, claims and verification rules.

Studies Service

The Studies Service allows users to store, retrieve, and search for DICOM Studies, Series, and Instances.

Store (STOW-RS)

This transaction 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

Parameter study corresponds to the DICOM attribute StudyInstanceUID. If specified, any instance that doesn't belong to the provided study is reported as a failure with failure reason 272 (PS3.18 §6.6.1.2).

Responses are always returned as:

  • application/dicom+json

The following Content-Type headers are supported:

  • multipart/related; type="application/dicom"
  • application/dicom

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 — see Transfer Syntax Support). 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.

Two transfer syntaxes are normalized before any rule is evaluated: instances arriving as Deflated Explicit VR Little Endian (1.2.840.10008.1.2.1.99) or Explicit VR Big Endian (1.2.840.10008.1.2.2) are re-encoded losslessly to Explicit VR Little Endian, and it is that re-encoding the service stores — these two syntaxes are never a stored syntax. All data element values, including pixel data, are preserved, though the bytes are re-serialized as Explicit VR Little Endian: a big-endian instance comes back with every multi-byte value in little-endian byte order, and an out-of-order dataset comes back re-sorted into ascending tag order. The file meta group is rewritten by the encoder and carries its implementation UID rather than the sender's. An instance whose deflated stream does not decode is rejected like any other unparseable input.

Ingest-time 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 (Deflated and Big Endian inputs are still normalized to Explicit VR Little Endian)

Store Required Attributes

Each DICOM file must be parseable as a DICOM Part 10 file, and the following DICOM elements are required to be present:

  • StudyInstanceUID (0020,000D)
  • SeriesInstanceUID (0020,000E)
  • SOPInstanceUID (0008,0018)
  • TransferSyntaxUID (0002,0010)

Note:

  • SOPClassUID (0008,0016) is extracted on a best-effort basis; instances lacking it are still accepted
  • No UID format/length validation is performed beyond presence checks
  • Files that fail parsing or are zero-length are reported in the FailedSOPSequence with failure reason 272

Store Response 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

Store Response Payload

The response payload populates 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 successfully stored
(0008,1198) FailedSOPSequence The sequence of instances that failed to store
(0008,1199) ReferencedSOPSequence The sequence of stored instances

Each dataset in the 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 the 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 DICOM server

Note on Retrieve URLs: For POST /studies (without a study UID), the top-level study RetrieveURL is only included when all stored instances belong to a single study.

Retrieve URL 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 a RetrieveURL is dereferenced by whoever receives it, it is never built from an unverified request header. If the base URL is not configured for a deployment, store responses from that service 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.

Store 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

Retrieve (WADO-RS)

This transaction offers support for retrieving stored studies, series, instances, frames, metadata, rendered images, and thumbnails by reference.

Method Path Description
GET /studies/{study} Retrieve all instances within a study
GET /studies/{study}/metadata Retrieve metadata for all instances within a study
GET /studies/{study}/series/{series} Retrieve all instances within a series
GET /studies/{study}/series/{series}/metadata Retrieve metadata for all instances within a series
GET /studies/{study}/series/{series}/instances/{instance} Retrieve a single instance
GET /studies/{study}/series/{series}/instances/{instance}/metadata Retrieve metadata for a single instance
GET /studies/{study}/series/{series}/instances/{instance}/frames/{frames} Retrieve one or many frames from a single instance (comma-separated frame numbers, 1-indexed)
GET /studies/{study}/series/{series}/instances/{instance}/rendered Retrieve an instance rendered into an image format (renders frame 0)
GET /studies/{study}/series/{series}/instances/{instance}/frames/{frames}/rendered Retrieve frame(s) rendered into an image format
GET /studies/{study}/series/{series}/instances/{instance}/thumbnail Retrieve a thumbnail of an instance (renders frame 0)
GET /studies/{study}/series/{series}/instances/{instance}/frames/{frames}/thumbnail Retrieve thumbnail(s) of frame(s)

Retrieve Instances Within Study or Series

The following Accept headers are supported for retrieving instances:

  • multipart/related; type="application/dicom"
  • application/dicom
  • application/*
  • */* (defaults to multipart/related; type="application/dicom")

The transfer-syntax Accept-header parameter (PS3.18 §8.7.3.5.2) is supported. When a specific transfer syntax is requested and differs from the stored one, each instance is transcoded on the fly before being returned. transfer-syntax=* (or omitting the parameter) returns instances in their stored transfer syntax (which may be the result of ingest-time transcoding — see Store). Each part's Content-Type carries a transfer-syntax parameter identifying the actual returned syntax (PS3.18 §8.7.9). An unsupported requested transfer syntax results in 406 Not Acceptable.

Retrieve an Instance

The following Accept headers are supported for retrieving a specific instance:

  • multipart/related; type="application/dicom"
  • application/dicom
  • application/*
  • */* (defaults to multipart/related; type="application/dicom")

The transfer-syntax Accept-header parameter is supported as described above — the instance is transcoded when the requested syntax differs from the stored one.

Retrieve Frames

The following Accept headers are supported for retrieving frames:

  • multipart/related - returns multipart/related; type="<frame media type>" with appropriate media type based on the instance's transfer syntax
  • application/octet-stream
  • application/*
  • */*

The frame media type is derived from the returned transfer syntax:

  • application/octet-stream - Uncompressed
  • image/dicom-rle - RLE Lossless
  • image/jpeg - JPEG Baseline or JPEG Lossless
  • image/jls - JPEG-LS
  • image/jp2 - JPEG 2000
  • image/jxl - JPEG XL
  • image/jphc - High-Throughput JPEG 2000

A single-part response carries the frame media type, not application/octet-stream. A request for one frame under Accept: */* against a JPEG-encoded instance is answered Content-Type: image/jpeg; only an instance in an uncompressed transfer syntax is answered application/octet-stream. There is no single-part media type this service falls back to — the bytes are the stored frame, and the header names what they actually are.

A request naming more than one frame is always answered as multipart/related, whatever the Accept header allows, because separate frames need separate body parts (PS3.18 §10.4.3).

The Accept header is checked against every frame media type this service can produce, not against the one this instance will produce. A request with Accept: application/octet-stream for a JPEG-encoded frame is therefore answered 200 with Content-Type: image/jpeg rather than 406. A client that can only decode one encoding should name the transfer syntax it wants with the transfer-syntax Accept-header parameter, which does govern what comes back. That parameter is read from a multipart/related, application/dicom, application/* or */* media range only — carried on a concrete image media type such as image/jpeg, it is ignored.

The transfer-syntax Accept-header parameter is supported. When a specific transfer syntax is requested and differs from the stored one, frames are transcoded on the fly and the frame media type reflects the target syntax. transfer-syntax=* (or omitting the parameter) returns frames in their stored format. An unsupported requested transfer syntax results in 406 Not Acceptable.

Retrieve Metadata (for Study, Series, or Instance)

The following Accept header is supported for retrieving metadata:

  • application/dicom+json, or a wildcard that covers it (application/*, */*, or no Accept header at all)

Metadata is returned in DICOM JSON format as defined in PS3.18 Annex F.

Compression: Metadata responses are served gzip-compressed when the client sends Accept-Encoding: gzip.

Note: Bulk pixel data (PixelData, 7FE0,0010) is never included in metadata responses; retrieve it via the frames or instance endpoints.

Retrieve Rendered Image (for Instance or Frame)

The following Accept headers are supported for retrieving a rendered image:

  • image/png
  • image/jpeg
  • image/bmp
  • image/* (defaults to PNG)
  • */* (defaults to PNG)
  • multipart/related or application/octet-stream (defaults to PNG) — accepted so a client that names only a container gets a rendered image rather than a 406

The service renders the specified instance or frame(s) into the requested image format. For instance endpoints, frame 0 is rendered. Multiple frames are returned as multipart/related with individual image parts.

Supported Query Parameters:

Parameter Format Description
viewport vw,vh[,sx,sy,sw,sh] Scaling dimensions (vw, vh: required positive integers, with vw×vh at most 16,777,216). Optional crop, all four values or none: sx, sy non-negative integers, sw, sh positive integers; the source region is extracted before scaling
window center,width,function Windowing parameters. center and width must be numbers; function must be linear or sigmoid
quality 1-100 JPEG quality (integer 1-100, applies only to JPEG output)

Priority: Image formats are selected in priority order: PNG > JPEG > BMP

Retrieve Thumbnail (for Instance or Frame)

The following Accept headers are supported for retrieving a thumbnail:

  • image/jpeg (default per DICOM spec)
  • image/png
  • image/bmp
  • image/* (defaults to JPEG)
  • */* (defaults to JPEG)
  • multipart/related or application/octet-stream (defaults to JPEG) — accepted so a client that names only a container gets a thumbnail rather than a 406

The service generates a thumbnail of the specified instance or frame(s). For instance endpoints, frame 0 is rendered. Multiple frames are returned as multipart/related with individual image parts.

Supported Query Parameters:

Parameter Format Description
viewport vw,vh Thumbnail dimensions (width and height are required positive integers, with vw×vh at most 1,048,576). Defaults to 128,128

Priority: Image formats are selected in priority order: JPEG > PNG > BMP

Retrieve Response Status Codes

Code Description
200 (OK) All requested data was retrieved successfully
400 (Bad Request) Invalid query parameters (e.g., malformed viewport, window, or quality value, or a non-integer frame number), or a /rendered or /thumbnail request naming more frames than the service is configured to render at once
401 (Unauthorized) Authorization is enabled and the request carries no valid bearer token; see Authorization
403 (Forbidden) Authorization is enabled and the requested study is not in the token's scope; see Authorization
404 (Not Found) The specified DICOM resource could not be found, or the instance does not contain pixel data for rendered/thumbnail requests
406 (Not Acceptable) The specified Accept header is not supported, or a requested transfer-syntax cannot be transcoded to
500 (Internal Server Error) The server encountered an unexpected error (if a mid-stream error occurs after headers are sent, the connection is torn down instead)

Search (QIDO-RS)

Query based on ID for DICOM Objects (QIDO) enables searching for studies, series and instances by attributes.

Method Path Description
GET /studies Search for studies
GET /studies/{study}/series Search for series in a study
GET /studies/{study}/instances Search for instances in a study
GET /studies/{study}/series/{series}/instances Search for instances in a series

The following Accept header is supported for searching:

  • application/dicom+json, or a wildcard that covers it (application/*, */*, or no Accept header at all)

Index Requirements

Search queries are served from search indexes that are maintained automatically by a background study-processing stage after instances are stored.

Important: Newly stored studies become searchable once this processing has completed. Queries against studies that have not yet been processed return an empty array.

Supported Search Parameters (Study-Level)

The following query parameters are supported for study-level searches:

Parameter Support Description
StudyInstanceUID Direct lookup Unique study identifier
PatientID Exact match, case-insensitive Patient identifier
StudyDate Single date or range Study date in YYYYMMDD format. Supports single date (20240101) or range (20240101-20240131, 20240101-, -20240131)
PatientName Leading components, case-insensitive Patient's name in DICOM PN form. The value names leading components and each matches whole: DOE matches DOE^JOHN, DOE^JOHN matches DOE^JOHN^Q but not DOE^JOHNSON. Matched against the alphabetic component group
StudyTime Single time or range Study time in DICOM TM format, HH[MM[SS[.FFFFFF]]]. Supports single time (143000) or range (080000-170000, 080000-, -170000)
AccessionNumber Exact match, case-insensitive Accession number
StudyDescription Exact match, case-insensitive Study description
ModalitiesInStudy List; matches any one modality, ignoring case Modality (e.g. CT, MR). A list separated by \ or , is an IN clause — the study matches when any of its modalities equals any listed value
limit Supported (default 100, maximum 1000) Maximum number of matches returned in one response
offset Supported (default 0, maximum 1000) Number of matches skipped before the first returned one. A value above the maximum is rejected with 400, not capped

Search Matching

The service supports the following matching types:

Search Type Supported Attributes Example
Range Query StudyDate, StudyTime StudyDate=20240101-20240131 - Inclusive range. Either bound may be omitted (e.g., StudyDate=20240101- or StudyDate=-20240131)
Exact Match StudyInstanceUID, PatientID, AccessionNumber, StudyDescription, ModalitiesInStudy PatientID=PATIENT001
Leading Components PatientName PatientName=DOE matches DOE^JOHN — the value names leading PN components and each matches whole, so this is not an exact match on the full name

Note:

  • A zero-length value is universal matching (PS3.4 §C.2.2.2.1): PatientName= places no constraint and every study matches. It is neither an error nor an ignored parameter, so it carries no Warning header field — a universal matcher selects everything by definition
  • Matching ignores case for every attribute except StudyInstanceUID, which is a UID: aa-1234 and AA-1234 are one identifier, and chris and CHRIS are one person
  • StudyTime values are compared by the instant they denote, so a query and a stored value written to different precision (090000 and 090000.000000) match
  • The upper bound of a StudyTime range runs to the end of the unit it names, matching the way a StudyDate upper bound runs to the end of its day. -235959 includes a study acquired at 235959.500, and -0900 includes one at 090030. An explicit fraction names an instant instead, so -090030.000 ends exactly there
  • Each query parameter must be supplied at most once. A repeated parameter — PatientID=A&PatientID=B — is rejected with 400 Bad Request naming the parameter
  • A StudyTime naming the whole day — 000000-235959, 000000-, -235959, or a bare - — narrows nothing and is treated as absent rather than searched for

Attribute ID

Query parameter keys may be encoded as either of the following (per PS3.18 §8.3.4.1):

Value Example
{group}{element} 0020000D
{dicomKeyword} StudyInstanceUID

Response Pagination

Both search transactions implement response pagination per PS3.18 §8.3.4.4.

Parameter Default Behavior
offset 0 Number of matches skipped before the first returned match; an explicit value above 1000 is rejected with 400
limit 100 Maximum matches returned in one response; an explicit value above 1000 is capped

maxResults (PS3.18 §8.3.4.4.1) is 1000 — the ceiling on an explicit limit, so no single response returns more than 1000 matches. A request that supplies no limit receives 100.

When matches remain beyond those returned, the response carries a Warning header field:

Warning: 299 {service}: There are more additional results that can be requested

The header announces that a further page can be requested. It does not carry a count of the matches not returned.

Search Depth

A search that combines two or more matching attributes is limited in how far back it reaches, but only where it has to be. Naming anything selective — a patient identifier, an accession number — settles the search almost at once, and it is then answered in full however old the matches are. The limit is reached only when every attribute named is a broad one.

Where a search is limited, the response is 200 (OK) and carries a Warning header field naming the earliest study date covered:

Warning: 299 {service}: Searched studies from 20241216 onward; earlier matches may exist

Results from that date onward are complete. Nothing is claimed about studies before it.

A PatientName search names no date. A PatientName filter matches leading components, so it is answered from a range covering every name built on them — and inside that range entries are ordered by name before date, so the search reaches the second patient only after exhausting the first. Where such a search is limited, the warning states the limit without dating it:

Warning: 299 {service}: The search was limited before every matching study was examined; further matches may exist

Both spellings mean the same thing to a caller: the result set is not known to be complete. Only the first tells you from when it is.

A search on a single matching attribute is not limited at all, and neither is a search on none. Both are answered in full — a search for a modality last acquired three years ago returns it.

An empty result set carries the warning too, when the search was limited. 200 (OK) with an empty array and no Warning header means no study matches. 200 (OK) with an empty array and this warning means no study matches within the range searched. These are different answers, and they are distinguished by the header rather than by the payload.

An explicit StudyDate narrows the search but does not remove the limit. It is the most effective thing a caller can supply: it bounds every attribute at once, so a search that names a date is normally answered in full and carries no warning whatever attributes accompany it.

A caller needing a longer history for a broad combination of attributes should page through it by date, a range at a time.

Unsupported Query Parameters

A query parameter this service does not match on is accepted, ignored, and announced. The response is 200 (OK) and carries a Warning header field naming every parameter that was ignored:

Warning: 299 {service}: The following query parameters are not supported and were ignored: PatientSex\StudyID

This applies to both search transactions, and to any parameter other than that level's matching attributes listed above and the limit / offset controls — including an attribute the service returns but cannot match on, and a parameter it does not recognize at all. The result set is therefore wider than the request asked for: the ignored parameter narrowed nothing.

A 400 is not used here. PS3.18 reserves it for a query the service cannot parse, and PS3.4 §C.2.2.1.3 permits an Optional Key to be returned without being matched on — so a well-formed query the service can only partly honor is answered, with the shortfall stated.

Parameter names are separated by \, the DICOM multi-valued delimiter, rather than by a comma. Warning is a comma-delimited list field, so a comma inside one warn-text would make two warnings impossible to tell apart.

A name this service cannot repeat back is reported as (unprintable). DICOM keywords and Attribute IDs are alphanumeric, so a parameter name outside that shape is not one this service defines, and echoing it would place caller-supplied text — a line break included — into a header field. The substitution keeps the count honest: the caller is still told how many of its parameters were ignored, even where one of them cannot be named. The parentheses are what make the token impossible to mistake for an Attribute ID.

Warning: 299 {service}: The following query parameters are not supported and were ignored: PatientSex\(unprintable)

Both warnings are sent when both apply — a query naming an ignored attribute can still overflow its page — as two warn-values, the query's shortcoming before the response's:

Warning: 299 {service}: The following query parameters are not supported and were ignored: PatientSex
Warning: 299 {service}: There are more additional results that can be requested

Both parameters must be non-negative integers. A malformed value is rejected with 400 Bad Request rather than ignored — silently dropping a limit would return the full result set to a caller that asked for one page.

offset may not exceed 1000 — the same ceiling as limit, so a request may skip no more than it may retrieve — and a larger one is rejected with 400 Bad Request rather than capped. Paging is offset-based with no cursor, so reaching a match means loading every match in front of it, and a skipped match costs the same storage reads as a returned one. A caller needing to go deeper should narrow the query rather than page further into an unnarrowed one.

limit is capped rather than rejected because a capped page is still a prefix of the page requested, and the Warning header says more remains — whereas a capped offset would silently answer with a different page than the one asked for.

Results are ordered by study date and time, most recent first. One exception:

  • A search on PatientName that names fewer components than the stored name — SMITH matching SMITH^JOHN — is ordered most-recent-first within each matching patient, but is not ordered by date across several patients sharing those leading components.

Notes for Client Implementers

Do not treat 200 (OK) with an empty array as definitive without checking for a Warning header field. A search limited to a window returns the same empty payload whether nothing matches at all or nothing matches recently. The header is the only distinction.

Treat a 299 warning as information, not an error. It accompanies a successful response and does not indicate a failed or degraded search. A response may carry more than one — an ignored parameter, a limited window, and further pages available are independent conditions and can all apply at once.

To search a longer history, page by date rather than widening the range. Take the date the warning names, and issue the next request with a StudyDate range ending the day before it. Repeat until a response arrives without the warning, or until far enough back to stop. Each request is bounded, and together they cover the history without any single request being expensive.

Supply a StudyDate whenever one is known. It bounds every attribute at once, which is both faster and the surest way to receive a complete answer rather than a limited one.

Prefer StudyInstanceUID when it is known. It is answered as a direct lookup, without reading any index.

Supported Search Parameters (Series-Level)

The following query parameters are supported for series-level searches within a study:

Parameter Support Description
Modality List; matches any one, ignoring case Filter by modality. A list separated by \ or , is an IN clause
SeriesInstanceUID Exact match Filter by series UID (a UID has no case to ignore)
SeriesNumber Exact match Filter by series number
limit Supported (default 100, maximum 1000) Maximum number of matches returned in one response
offset Supported (default 0, maximum 1000) Number of matches skipped before the first returned. A value above the maximum is rejected with 400, not capped

Supported Search Parameters (Instance-Level)

The following query parameters are supported for instance-level searches, both within a series and within a whole study:

Parameter Support Description
SOPInstanceUID Exact match Filter by SOP Instance UID (a UID has no case to ignore)
InstanceNumber Exact match Filter by instance number
SeriesInstanceUID Exact match Filter by series UID. On the study-level endpoint this narrows the search to one series; on the series-level endpoint the series is already fixed by the path, so asking for a different one returns an empty array
limit Supported (default 100, maximum 1000) Maximum number of matches returned in one response
offset Supported (default 0, maximum 1000) Number of matches skipped before the first returned. A value above the maximum is rejected with 400, not capped

Instance-level searches do not use the search indexes, but they read data built by the same study-processing stage described under Index Requirements. As with series-level searches, a study that has not yet been processed returns an empty array.

Search Response

The response is an array of DICOM datasets in DICOM JSON format. The following attributes are returned by default for study-level searches:

Default Study Tags:

Tag Attribute Name
(0020,000D) StudyInstanceUID
(0010,0020) PatientID
(0010,0010) PatientName
(0010,0030) PatientBirthDate
(0010,0040) PatientSex
(0020,0010) StudyID
(0008,0020) StudyDate
(0008,0030) StudyTime
(0008,0050) AccessionNumber
(0008,0061) ModalitiesInStudy
(0008,1030) StudyDescription
(0020,1206) NumberOfStudyRelatedSeries
(0020,1208) NumberOfStudyRelatedInstances

Default Series Tags:

Tag Attribute Name
(0020,000D) StudyInstanceUID
(0020,000E) SeriesInstanceUID
(0020,0011) SeriesNumber
(0008,0005) SpecificCharacterSet
(0008,0060) Modality
(0008,0021) SeriesDate
(0008,0031) SeriesTime
(0008,103E) SeriesDescription
(0008,0070) Manufacturer
(0008,0080) InstitutionName
(0008,0090) ReferringPhysicianName
(0008,1090) ManufacturerModelName
(0018,0015) BodyPartExamined
(0018,1030) ProtocolName
(0020,1209) NumberOfSeriesRelatedInstances

Default Instance Tags:

The minimum set of PS3.18 Table 10.6.3-5, returned by both instance-level searches:

Tag Attribute Name
(0008,0016) SOPClassUID
(0008,0018) SOPInstanceUID
(0020,000D) StudyInstanceUID
(0020,000E) SeriesInstanceUID
(0020,0013) InstanceNumber
(0028,0008) NumberOfFrames

Note: The service does not currently support the includefield parameter to return additional attributes beyond the defaults.

Search Response Status Codes

Code Description
200 (OK) The response payload contains all matching resources (an empty array when there are no matches)
400 (Bad Request) The query cannot be honored as written: a range that cannot match (a StudyDate range whose end precedes its start), a limit or offset that is not a non-negative integer, an offset above 1000, or a query parameter supplied more than once
401 (Unauthorized) Authorization is enabled and the request carries no valid bearer token; see Authorization
403 (Forbidden) Authorization is enabled and a request for a study by UID, or for anything beneath it (series, instances, frames, metadata, etc.), names a Study Instance UID that is not in the token's scope; see Authorization
406 (Not Acceptable) The specified Accept header does not allow application/dicom+json
500 (Internal Server Error) The server encountered an unexpected error

Search Notes

  • An empty result set is returned with 200 (OK) and an empty JSON array — 204 (No Content) is not used
  • A 200 (OK) always means the search ran to completion. A search that fails part-way through returns 500, and never a partial or empty array with 200 — a client must be able to distinguish "no studies match" from "the search could not be completed". A query the service cannot satisfy because of how it is written returns 400, so a caller can tell its own mistake from the server's.
  • A 200 (OK) does not by itself mean every parameter was applied. Two things narrow what the payload holds relative to what was asked, and both are stated in a Warning header field rather than left for the client to infer:
  • A parameter this service does not match on is ignored, so the result set is wider than the request — see Unsupported Query Parameters.
  • Matches beyond limit are not returned, so the result set is narrower than the whole match set — see the maxResults note above.

A response carrying no Warning header field is complete in every sense: every parameter was applied, no match was left behind, and no limit was placed on how far back the search reached.

Technical Specifications

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).

Uncompressed:

  • 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) — accepted on ingest, stored as Explicit VR Little Endian (see Ingest-Time Transcoding); available as a retrieve target
  • 1.2.840.10008.1.2.1.99 (Deflated Explicit VR Little Endian) — accepted on ingest, stored as Explicit VR Little Endian (see Ingest-Time Transcoding); not available as a retrieve target

Compressed:

  • 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. Rules are evaluated against the post-normalization transfer syntax, so an instance sent as Deflated or Big Endian Explicit VR is evaluated as Explicit VR Little Endian:

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.

Retrieve-Time Transcoding

WADO-RS retrieve endpoints (study, series, instance, and frames) honor the transfer-syntax Accept-header parameter. When the requested transfer syntax differs from the stored one, the service transcodes on the fly using the same transfer syntax support table above. Deflated Explicit VR Little Endian is not offered as a retrieve target. Transcoding between any other pair of supported transfer syntaxes is available, Explicit VR Big Endian included; requesting an unsupported transfer syntax (or one for which no codec is available) results in 406 Not Acceptable.

Character Set Support

The service supports all DICOM-defined character sets.

Limitations and Known Issues

Current Limitations

The following optional features are not supported:

  1. Wildcard Matching: The optional wildcard matching capability is not supported, and wildcard characters (*, ?) are not treated as wildcards in any search parameter. For attributes with a PN VR, PS3.4 §C.2.2.2.4 makes wildcard matching implementation dependent and requires the position to be stated here.

  2. QIDO-RS includefield: The optional includefield parameter (PS3.18 §8.3.4.3) to return additional attributes beyond defaults is not currently supported.

  3. Rendered Image Viewport Cropping: Only the numeric sx,sy,sw,sh form (PS3.18 §8.3.5.1.3) is supported. Empty crop sub-values (which the standard defines as defaulting to 0 or the image edge) and negative sw/sh (which the standard defines as a horizontal/vertical flip) are rejected with 400 rather than honored.

  4. ETag/Cache Validation: ETag headers and If-None-Match cache validation (optional per PS3.18 §8.3.3) are not supported for metadata endpoints.

  5. Fuzzy Matching: Fuzzy matching (optional per PS3.18 §10.6.3.2) is not supported in any search parameters.

References

  1. DICOM Standard PS3.18 – Web Services
  2. DICOMweb Overview

DICOM® is the registered trademark of the National Electrical Manufacturers Association for its standards publications relating to digital communications of medical information.