Developers
Standard formats in and out, codes on every finding, a sandbox, version pinning and honest failure codes. This page answers the questions an engineering lead asks before the first call.
Yes. Every POST /v1/inference/evaluate answer is available as a FHIR R4 Bundle: send
Accept: application/fhir+json or add ?format=fhir. The Bundle holds one
preliminary DiagnosticReport, one Observation per finding and one per verdict.
A verdict Observation carries the category, the recommendation, derivedFrom pointing at its
finding, and the criteria pack, version and validator as an extension and a meta.tag
(usable-for-output or advisory). A deferral is an Observation with dataAbsentReason and the
reason text, so an undecided finding stays visible instead of disappearing. The default JSON answer is
unchanged; FHIR is a second rendering of the same decision.
Yes. POST /v1/results/normalize accepts another AI system's output as FHIR R4
Observations (a Bundle, one Observation or a list) or as a DICOM SR TID 1500 measurement report in the
DICOM JSON model, with no DIMSE networking and no pixels. Each measurement group becomes a finding with its
source algorithm and version preserved, the findings are graded by the same engine as every other call,
and every verdict names both the AI source and the RadVector criteria pack. Patient fields are never read.
RadVector grades findings someone else reported, as decision support; it detects nothing.
Yes, where a verified code exists. Findings and verdicts carry a codes list drawn only
from codes copied from the published Open Imaging Finding Models (RadElement, the ACR and RSNA common
data elements), each entry naming the model it came from, and a build-time check re-verifies them
against the published set. A finding without a verified code is sent as text. In FHIR the same codes
appear as Observation.code.coding. A wrong code is worse than none, so the list is short and
grows only by verification.
Yes. POST /v1/context/prepare takes the current order or exam text, up to a handful of
de-identified prior report texts with their dates, and an optional technologist worksheet. It returns the
comparable priors ranked same-type first with the interval to this study, the prior measurements bound
to their lesions, the reporting standards that apply with each one's required reporting elements, the
recommendations earlier reports made that are still open, and missing-information warnings such as a
dictation that refers to a worksheet none was supplied for. It is assembly over the same deterministic
readers the reporting engine uses; no language model is called.
Yes, where the deployment has it switched on. A sandbox key is minted from the portal dashboard beside a
live key. It returns the same engine answers as a live key, is never billed, never counts against the
free monthly allowance, has its own lower rate limit, and cannot call /v1/impression because
that route spends hosted model tokens. Every sandbox answer carries X-RadVector-Sandbox:
true. A published file of synthetic request bodies,
synthetic-reports.json, covers each route with
invented values and the answer to expect, so a team can test without any real data.
Yes. Send pack_versions, for example {"fleischner": "fleischner-2017-r6"}, on
an evaluate call. When the live pack's version differs, the API answers 409
pack_version_mismatch naming the live version and grades nothing, so a stale integration fails
loudly instead of silently changing its recommendations. This is the honest form of pinning: replaying an
old pack would also need the evaluator code of that date, and that is not promised.
Every verdict carries a deferral_code from a closed set: inapplicable, absent, excluded,
undocumented, contradiction, several_lesions, error, unresolved. An undocumented feature is named, with
the range of categories the finding could still reach. A draft pack answers advisory and is marked not
usable for output. Your code branches on the code, never on prose.
Yes to both. POST /v1/inference/evaluate/batch takes 1 to 25 evaluate requests and answers
them in order, each with its own result or error and each metered as if sent alone. An
Idempotency-Key header on evaluate, results normalization and impression stores the first
answer durably in the API's own database, so a retry that lands on another instance replays that answer
with Idempotent-Replayed: true and is neither re-run nor re-metered. The same key with a
different body is refused.
An authenticated GET /v1/health returns build, the deploy's build id, beside
the live criteria packs and their versions. The anonymous health answer never carries it. Every answer
also carries an X-Trace-Id, which appears on each verdict's provenance and each usage event,
so a question about one call can be answered from the record.
Create an account, mint a key, send one fixture.