Skip to main content

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​

EnvironmentBase URLPurpose
Productionhttps://d1nxuh43hp41jj.cloudfront.net/v1Live clinical data
Sandboxhttps://d1dl1uoy9jq97u.cloudfront.net/v1Integration 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:

  1. Create an order (POST /new-order) — returns a UUIDv4 order ID that identifies the study for its entire lifetime.
  2. Upload the imaging data — via a single PUT or a multipart upload. Completing the upload starts processing.
  3. Poll for status (GET /status) until processing reaches a terminal state.
  4. 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 sizeMethodEndpoints
Under 5 MBSingle PUTGET /upload/single-put
5 MB or largerMultipartPOST /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.gz file with its corresponding .bvec and .bval files.

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​

  1. POST /upload/multipart/initiate — returns the parameters used by the remaining calls.
  2. POST /upload/multipart/presigned-urls — returns one presigned URL per chunk. Maximum 100 chunks per upload.
  3. PUT each chunk to its presigned URL, retaining the returned ETag for each part.
  4. POST /upload/multipart/complete — supply the part numbers and ETags. This starts processing.
  5. 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:

  1. The API — POST /new-order at creation, or PATCH /add-metadata afterwards.
  2. DICOM tags embedded in the uploaded study.
  3. 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​

StatusTerminalMeaning
RECEIVEDNOUpload successfully received
QUEUEDNOOrder queued for processing
PENDINGNOOrder status is pending
ELIGIBILITY_CHECK_RUNNINGNOQuality control in-progress
PREPROCESSINGNOOrder is processing
PREPROCESSING_FAILEDYESOrder processing failed
ANALYSIS_RUNNINGNOML analysis running
IN_REVIEWNOBlocked on a manual review
DELIVEREDYESResults successfully delivered
FAILEDYESOrder failed processing
CANCELLEDYESOrder cancelled by the user
EXPIREDYESOrder is expired and can no longer be retrieved
QC_FAILEDYES/NOOrder failed QC processing, can be bypassed by the user
QC_PASSEDNOOrder passed QC
QC_BYPASSNOQC 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_typeFormatDescription
PDFPDFHuman-readable visual PDF report, can be embedded into a DICOM encapsulated PDF
PNGPNGHuman-readable visual PNG image
JSONJSONMachine-readable structured report
XMLXMLMachine-readable structured report
TXTTXTHuman-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.

  1. POST /new-batch — creates the batch and returns a UUIDv4 ID.
  2. 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​

StatusMeaningAction
400Malformed request or invalid metadataFix the request; do not retry unchanged
401Missing, expired, or invalid tokenRequest a new token and retry once
403Token valid but lacks scope for this resourceDo not retry; check RBAC assignment
404Unknown order or study UIDDo not retry
429Rate limitedBack off and retry
5xxTransient service errorRetry 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.8
Release

The Neuropacs REST API now provides product device identifiers and descriptions, along with improved failure report retrieval.

The Neuropacs REST API now provides product device identifiers and descriptions, along with improved failure report retrieval.

  • Added UDI and fda_desc fields to GET /v1/products, providing each product’s FDA Unique Device Identifier and device description, where available. Both fields are documented in the API specification and return null when not assigned.
  • Fixed GET /v1/failure-report retrieval 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.7
Release

The Neuropacs REST API now supports dedicated QC report retrieval, per-order QC bypass requests, and report synchronization from registered Agents.

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-report to download QC findings or acquisition details using report_type=results or report_type=additional_info. Select the QC round using round=latest, original, or corrected; the response identifies the returned round in the X-QC-Round header. 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/reports so 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-report response 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_FAILED instead of FAILED and no longer generate a failure report. Retrieve QC findings through GET /v1/qc-report; update integrations that previously treated QC rejections as FAILED or expected a failure report.
  • Integration update: /v1/recent-activity now returns detail keys in camelCase, including orderId, statusDesc, and failureReason. Update integrations that use the previous key names.

Last updated: September 22, 2026