REST API
Overview
Our REST API ingestion option allows healthcare providers to upload DICOM imaging data securely and efficiently using AWS S3 presigned URLs. This approach leverages standard HTTPS calls to transfer files directly to cloud storage, enabling seamless integration with existing workflows.
This page is a conceptual guide: it covers authentication, the order lifecycle, upload strategy, metadata, and error handling. For per-endpoint request and response schemas, see the API Reference, which is generated from the service itself and is always authoritative.
Key Benefits
- Security: All endpoints require scoped OAuth2 Bearer tokens, ensuring least-privilege access. Time-limited, scoped presigned URLs ensure only authorized uploads.
- Flexibility: Compatible with standard HTTP clients, PACS, and custom tooling. Firewall-friendly.
- Access Control: Fine-grained Role-Based Access Control (RBAC) enforces user- and group-level permissions, aligning access with organizational policies.
Getting Access
API access is provisioned per organization. To request access, contact our support email support@neuropacs.com.
Credentials are issued either to a service account or a person, depending on the use case. Store them in a secrets manager and rotate them on your organization's normal schedule. Credential rotation can be performed self-service on the Neuropacs Web Portal.
Environments
| Environment | Base URL | Purpose |
|---|---|---|
| Production | https://d1nxuh43hp41jj.cloudfront.net/v1 | Live clinical data |
| Sandbox | https://d1dl1uoy9jq97u.cloudfront.net/v1 | Integration testing with non-PHI data |
All paths in this guide are relative to the base URL for your environment.
Authentication
We use OAuth2 client credentials. Every endpoint except the presigned upload URL itself requires a Bearer token.
Requesting a token
curl -X POST "$BASE_URL/auth/token" \
-u "$CLIENT_ID:$CLIENT_SECRET" \
-d "grant_type=client_credentials"
The response contains a Bearer token valid for one hour:
{
"access_token": "...",
"token_type": "Bearer",
"expires_in": 3600
}
Using a token
Include the token on every subsequent request:
curl "$BASE_URL/list-orders" -H "Authorization: Bearer $TOKEN"
GET /test-token validates a token without side effects and is useful as a connectivity check.
Token handling
- Cache the token and reuse it until shortly before expiry rather than requesting one per call.
- Refresh on expiry by requesting a new token; there is no refresh-token grant.
- Never embed credentials or tokens in client-side code, mobile apps, or anything distributed to end users. Tokens carry your organization's access.
The Order Lifecycle
Every study follows the same path:
- Create an order (
POST /new-order) — returns a UUIDv4 order ID that identifies the study for its entire lifetime. - Upload the imaging data — via a single PUT or a multipart upload. Completing the upload starts processing.
- Poll for status (
GET /status) until processing reaches a terminal state. - Retrieve the report (
GET /results) or, on failure, the failure report (GET /failure-report).
Orders can optionally be grouped into a batch for aggregated reporting; see Batches.
An order can be cancelled with PATCH /cancel-order while it is in progress. Cancellation is permanent and suspends all processing.
Uploading Studies
Choosing an upload method
| Study size | Method | Endpoints |
|---|---|---|
| Under 5 MB | Single PUT | GET /upload/single-put |
| 5 MB or larger | Multipart | POST /upload/multipart/* |
Most DICOM studies exceed 5 MB, so multipart is the common path. If you are writing a general-purpose client, implementing multipart alone is a reasonable choice.
Supported file types
- Individual DICOM files.
- ZIP archives containing either a complete DICOM study, or a
.nii/.nii.gzfile with its corresponding.bvecand.bvalfiles.
Review the technical specifications for imaging requirements, supported formats, and required tags before uploading.
- Maximum accepted study size: 10GB
Single upload
Request a presigned URL from GET /upload/single-put, then PUT the file directly to the returned URL. The PUT does not carry an Authorization header — the URL itself is the credential.
Multipart upload
POST /upload/multipart/initiate— returns the parameters used by the remaining calls.POST /upload/multipart/presigned-urls— returns one presigned URL per chunk. Maximum 100 chunks per upload.PUTeach chunk to its presigned URL, retaining the returnedETagfor each part.POST /upload/multipart/complete— supply the part numbers and ETags. This starts processing.POST /upload/multipart/abort— if you cannot finish, abort explicitly. Abandoned uploads leave an order that never processes.
Chunks may be uploaded in parallel.
- Chunk size range: 5 MB - 100 MB
- Recommended Chunk size: 10 MB
Presigned URL handling
Presigned URLs are time-limited, scoped, and write-only, and they require no additional authentication. Treat them as secrets: anyone holding a URL can write to that object until it expires. Do not log them, forward them, or store them beyond the life of the upload.
- Presigned URL expiry window: 1 hour
Metadata
Required metadata can arrive by any of three routes:
- The API —
POST /new-orderat creation, orPATCH /add-metadataafterwards. - DICOM tags embedded in the uploaded study.
- A JSON sidecar included in the uploaded archive.
Precedence: metadata supplied through the API overwrites conflicting values from DICOM tags or a sidecar.
PATCH /add-metadata accepts either identifier:
PATCH /add-metadata?order_id={orderID}
PATCH /add-metadata?study_uid={studyInstanceUID}
GET /metadata returns all metadata currently associated with an order.
Checking Status
GET /status?order_id={orderID}
GET /status?study_uid={studyInstanceUID}
If multiple orders correspond to one study UID, only the most recent is returned. Prefer order_id where you have it; it is unambiguous.
Status values
| Status | Terminal | Meaning |
|---|---|---|
RECEIVED | NO | Upload successfully received |
QUEUED | NO | Order queued for processing |
PENDING | NO | Order status is pending |
ELIGIBILITY_CHECK_RUNNING | NO | Quality control in-progress |
PREPROCESSING | NO | Order is processing |
PREPROCESSING_FAILED | YES | Order processing failed |
ANALYSIS_RUNNING | NO | ML analysis running |
IN_REVIEW | NO | Blocked on a manual review |
DELIVERED | YES | Results successfully delivered |
FAILED | YES | Order failed processing |
CANCELLED | YES | Order cancelled by the user |
EXPIRED | YES | Order is expired and can no longer be retrieved |
QC_FAILED | YES/NO | Order failed QC processing, can be bypassed by the user |
QC_PASSED | NO | Order passed QC |
QC_BYPASS | NO | QC failure bypassed by the user |
- Recommended polling interval: 5 minutes
- Typical processing time: 3 hours
GET /list-orders returns all active orders for your profile, including timestamps, status, and associations. Results are scoped by access level: standard users see their own orders; organization admins see all orders in their organization.
Retrieving Results
GET /results?order_id={orderID}&report_type={reportType}
GET /results?study_uid={studyInstanceUID}&report_type={reportType}
If processing failed, the corresponding failure report explains why:
GET /failure-report?order_id={orderID}&report_type={reportType}
Report types
report_type | Format | Description |
|---|---|---|
PDF | PDF | Human-readable visual PDF report, can be embedded into a DICOM encapsulated PDF |
PNG | PNG | Human-readable visual PNG image |
JSON | JSON | Machine-readable structured report |
XML | XML | Machine-readable structured report |
TXT | TXT | Human-readable textual report |
All report types can be embedded into alternative RIS formats such as:
- DICOM encapsulated PDF
- DICOM SR
- HL7v2
- HL7 FHIR
Batches
A batch groups related orders for tracking and aggregated reporting.
POST /new-batch— creates the batch and returns a UUIDv4 ID.PATCH /associate-order-to-batch— attaches an individual order to it.
Every order in a batch must be run with the same products list as the batch. A mismatch causes the association to fail.
GET /report?study_group={studyGroup}&report_type={reportType} returns the aggregated report for a group.
studyGroup is the UUIDv4 batch ID returned by POST /new-batch — the same value passed to PATCH /associate-order-to-batch. Retain it after creating a batch; it is the only way to retrieve the aggregated report.
Errors and Retries
| Status | Meaning | Action |
|---|---|---|
400 | Malformed request or invalid metadata | Fix the request; do not retry unchanged |
401 | Missing, expired, or invalid token | Request a new token and retry once |
403 | Token valid but lacks scope for this resource | Do not retry; check RBAC assignment |
404 | Unknown order or study UID | Do not retry |
429 | Rate limited | Back off and retry |
5xx | Transient service error | Retry with exponential backoff |
Retry 429 and 5xx responses with exponential backoff and jitter. Do not retry 4xx responses other than 401 without changing the request.
Limits
- Requests per minute: 2,000 requests/IP address/minute
- Requests per endpoint: 600 requests/endpoint/minute
- Maximum single-PUT size: 5 MB
- Maximum multipart chunks: 100
- Chunk size range: 5 MB - 100 MB
- Maximum study size: 10 GB
- Concurrent uploads: 100
API Reference
Per-endpoint request parameters, response schemas, and status codes are documented in our OpenAPI specification, which is generated from the service and is the authoritative reference.
Access to our OpenAPI specification can be requested by contacting our support email support@neuropacs.com.
Versioning
The API uses URL-based major versioning, with the version included in the request path, such as /v1/....
Backward-compatible changes may be introduced within an existing version, including new endpoints and optional fields. Integrations should tolerate additional response fields.
Breaking changes require a new major version. These include:
- Removing or renaming existing endpoints or fields.
- Adding required request parameters.
- Making incompatible changes to field types, response structures, status codes, or documented behavior.
- Changing authentication or authorization requirements in ways that require existing integrations to be updated.
Deprecation and retirement
When a replacement major version is released, all responses from the previous version include a warning header identifying its scheduled retirement date:
X-API-Deprecation-Warning: v1 will be deprecated on yyyy-mm-dd
Integrators receive at least 30 days advance notice before a version is retired. The previous version remains available during this notice period.
On the date specified in the warning header, the previous version stops serving API operations. Requests to that version return HTTP 410 Gone, with an error identifying the replacement version and a link to migration documentation. For example, when retiring /v1 in favor of /v2:
{
"error": "API version v1 is no longer supported. Please upgrade to /v2.",
"migration_guide": "https://neuropacs.github.io/neuropacs-docs/docs"
}
Integrators should monitor the deprecation warning header and complete migration before the announced retirement date.
Security and Compliance
- OAuth2 token authentication with short-lived, scoped Bearer tokens.
- Presigned URLs are write-only, scoped to a single object, and expire to limit exposure.
- Role-based IAM policies enforce least privilege for URL generation and storage access.
- All data in transit and at rest is encrypted.
- Detailed audit logs capture URL issuance and upload events for compliance monitoring.
See also our security & compliance documentation.
Releases
REST API Device Information and Failure Report Updates
v1.0.8ReleaseThe Neuropacs REST API now provides product device identifiers and descriptions, along with improved failure report retrieval.
REST API Device Information and Failure Report Updates
The Neuropacs REST API now provides product device identifiers and descriptions, along with improved failure report retrieval.
- Added
UDIandfda_descfields toGET /v1/products, providing each product’s FDA Unique Device Identifier and device description, where available. Both fields are documented in the API specification and returnnullwhen not assigned. - Fixed
GET /v1/failure-reportretrieval for institutions whose names contain spaces or punctuation. - Improved DICOM validation failure details to identify the affected file and the reason for rejection, including incomplete uncompressed pixel data.
REST API Quality Control and Reporting Updates
v1.0.7ReleaseThe Neuropacs REST API now supports dedicated QC report retrieval, per-order QC bypass requests, and report synchronization from registered Agents.
REST API Quality Control and Reporting Updates
The Neuropacs REST API now supports dedicated QC report retrieval, per-order QC bypass requests, and report synchronization from registered Agents.
- Added
GET /v1/qc-reportto download QC findings or acquisition details usingreport_type=resultsorreport_type=additional_info. Select the QC round usinground=latest,original, orcorrected; the response identifies the returned round in theX-QC-Roundheader. Read permission is required. - Added
PATCH /v1/qc-bypass?order_id=to request a QC bypass for an eligible order, with an optional reason. Requests can be withdrawn while the QC verdict is pending. Write permission is required, and manual review restrictions remain in effect. - Added
POST /v1/agent/reportsso registered Agents can synchronize QC and failure reports with the cloud. Uploaded reports are validated, and QC reports cannot be replaced while their review is open. - Agent heartbeat responses now include pending QC bypass requests for the Agent to apply locally.
- Documented all supported
GET /v1/failure-reportresponse formats: PDF, PNG, TXT, JSON, XML, and CSV. - Improved report retrieval for authorized administrators accessing orders across institutions.
- Integration update: Cloud QC rejections now use
QC_FAILEDinstead ofFAILEDand no longer generate a failure report. Retrieve QC findings throughGET /v1/qc-report; update integrations that previously treated QC rejections asFAILEDor expected a failure report. - Integration update:
/v1/recent-activitynow returns detail keys in camelCase, includingorderId,statusDesc, andfailureReason. Update integrations that use the previous key names.
Last updated: September 22, 2026