The thing a browser could not do
Classic DICOM networking was specified in 1993, for fixed machines on a trusted hospital network. Two systems open a long-lived association, negotiate which object types and encodings they will accept, and exchange messages over a raw TCP socket. It works extremely well, and it has one property that disqualifies it from anything built after about 2005: a browser cannot open a raw socket, and an ephemeral container has no stable AE title to be pushed to.
DICOMweb is the answer to that. PS3.18 maps the same operations onto ordinary HTTP, so a web page, a mobile app, a serverless function or a Python script can take part without implementing the DICOM Upper Layer Protocol. Same objects, same identifiers, same information model. An instance retrieved over WADO-RS is byte for byte the instance a C-MOVE would have delivered.
The interesting difference is not the syntax. It is that DIMSE requires both peers to know each other in advance, by title, address and port, configured by hand, while DICOMweb requires the client to know a URL and hold a credential. That is the whole reason cloud and browser architectures could not use the older protocol and can use this one.
Path plus suffix, and the API becomes guessable
The URI design has one good idea in it, and once you see it the rest stops needing to be memorised. The path names a place in the DICOM hierarchy, from studies down through series and instances to individual frames. The suffix names what you want back. The two are orthogonal, so almost every suffix works at almost every level and you can guess a URL you have never seen.
Seven suffixes are defined: metadata, rendered, thumbnail, bulkdata, pixeldata, renderedmpr and rendered3d. PS3.18 designates none of them mandatory and none optional, so a server can be entirely conformant while implementing almost none of them, which is close to what the cloud services actually do. Frame numbers are a comma-separated list that the standard requires in ascending order, a constraint many clients quietly violate and some servers quietly enforce.
The rule that will bite you
A 202 from STOW-RS does not mean queued. It means partial success: some instances stored, some failed.
The only way to know which is to parse the response, which is itself a DICOM data set. ReferencedSOPSequence lists what was stored, FailedSOPSequence lists what was not, and each failure carries a reason. A 202 with an empty ReferencedSOPSequence means nothing was stored at all. Pipelines that check the status code and move on have been dropping studies for years, and nobody notices until a radiologist does.
Metadata first, pixels on demand
A modern CT study is two gigabytes, and no browser is going to download it to show one slice. Every serious DICOMweb client therefore does the same thing: ask for the metadata, build the entire interface out of it, then fetch pixels as the user scrolls.
It works because a retrieve is permitted to replace a large attribute value with a reference. The metadata for a study of four hundred instances comes back as a few hundred kilobytes of JSON with the pixel data expressed as a BulkDataURI, and the client fetches slice 204 as one half-megabyte request when the radiologist asks for it. The series list, the slice count, the window presets and the geometry all come out of the JSON before a single pixel moves.
The catch is that PS3.18 permits that substitution without requiring it. It sets no size threshold and names no obligation, so the same instance can produce a four-kilobyte metadata response from one server and a forty-megabyte one from another, both conformant. If your client’s memory budget assumes the small case, measure it against the other one before you ship.
DICOM JSON is faithful, not friendly
The JSON model in PS3.18 Annex F is a faithful representation of a DICOM data set, deliberately shaped after the XML Native DICOM Model so that a system can support both without retooling. It is not the JSON an application developer would have designed, and the differences are exactly where the bugs live.
- Keys are uppercase hex tags. Lowercase is a common bug, and it fails by finding nothing rather than by raising anything.
- Every value is an array. Whatever the multiplicity, single values included. Person names are objects rather than strings, which catches people out separately.
- Exactly one of three members carries the value. Value, BulkDataURI or InlineBinary, never two of them. A parser that looks only for Value reads pixel data as absent.
- Empty is three different things. An attribute with no Value member at all, a JSON null inside a multi-valued attribute, and an empty object inside a sequence. They mean "not sent", "sent as blank" and "an empty item in a list", and a client that conflates them loses clinical meaning without erroring.
- Numbers may arrive as strings. IS, DS, SV and UV may be encoded either way, because the standard permits strings to preserve original formatting or avoid losing precision. Your parser has to accept both.
Search, and a breaking change most people missed
QIDO-RS is the direct descendant of C-FIND and inherits its matching semantics wholesale. Two things about it are worth knowing before you write a client against one.
The first is a live behavioural break. From 2013 until DICOM 2025e, a search with zero results returned 204 No Content. From the 2026a edition that row is gone, and zero results return 200 with an empty array. A client that branches on 204 to mean "nothing found" will start reading empty results as successes against a current server, and it still needs the 204 path for older ones. Handle both, because you will meet servers of both vintages for years.
The second is that six search resources are defined and you may not be given all six. A native origin server must implement every one; a server proxying a classic DIMSE archive may omit three, and the three it may omit are the relational forms. Those are precisely the queries that find every series matching a criterion without naming a study first, and precisely the ones a gateway fronting an old archive is least likely to have. It is the first capability to test for, not a footnote.
One parameter worth knowing
In classic DICOM the encoding of the pixels is agreed during association negotiation. Over HTTP there is no association, so it moves into content negotiation as a parameter on the media type. It is a small mechanism with large performance consequences.
Name a transfer syntax and the server transcodes if it must, or returns 406 if it cannot. Name none and you get the default for that resource, with no idea what encoding is about to arrive. Send transfer-syntax=* and you are telling the server to hand over whatever it already has, which on a large retrieval is the difference between streaming bytes off disk and re-encoding several hundred megabytes to satisfy a preference you never actually had.
Two encodings are prohibited outright on the web: Implicit VR Little Endian, and the retired Explicit VR Big Endian. The one encoding every DIMSE system is required to support is the one the web services forbid.
The four gaps
Everything above is the easy part. The three core services are genuinely simple and an engineer can be productive against them in a day, and that is not where projects go wrong. They go wrong at four edges the standard deliberately leaves open, and all four have the same shape: PS3.18 declines to specify something, every implementation fills the gap differently, and the difference only surfaces when you try to move between two of them.
| The gap | What PS3.18 provides | What you will actually build |
|---|---|---|
| Authorization | Nothing. Access control, authorization and auditing are stated to be beyond its scope | Cloud IAM and OAuth bearer tokens, IHE IUA on premise, or a reverse proxy validating tokens in front of an archive with no concept of a user |
| Bulk export | Nothing. There is no transaction for "give me everything", and the ZIP retrieval proposal was cancelled | Three clouds, three proprietary import and export APIs, none of which resembles another |
| Third-party delivery | No equivalent of C-MOVE. SEND-RS is still in work, and nothing is published | Pull the study yourself and store it onward, or proxy a C-MOVE through a gateway. Either way the bytes cross your compute and you pay the egress |
| Capability discovery | OPTIONS on the base URI, returning a WADL document | Read the vendor conformance statement, hard-code per-vendor behaviour, and find the rest by trial and error |
None of these is an oversight. Each is a scoping decision by a committee that did not want to specify security, or could not agree on bulk semantics. The cost lands entirely on implementers, and it is not evenly distributed: it lands hardest on anyone trying to be portable across two vendors.
The discovery gap is worth one further sentence, because it shapes everything downstream. WADL is a W3C Member Submission from 2009 that the wider industry abandoned in favour of OpenAPI, so capability discovery is rarely implemented and almost never used. That is why comparing two servers is a document you have to read rather than a call your client can make.
Security, or its absence
The authorization gap deserves its own heading, because the situation is more absolute than most people realise and because assuming the standard handles it has produced real exposure.
PS3.18 states in its scope that security is out of scope, and refers you to PS3.15. It does carry a short security and privacy section, but that section is about protected health information rather than authentication: it observes that DICOM objects very likely contain it, that HIPAA and GDPR apply, and that satisfying them is the implementer’s responsibility. It warns that rendered volumes may contain recognisable facial features. It says nothing about TLS, OAuth, bearer tokens or the Authorization header, and neither does anything else in the part. Authorization appears in none of the header field tables.
DICOMweb defines two status codes for authentication failure, requires you to document whatever you did in a conformance statement, and stops. Every access-control decision in your imaging architecture is yours to design, and there is no standard your vendor is failing to meet.
What "DICOMweb support" buys you
All three major clouds sell a managed DICOM service and all three advertise DICOMweb support. The phrase means considerably less than it sounds like. All three implement store, search and retrieve; all three drop the URI service, non-patient instances and capability discovery; only one of them ships a worklist. The evidence is also asymmetric, because only Google publishes an explicit list of what it does not support, so the other two are silence rather than denial.
Three architectural facts matter more than any individual row. AWS transcodes on ingest, because its native model is image sets rather than DICOM instances and the storage format is fixed when the data store is created. Google accepts the broadest codec list and transcodes on retrieve. Azure has the only real worklist and no HTJ2K at all, which matters directly if you were planning progressive loading in a browser viewer.
The portability lesson sits underneath all three. Every one of them has a proprietary layer larger and more capable than its DICOMweb layer, and those are the features you will end up using and the ones that will not move. Budget for the rewrite, or confine yourself to store, search and retrieve and accept the performance you get.
Getting there from DIMSE
The common situation is not greenfield. It is a hospital with a DIMSE-only archive, a modality fleet that speaks nothing else, and a requirement to expose imaging to a web application, a cloud pipeline or an AI vendor. Nobody is replacing the PACS to achieve that, so the answer is a translation layer, and it takes one of three shapes: a gateway speaking DICOMweb outward and DIMSE inward, a dual-stack archive if a replacement is already on the roadmap for other reasons, or an edge collector writing to object storage for a cloud service to ingest from.
Translation is not free, and its cost is rarely where you look for it. Google documents that any C-FIND query on ModalitiesInStudy becomes one QIDO-RS query per modality, which is a fan-out nobody expects and which will surprise anyone migrating a worklist-heavy or dashboard-heavy workflow.
Whichever shape you choose, the decision that actually matters is where the identity boundary sits. A gateway that translates protocol but not authorization leaves you with an archive that trusts anything on the network and a proxy that has quietly become your entire access-control system. Design that deliberately, because nothing in DICOMweb will do it for you.
Where this sits
DICOMweb is not a separate standard. It is the web face of the one Part 1 covers, and the objects, identifiers, UID rules and pixel transformations described there apply unchanged on this side of the wire. Part 1 covers the imaging standard underneath it, Part 2 the profiles that turn conformant products into a working department, and Part 4 the other REST API in healthcare, whose first impression is misleading in very nearly the same way.
The full 23-page paper goes further in every direction: the twenty-year lineage and the branch that was abandoned, UPS-RS and the worklist that dispatches a study to an inference service, the rendered and volumetric resources, HTJ2K and what resolution-major ordering makes possible, the supplements added since 2020, building a viewer against a real archive, and nine expensive mistakes ordered by what each has cost.