agentsclimarketplace

Orthanc api

Skill Lightbridge-KS/agent-skills/plugins/radiology/skills/orthanc-api

My Public Agent Skills

Install
npx -y skills add Lightbridge-KS/agent-skills --skill orthanc-api

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Reference for driving an Orthanc DICOM server through its REST API. Use this skill whenever a task involves Orthanc — uploading, browsing, searching, downloading, anonymizing, or modifying DICOM resources (patients/studies/series/instances) on a local or remote Orthanc; performing DICOM network operations through Orthanc such as C-ECHO, C-STORE, C-MOVE, C-GET, or Query/Retrieve (C-FIND) against remote modalities/PACS; configuring Orthanc peers or modalities; tracking changes; decoding instances to PNG/NumPy for AI pipelines; or running asynchronous Orthanc jobs. Trigger this even when the user only mentions an Orthanc URL (e.g. localhost:8042), 'the Orthanc REST API', or building a script/tool/pipeline that talks to Orthanc, even if no specific endpoint is named.

SKILL.md

7.1 KB, as published. Nobody here has run it

Orthanc REST API Reference

Orthanc is a lightweight, self-contained DICOM server. Its entire feature set is exposed over a RESTful HTTP API returning JSON — anything the Orthanc Explorer UI can do, the REST API can do. This skill is the working reference for that API.

Examples below use Python requests as the primary idiom (the common case for tooling and AI pipelines); curl is shown only where it is clearer, mainly for binary uploads.

Mental model

Orthanc organizes everything under the DICOM Patient → Study → Series → Instance hierarchy. Each resource has a stable Orthanc ID and links to its parent and children.

Patient ──< Study ──< Series ──< Instance
   │           │         │           └─ the actual DICOM file (1 image / object)
   │           │         └─ one acquisition (e.g. one CT sequence)
   │           └─ one imaging exam (one StudyInstanceUID)
   └─ one person

Navigate DOWN via child arrays:   GET /studies/{id}  → {"Series": [...]}
Navigate UP via parent fields:    GET /series/{id}   → {"ParentStudy": "..."}

The #1 source of bugs: two ID systems

┌──────────────────────────────────────────────────────────────────────┐
│  ORTHANC ID                  DICOM UID                                 │
│  5d4a3991-8a265cb2-...        1.2.840.113704.1.111...                   │
│  ──────────────────          ─────────────────────                     │
│  SHA-1–derived, stable        the DICOM-standard identity              │
│  Used in REST PATHS:          Used in C-FIND / C-MOVE / C-GET queries  │
│    /studies/{orthanc_id}        {"StudyInstanceUID": "1.2.840..."}     │
│  Returned by upload,          Lives in MainDicomTags                    │
│    /tools/find, /changes                                                │
│                                                                        │
│  Bridge between them:  POST /tools/lookup  (DICOM UID → Orthanc ID)    │
└──────────────────────────────────────────────────────────────────────┘

If a path 404s, the usual cause is feeding a DICOM UID where an Orthanc ID is expected (or vice versa). Use /tools/lookup to convert.

Two more recurring gotchas

LOCAL  vs  REMOTE      POST /tools/find          → searches Orthanc's OWN database
                       POST /modalities/{id}/query → C-FIND against a REMOTE modality/PACS

SYNC   vs  ASYNC       Long operations (store, move, get, archive) can run as JOBS.
                       Send "Synchronous": false → get a job ID → poll /jobs/{id}.
                       See references/jobs-and-changes.md.

Connection basics

Default endpoint is http://localhost:8042. Auth is HTTP Basic when enabled. Parameterize both — never hard-code credentials.

import requests

BASE = "http://localhost:8042"
AUTH = ("orthanc", "orthanc")   # or None if AuthenticationEnabled=false
S = requests.Session()
S.auth = AUTH

# Always confirm the server + version BEFORE using version-gated features
sys = S.get(f"{BASE}/system").json()
print(sys["Version"], sys["ApiVersion"])

Many features are version-gated (e.g. numpy output ≥ 1.11.0, C-GET ≥ 1.12.6, OrderBy/ExtendedFind ≥ 1.12.5, RequestedTags ≥ 1.11.0, extended /changes ≥ 1.12.5). When a workflow notes a minimum version, check /system first rather than calling an endpoint that may not exist on the target install.

Task → where to look

If the task is...Read this reference
Look up the exact path / method / summary for any endpointreferences/endpoints.md
Upload DICOM; browse the hierarchy; read DICOM tagsreferences/data-access.md
Download a file/preview/PNG/NumPy array/ZIP/PDF/videoreferences/data-access.md
Search the LOCAL database (/tools/find, /tools/lookup)references/data-access.md
Anonymize, modify, or delete resources (incl. bulk)references/data-access.md
Configure modalities/peers; C-ECHO/STORE/MOVE/GETreferences/networking.md
Query/Retrieve (C-FIND → answers → C-MOVE/C-GET) a remote PACSreferences/networking.md
Run async jobs, poll status; watch /changes; auto-routereferences/jobs-and-changes.md

Highest-frequency calls (inline quick start)

# 1. Upload a DICOM file (binary body). curl is clearer for raw binary:
#    curl -X POST -H "Expect:" http://localhost:8042/instances --data-binary @CT.dcm
with open("CT.dcm", "rb") as f:
    r = S.post(f"{BASE}/instances", data=f.read())
ids = r.json()   # {"ID","ParentPatient","ParentSeries","ParentStudy","Status"}

# 2. List all resources at a level (returns an array of Orthanc IDs)
studies = S.get(f"{BASE}/studies").json()

# 3. Get one resource (MainDicomTags + parent/child links)
study = S.get(f"{BASE}/studies/{study_id}").json()

# 4. Read human-readable DICOM tags of an instance
tags = S.get(f"{BASE}/instances/{instance_id}/simplified-tags").json()

# 5. Download the raw DICOM file
dcm = S.get(f"{BASE}/instances/{instance_id}/file").content   # write to .dcm

# 6. Find studies in the LOCAL database by DICOM tag
hits = S.post(f"{BASE}/tools/find",
              json={"Level": "Study",
                    "Query": {"PatientName": "DOE*"},
                    "Expand": True}).json()

Conventions used in the references

  • {id} always means an Orthanc ID unless the path says otherwise.
  • Resource-listing endpoints return an array of IDs; add ?expand (or POST "Expand": true for /tools/find) to get full objects instead.
  • Errors come back as JSON with HttpStatus, Message, and often OrthancError.
  • The canonical, always-current OpenAPI/Swagger spec is at https://orthanc.uclouvain.be/api/. Use it to confirm parameters for any endpoint not detailed here.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.