The API
Everything the web console does goes through the central service’s API, so anything you do in the console can also be scripted.
The OpenAPI description
Section titled “The OpenAPI description”Every central server describes its API at /openapi/v1.json, for signed-in users. The description is generated
from the running version, with every operation tagged by area and marked with the role it needs. Load it into Postman,
Swagger UI or a client generator.
Signing in
Section titled “Signing in”API calls sign in the way the console does:
| Console sign-in | How a script signs in |
|---|---|
| Windows | Windows authentication (Negotiate: Kerberos or NTLM), as the account the script runs as. |
| Identity provider | The console’s sign-in cookie. Scripts are easier with Windows or local accounts. |
| Local accounts | POST /api/signin with {"name": "…", "password": "…"}, then the Routes.Console cookie it sets. |
POST /api/signin needs no sign-in, only the X-Routes-Console: 1 header. Its answer’s next says what is missing:
next |
Send it again with |
|---|---|
password |
newPassword: the password was temporary. |
code |
code: the six digits from the account’s authenticator app. |
enroll |
code, after adding the answer’s secret or uri to an authenticator app: two-factor sign-in is required and not set up yet. |
done |
Nothing: signed in. |
Wrong credentials answer 401; more than ten attempts a minute from one address, 429. The OpenAPI description says
which sign-in the server uses.
What a call may do follows the user’s role: viewer, history (patient data) or administrator.
Two rules apply to every call that changes something:
- The
X-Routes-Console: 1header is required on everyPOST,PUTandDELETEunder/api(except the node API). Without it the answer is400. Browsers cannot add it from another site, which protects against cross-site requests. - Send back the
revisionyou read. A source, destination, route or the settings saved with an older revision is refused (409), so two people cannot overwrite each other’s changes.
Examples
Section titled “Examples”# Windows sign-in: the nodes and their stateInvoke-RestMethod https://central01:5080/api/nodes -UseDefaultCredentials
# Drain a nodeInvoke-RestMethod https://central01:5080/api/nodes/node01/state -Method Post -UseDefaultCredentials ` -Headers @{ 'X-Routes-Console' = '1' } -ContentType 'application/json' -Body '{"state":"Drained"}'# Windows sign-in from Linux (Kerberos ticket from kinit)curl --negotiate -u : https://central01:5080/api/nodes
# Local accounts: sign in, keep the cookie, use itcurl -c cookies.txt -H 'X-Routes-Console: 1' -H 'Content-Type: application/json' \ -d '{"name":"automation","password":"…"}' https://central01:5080/api/signincurl -b cookies.txt https://central01:5080/api/config/export -o routes-config.jsonGive scripts an account of their own, with no more rights than they need.
| Area | Paths | What it covers |
|---|---|---|
| Session | /api/me |
Who is signed in, and their role. |
| Configuration | /api/config, /api/sources, /api/destinations, /api/routes, /api/routes/order, /api/settings |
Read and change the configuration; export, import, versions, differences and restore under /api/config. |
| Testing | /api/route-test, /api/destinations/{id}/echo, /api/destinations/{id}/negotiate, /api/scripts/test, /api/hl7/test |
The route tester, C-ECHO, transfer syntax tests, script and HL7 tests. |
| Nodes | /api/nodes, /api/nodes/{name}/state, /api/nodes/{name}/commands, /api/nodes/{name}/key, /api/enrollment, /api/centrals |
Node state, drain and resume, dead-letter commands, node keys, the enrollment key, central servers. |
| History | /api/history/studies, /api/history/resend, /api/problems/…, /api/ai/jobs, /api/hl7/messages |
Studies and their deliveries, resends, dead letters, quarantine, prior studies, reconciliation, AI jobs, HL7 messages. |
| Worklist | /api/worklist, /api/worklist/{id}/status, /api/worklist/outbound |
Worklist items, and status updates to other systems. |
| Patient ID maps | /api/patient-maps/{id}/entries, /import, /export |
Map entries. |
| Alerts | /api/alerts, /api/alerts/settings, /api/alerts/test |
Alerts and their rules. |
| Reports | /api/reports/usage, /api/reports/schedules, /api/reports/runs |
Usage reports and their schedules. |
| Audit | /api/audit |
The audit log. |
| Users | /api/users, /api/account |
Local accounts. |
| Monitoring | /api/live, /api/analytics/samples, /api/analytics/hourly |
The live feed the Monitoring page uses (server-sent events); the nodes’ figures sampled every minute (from, to: up to 7 days) and usage per hour (from, to: up to 92 days; by: Total, Modality, Node or Destination), for its charts. |
Searches of the history and the patient ID maps are recorded in the audit log, without the search text.
The node API
Section titled “The node API”Nodes use /api/node/…: enroll, heartbeat, config, secrets, history, activity, worklist, hl7,
mpps, commitment, patient-maps, ai/mapping and upload. They send their key in the X-Routes-Key header and
their name in X-Routes-Node. This API is for nodes only: a proxy or firewall in front of the central service must let
it through, but nothing else should call it.
Metrics
Section titled “Metrics”GET /metrics answers in the Prometheus text format, for the whole deployment: any central server answers for every
node, so scrape one address. Turn it on in Configuration › Node enrollment › Metrics, which generates a bearer token;
without a token the endpoint answers 404.
scrape_configs: - job_name: routes scheme: https metrics_path: /metrics authorization: credentials: <token> static_configs: - targets: ['central01:5080']| Metric | Labels | What it is |
|---|---|---|
routes_database_up |
1 when the database is reachable. | |
routes_config_version |
The current configuration version. | |
routes_central_up, routes_central_leader |
central |
Each central server running; the one that evaluates alerts. |
routes_alerts_open |
severity |
Open alerts. |
routes_node_up, routes_node_last_seen_seconds |
node |
Heartbeats. |
routes_node_state |
node, state |
1 for the node’s current state, Offline included. |
routes_node_drained, routes_node_config_current, routes_node_problem |
node |
Drained; running the current configuration; reporting a problem. |
routes_node_received_instances_total, routes_node_forwarded_instances_total, routes_node_dead_lettered_instances_total |
node |
Lifetime counters. |
routes_node_refused_instances_total, routes_node_received_bytes_total, routes_node_sent_bytes_total |
node |
Since the node started. |
routes_node_inbound_associations, routes_node_outbound_associations |
node |
Open associations. |
routes_node_queued_instances, routes_node_in_flight_instances |
node |
Waiting and being sent, every destination. |
routes_node_receive_rate, routes_node_send_rate |
node |
Instances per second, 10-second average. |
routes_node_disk_free_bytes, routes_node_memory_bytes |
node |
Free space on the data volume; the process’s working set. |
routes_node_pending_commitments, routes_node_history_backlog, routes_node_resend_cache_bytes |
node |
Storage commitment, history waiting for the central service, the resend cache. |
routes_node_held_studies, routes_node_held_instances |
node |
Held until their study is complete. |
routes_node_start_time_seconds |
node |
When the node started (Unix time). |
routes_destination_queued_instances, routes_destination_in_flight_instances, routes_destination_associations |
node, destination |
Each destination’s queue on each node. |
routes_destination_dead_letters |
node, destination |
Dead letters on disk. |
routes_destination_forwarded_instances_total, routes_destination_dead_lettered_instances_total |
node, destination |
Since the node started. |
routes_destination_awaiting_commitment, routes_destination_committed_instances_total, routes_destination_commit_failed_instances_total |
node, destination |
Storage commitment by the destination. |
routes_destination_unreachable, routes_destination_unreachable_seconds |
node, destination |
Associations failing, and for how long. |
routes_destination_oldest_queued_seconds |
node, destination |
The oldest waiting instance’s age. |
routes_destination_paused, routes_destination_held, routes_destination_send_limit_bytes_per_second |
node, destination |
Paused by its schedule; held (a key has not arrived); the current bandwidth limit. |
The same metrics can be sent over OTLP instead: see Monitoring.
Health
Section titled “Health”GET /health answers 200 OK when the central server and its database are ready, and 503 otherwise, without
sign-in: for load balancers in front of several central servers.
DICOMweb
Section titled “DICOMweb”Nodes serve DICOMweb under /dicomweb on the DICOMweb port, for the senders listed under each source:
| Service | Method and path |
|---|---|
| STOW-RS | POST /dicomweb/studies, POST /dicomweb/studies/{study} |
| QIDO-RS | GET /dicomweb/studies, /studies/{study}/series, /studies/{study}/instances, /studies/{study}/series/{series}/instances |
| WADO-RS | GET /dicomweb/studies/{study}, …/series/{series}, …/instances/{instance}, each with /metadata; …/frames/{frames} |
| Rendered | …/rendered for studies, series, instances and frames; …/thumbnail for series, instances and frames |
Senders authenticate with their token, as a Bearer token or as the password of HTTP Basic authentication, or with an identity provider’s access token. See DICOMweb and, for the answers, Status codes.
