The DICOM Proxy provides comprehensive REST APIs that follow DICOMweb standards along with proprietary proxy APIs for advanced functionality. All APIs support JSON responses and standard HTTP status codes.
Base URL: http://localhost:8080
(or configured HTTP port)
Base URL (SSL): https://localhost:8443
(or configured HTTPS port)
Interactive API documentation is available at:
GET /openapi.json
When authentication is enabled, include credentials in the Authorization header:
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
For programmatic access, use API key in header:
X-API-Key: your-api-key-here
Query for DICOM objects using standard QIDO-RS endpoints.
GET /wado/studies
Query Parameters:
StudyDate
- Study date range (format: YYYYMMDD
or YYYYMMDD-YYYYMMDD
)StudyTime
- Study time range (format: HHMMSS
or HHMMSS-HHMMSS
)AccessionNumber
- Accession numberPatientID
- Patient identifierPatientName
- Patient name (supports wildcards)StudyInstanceUID
- Study instance UIDStudyID
- Study IDModalitiesInStudy
- Modalities (comma-separated)InstitutionName
- Institution nameReferringPhysicianName
- Referring physicianlimit
- Maximum number of results (default: 100)offset
- Result offset for paginationExample Request:
curl "http://localhost:8080/wado/studies?PatientName=DOE*&StudyDate=20240101-20241231&limit=50"
Example Response:
[
{
"00080020": {"Value": ["20240315"], "vr": "DA"},
"00080030": {"Value": ["143000.000"], "vr": "TM"},
"00080050": {"Value": ["ACC001"], "vr": "SH"},
"00080061": {"Value": ["CT"], "vr": "CS"},
"00080090": {"Value": ["Dr. Smith"], "vr": "PN"},
"0020000D": {"Value": ["1.2.3.4.5.6.7.8.9"], "vr": "UI"},
"00100010": {"Value": [{"Alphabetic": "Doe^John"}], "vr": "PN"},
"00100020": {"Value": ["123456"], "vr": "LO"},
"00200010": {"Value": ["ST001"], "vr": "SH"}
}
]
GET /wado/studies/{studyInstanceUID}/series
Path Parameters:
studyInstanceUID
- Study instance UIDQuery Parameters:
Modality
- Series modalitySeriesNumber
- Series numberSeriesInstanceUID
- Series instance UIDBodyPartExamined
- Body part examinedSeriesDescription
- Series descriptionlimit
- Maximum number of resultsoffset
- Result offsetExample Request:
curl "http://localhost:8080/wado/studies/1.2.3.4.5.6.7.8.9/series?Modality=CT"
GET /wado/studies/{studyInstanceUID}/series/{seriesInstanceUID}/instances
Path Parameters:
studyInstanceUID
- Study instance UIDseriesInstanceUID
- Series instance UIDQuery Parameters:
SOPInstanceUID
- SOP instance UIDInstanceNumber
- Instance numberlimit
- Maximum number of resultsoffset
- Result offsetRetrieve DICOM objects and metadata.
GET /wado/studies/{studyInstanceUID}
Accept Headers:
application/dicom
- DICOM Part 10 formatmultipart/related; type="application/dicom"
- Multipart DICOMapplication/json
- JSON metadataGET /wado/studies/{studyInstanceUID}/series/{seriesInstanceUID}
GET /wado/studies/{studyInstanceUID}/series/{seriesInstanceUID}/instances/{sopInstanceUID}
GET /wado/studies/{studyInstanceUID}/metadata
GET /wado/studies/{studyInstanceUID}/series/{seriesInstanceUID}/metadata
GET /wado/studies/{studyInstanceUID}/series/{seriesInstanceUID}/instances/{sopInstanceUID}/metadata
Example Response:
[
{
"00080018": {"Value": ["1.2.3.4.5.6.7.8.9.10"], "vr": "UI"},
"00080016": {"Value": ["1.2.840.10008.5.1.4.1.1.2"], "vr": "UI"},
"00200013": {"Value": ["1"], "vr": "IS"},
"00280010": {"Value": [512], "vr": "US"},
"00280011": {"Value": [512], "vr": "US"},
"00280030": {"Value": [0.5, 0.5], "vr": "DS"}
}
]
GET /wado/studies/{studyInstanceUID}/series/{seriesInstanceUID}/instances/{sopInstanceUID}/rendered
Query Parameters:
viewport
- Image dimensions (format: width,height
)window
- Window center and width (format: center,width
)quality
- JPEG quality (1-100)Accept Headers:
image/jpeg
- JPEG formatimage/png
- PNG formatimage/gif
- GIF formatStore DICOM objects via HTTP.
POST /wado/studies
Content-Type: multipart/related; type="application/dicom"
POST /wado/studies/{studyInstanceUID}
Content-Type: multipart/related; type="application/dicom"
Example Request:
curl -X POST \
-H "Content-Type: multipart/related; type=\"application/dicom\"" \
--data-binary @study.dcm \
http://localhost:8080/wado/studies
Test connectivity to a configured PACS server.
POST /proxy/echo/{serverid}
Path Parameters:
serverid
- Server ID from configurationExample Request:
curl -X POST http://localhost:8080/proxy/echo/pacs1
Example Response:
{
"success": true,
"server_id": "pacs1",
"response_time_ms": 45,
"status": "Success"
}
Store DICOM objects to a specific PACS server.
POST /proxy/cstore/{serverid}
Content-Type: application/dicom
Path Parameters:
serverid
- Server ID from configurationExample Request:
curl -X POST \
-H "Content-Type: application/dicom" \
--data-binary @image.dcm \
http://localhost:8080/proxy/cstore/pacs1
Query a specific PACS server using QIDO-RS format.
GET /proxy/wado/{serverid}/rs/studies
GET /proxy/wado/{serverid}/rs/studies/{studyInstanceUID}/series
GET /proxy/wado/{serverid}/rs/studies/{studyInstanceUID}/series/{seriesInstanceUID}/instances
Path Parameters:
serverid
- Server ID from configurationQuery Parameters: Same as standard QIDO-RS parameters
Retrieve objects from a specific PACS server.
GET /proxy/wado/{serverid}/rs/studies/{studyInstanceUID}
GET /proxy/wado/{serverid}/rs/studies/{studyInstanceUID}/series/{seriesInstanceUID}
GET /proxy/wado/{serverid}/rs/studies/{studyInstanceUID}/series/{seriesInstanceUID}/instances/{sopInstanceUID}
GET /api/status
Example Response:
{
"service_name": "DICOM Proxy",
"version": "1.09.1",
"uptime_seconds": 3600,
"dicom_port": 11112,
"http_port": 8080,
"https_enabled": false,
"storage_path": "C:\\DicomStorage",
"studies_count": 1542,
"series_count": 8967,
"instances_count": 234567,
"storage_used_gb": 156.7,
"storage_available_gb": 843.3,
"license_status": "Valid",
"license_expires": "2025-12-31"
}
GET /api/connections
Example Response:
{
"active_dicom_connections": 5,
"total_dicom_connections": 1234,
"active_http_connections": 12,
"configured_servers": [
{
"id": "pacs1",
"name": "Main PACS Server",
"status": "Connected",
"last_echo": "2024-03-15T14:30:00Z",
"response_time_ms": 23
}
]
}
GET /api/config
PUT /api/config
Example Response (GET):
{
"dicom_port": 11112,
"http_port": 8080,
"https_port": 8443,
"max_connections": 50,
"storage_quota_gb": 1000,
"cleanup_enabled": true,
"this_modality": {
"ae_title": "DICOMPROXY",
"port": 11112,
"ip_address": "0.0.0.0"
}
}
GET /api/servers
POST /api/servers
PUT /api/servers/{serverid}
DELETE /api/servers/{serverid}
Example Server Object:
{
"id": "pacs1",
"name": "Main PACS Server",
"ae_title": "MAINPACS",
"hostname": "192.168.1.100",
"port": 11112,
"enabled": true,
"max_connections": 10,
"timeout_seconds": 30,
"priority": 1,
"supported_services": ["C-STORE", "C-FIND", "C-GET", "C-MOVE", "C-ECHO"]
}
GET /api/database/studies
GET /api/database/series/{studyInstanceUID}
GET /api/database/instances/{studyInstanceUID}/{seriesInstanceUID}
DELETE /api/database/studies/{studyInstanceUID}
POST /api/database/cleanup
POST /api/database/reindex
GET /api/metrics
Example Response:
{
"timestamp": "2024-03-15T14:30:00Z",
"performance": {
"cpu_usage_percent": 12.5,
"memory_usage_mb": 512,
"disk_io_read_mbps": 45.2,
"disk_io_write_mbps": 23.1,
"network_in_mbps": 15.7,
"network_out_mbps": 22.3
},
"dicom_stats": {
"c_store_requests_per_minute": 45,
"c_find_requests_per_minute": 12,
"c_get_requests_per_minute": 8,
"c_move_requests_per_minute": 3,
"c_echo_requests_per_minute": 20,
"average_response_time_ms": 150
},
"http_stats": {
"requests_per_minute": 67,
"average_response_time_ms": 89,
"error_rate_percent": 0.5
}
}
Support for TUS protocol for large file uploads.
POST /files/
PATCH /files/{upload-id}
HEAD /files/{upload-id}
Headers:
Tus-Resumable: 1.0.0
Upload-Length: <file-size>
Upload-Metadata: filename <base64-encoded-filename>
Code | Description | Usage |
---|---|---|
200 | OK | Successful request |
201 | Created | Resource created successfully |
204 | No Content | Successful request with no content |
400 | Bad Request | Invalid request parameters |
401 | Unauthorized | Authentication required |
403 | Forbidden | Insufficient permissions |
404 | Not Found | Resource not found |
409 | Conflict | Resource conflict (duplicate) |
422 | Unprocessable Entity | Invalid DICOM data |
500 | Internal Server Error | Server error |
503 | Service Unavailable | Service temporarily unavailable |
{
"error": {
"code": "INVALID_DICOM_DATA",
"message": "The DICOM file contains invalid data",
"details": "Missing required tag: PatientID (0010,0020)",
"timestamp": "2024-03-15T14:30:00Z",
"request_id": "req-123456"
}
}
Code | Description |
---|---|
INVALID_PARAMETERS |
Request parameters are invalid |
INVALID_DICOM_DATA |
DICOM data is invalid or corrupted |
STORAGE_FULL |
Storage quota exceeded |
SERVER_UNREACHABLE |
Configured PACS server unreachable |
LICENSE_EXPIRED |
Software license has expired |
AUTHENTICATION_FAILED |
Authentication credentials invalid |
RATE_LIMIT_EXCEEDED |
Too many requests |
The API implements rate limiting to prevent abuse:
X-RateLimit-Limit
: Request limitX-RateLimit-Remaining
: Remaining requestsX-RateLimit-Reset
: Reset time (Unix timestamp)For endpoints that return multiple results, pagination is supported:
Request Parameters:
limit
- Number of results per page (default: 100, max: 1000)offset
- Starting position (default: 0)Response Headers:
X-Total-Count
: Total number of resultsLink
: Pagination links (next, prev, first, last)Example Link Header:
Link: </wado/studies?limit=100&offset=0>; rel="first",
</wado/studies?limit=100&offset=100>; rel="next",
</wado/studies?limit=100&offset=900>; rel="last"
Request Content Types:
application/dicom
- DICOM Part 10 filesmultipart/related; type="application/dicom"
- Multipart DICOMapplication/json
- JSON dataapplication/x-www-form-urlencoded
- Form dataResponse Content Types:
application/json
- JSON responsesapplication/dicom
- DICOM filesmultipart/related; type="application/dicom"
- Multipart DICOMimage/jpeg
- JPEG imagesimage/png
- PNG imagestext/plain
- Plain text responsesSupported DICOM transfer syntaxes:
const axios = require('axios');
class DicomProxyClient {
constructor(baseUrl = 'http://localhost:8080') {
this.baseUrl = baseUrl;
}
async searchStudies(params = {}) {
const response = await axios.get(`${this.baseUrl}/wado/studies`, { params });
return response.data;
}
async getStudy(studyInstanceUID) {
const response = await axios.get(
`${this.baseUrl}/wado/studies/${studyInstanceUID}`,
{ headers: { 'Accept': 'application/json' } }
);
return response.data;
}
async storeStudy(dicomBuffer) {
const response = await axios.post(
`${this.baseUrl}/wado/studies`,
dicomBuffer,
{ headers: { 'Content-Type': 'application/dicom' } }
);
return response.data;
}
}
import requests
import json
class DicomProxyClient:
def __init__(self, base_url='http://localhost:8080'):
self.base_url = base_url
def search_studies(self, **params):
response = requests.get(f'{self.base_url}/wado/studies', params=params)
return response.json()
def get_study(self, study_instance_uid):
headers = {'Accept': 'application/json'}
response = requests.get(
f'{self.base_url}/wado/studies/{study_instance_uid}',
headers=headers
)
return response.json()
def store_study(self, dicom_bytes):
headers = {'Content-Type': 'application/dicom'}
response = requests.post(
f'{self.base_url}/wado/studies',
data=dicom_bytes,
headers=headers
)
return response.json()
using System;
using System.Net.Http;
using System.Threading.Tasks;
using System.Text.Json;
public class DicomProxyClient
{
private readonly HttpClient _httpClient;
private readonly string _baseUrl;
public DicomProxyClient(string baseUrl = "http://localhost:8080")
{
_baseUrl = baseUrl;
_httpClient = new HttpClient();
}
public async Task<JsonDocument> SearchStudiesAsync(Dictionary<string, string> parameters = null)
{
var queryString = parameters != null
? string.Join("&", parameters.Select(p => $"{p.Key}={p.Value}"))
: "";
var url = $"{_baseUrl}/wado/studies?{queryString}";
var response = await _httpClient.GetStringAsync(url);
return JsonDocument.Parse(response);
}
public async Task<JsonDocument> GetStudyAsync(string studyInstanceUID)
{
_httpClient.DefaultRequestHeaders.Accept.Clear();
_httpClient.DefaultRequestHeaders.Accept.Add(
new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json")
);
var response = await _httpClient.GetStringAsync($"{_baseUrl}/wado/studies/{studyInstanceUID}");
return JsonDocument.Parse(response);
}
}
For more examples and tutorials, see the Examples & Tutorials documentation.