Overview

Once you have created an account and logged in, you can create an image store. Each image store has a unique label across all image stores, not just the ones owned by you.

Each image store is accessed via its label in the URL path: https://litevna.app/{label}/dicomweb. The label must be the first path component before /dicomweb and must match the image store associated with your API key.

API Keys & Tokens

Creating API Keys

Log in to your account at https://litevna.app, navigate to your image store, and create an API key. When creating an API key, you can configure:


Creating Scoped Tokens (Optional)

You can derive short-lived, scoped tokens from your API keys using the POST /image-stores/{label}/tokens/create endpoint:

POST /image-stores/{label}/tokens/create
Content-Type: application/json

{
  // API key from which to derive the token
  "api_key_value": "eyJhbGc...",
  "ttl": 3600,
  // optional   "scopes": {
    "study_ids": ["1.2.3.4.5"],
    "patient_ids": ["P12345"]
  }
}

Tokens:

Authentication Methods

All requests must include valid authentication. The [token] in the examples below can be either:

Five authentication methods are supported:

1. Authorization Header (Bearer)

Authorization: Bearer [token]

Standard OAuth 2.0 Bearer token format.

2. Authorization Header (Basic)

Use username "litevna" with the token as password:

Authorization: Basic [base64(litevna:token)]

Useful for tools that support Basic auth but not custom headers.

3. URL Path Prefix

Embed the token in the URL path before /dicomweb:

https://litevna.app/{label}/key_[token]/dicomweb/studies

Useful for direct links without header support (e.g., image tags, embedding in viewers).

4. Cookie

Set a cookie named litevna-token with the token value.

Automatically set when creating tokens via the web UI.

5. Query Parameter

Add the token as a query parameter:

https://litevna.app/{label}/dicomweb/studies?_auth_token=[token]

Enables "simple" cross-origin requests without CORS preflight. Query param excluded from cache key.

QIDO

To issue a QIDO request, use a path such as: https://litevna.app/{label}/dicomweb/studies?limit=100

WADO

To issue a WADO request, use a path with the pattern:

https://litevna.app/{label}/dicomweb/studies/[studyUID]/series/[seriesUID]/metadata

or

https://litevna.app/{label}/dicomweb/studies/[StudyInstanceUID]/series/[SeriesInstanceUID]/instances/[SOPInstanceUID]/frame/1
Rendered Frames

To retrieve a fully rendered frame as a PNG or JPEG image (with windowing, rescaling, and color space conversion applied), use:

GET https://litevna.app/{label}/dicomweb/studies/[StudyInstanceUID]/series/[SeriesInstanceUID]/instances/[SOPInstanceUID]/frames/[frameNumber]/rendered

Set the Accept header to control the output format:

Query Parameters

Example:

curl https://litevna.app/{label}/dicomweb/studies/[StudyUID]/series/[SeriesUID]/instances/[SOPInstanceUID]/frames/1/rendered \
  -H "Authorization: Bearer [token]" \
  -H "Accept: image/jpeg" \
  "?window=400,1500&width=512&quality=90"
DICOM Part 10

To download dicom part 10 file, set the Accept header to "application/dicom" on an instance level request, like:

GET https://litevna.app/{label}/dicomweb/studies/[StudyInstanceUID]/series/[SeriesInstanceUID]/instances/[SOPInstanceUID]
Accept: application/dicom

STOW

To store a dicom file (STOW), send a POST request to:

https://litevna.app/{label}/dicomweb/studies

Example:

curl -X POST https://litevna.app/{label}/dicomweb/studies \
  -H "Authorization: Bearer [token]" \
  -H "Content-Type: application/dicom" \
  --data-binary @/path/to/dicom-file.dcm

Large File Uploads (Presigned URL)

For files too large to POST directly (typically >100 MB), use the three-step presigned upload flow to bypass the request body size limit:

  1. Request an upload URL — POST to the {label}/dicomweb/studies/upload-url endpoint to obtain a short-lived presigned URL and an opaque uploadId:

    Request:

    POST https://litevna.app/{label}/dicomweb/studies/upload-url
    Authorization: Bearer [token]

    Response:

    {
      "uploadUrl": "https://...",
      "uploadId": "550e8400-e29b-41d4-a716-446655440000",
      "expiresAt": 1234567890000
    }

    The URL expires after 1 hour (expiresAt is a Unix timestamp in milliseconds).

  2. Upload the file — PUT the gzip-compressed DICOM bytes directly to the presigned URL. No authorization header is needed:

    PUT {uploadUrl}
    Content-Type: application/dicom
    Content-Encoding: gzip

    <gzip-compressed DICOM bytes>

    The file must be gzip-compressed before uploading.

  3. Trigger processing — After the upload has completed, POST to {label}/dicomweb/studies with the uploadId query parameter and no request body. LiteVNA will read the pre-uploaded file and process it, returning a result after the file has been processed, or an error if processing fails:
    POST https://litevna.app/{label}/dicomweb/studies?uploadId={uploadId}
    Authorization: Bearer [token]

Example (shell):

# Step 1 — get upload URL
RESP=$(curl -s -X POST https://litevna.app/{label}/dicomweb/studies/upload-url \
  -H "Authorization: Bearer [token]")
UPLOAD_URL=$(echo $RESP | jq -r .uploadUrl)
UPLOAD_ID=$(echo $RESP | jq -r .uploadId)

# Step 2 — gzip and upload the file
gzip -c /path/to/dicom-file.dcm > /tmp/dicom-file.dcm.gz
curl -X PUT "$UPLOAD_URL" \
  -H "Content-Type: application/dicom" \
  -H "Content-Encoding: gzip" \
  --data-binary @/tmp/dicom-file.dcm.gz

# Step 3 — trigger processing
curl -X POST "https://litevna.app/{label}/dicomweb/studies?uploadId=$UPLOAD_ID" \
  -H "Authorization: Bearer [token]"
DELETE

To delete a study, series, or instance and all child objects, send a DELETE request to the corresponding url, such as:

DELETE https://litevna.app/{label}/dicomweb/studies/[StudyInstanceUID]

or

DELETE https://litevna.app/{label}/dicomweb/studies/[StudyInstanceUID]/series/[SeriesInstanceUID]/instances/[SOPInstanceUID]
Made by Jason Hostetter