Skip to content

eye/fundus

Fundus photo read: DR grade, glaucoma suspicion, AMD stage, vessels and referral urgency per eye.

BetaOP · XC · OTEyeOphthalmologyEndocrinologyv1.0.0 · $0.02 / request

About

The full read of one visit's fundus photographs: every image is checked and graded, the images of each eye are read together, and the result contains all sections the input supports.

Endpoint eye/fundus/interpret · version 1.0.0 · $0.02 per request · the bare id eye/fundus is an alias.

1. Calling the API#

Set up your API key#

Create a key in Settings → API Keys and set it as MEDRUN_KEY in your runtime.

export MEDRUN_KEY="YOUR_API_KEY"

Submit a request#

Every call is asynchronous: submitting returns a request with its id and status, and you follow it until the result is ready.

response=$(curl --request POST \
  --url https://api.medrun.ai/v1/run/eye/fundus/interpret \
  --header "Authorization: Bearer $MEDRUN_KEY" \
  --header "Content-Type: application/json" \
  --data '{
  "input": {
    "files": [
      "file_01K6R4X2Q9Y7T3V5W8Z0A1B2C3",
      "file_01K6R4X2Q9Y7T3V5W8Z0A1B2C4"
    ],
    "options": {
      "report": false
    }
  }
}')
REQUEST_ID=$(echo "$response" | jq -r .id)

Request status

The submit call returns the request, not the result. Use the queue calls below to check its status and fetch the result, or subscribe to a webhook.

Stream progress#

Stages stream as server-sent events (received, queued, preprocessing, inference, report, completed). Critical findings are flagged first, before the full result.

curl --no-buffer \
  --url https://api.medrun.ai/v1/requests/$REQUEST_ID/events \
  --header "Authorization: Bearer $MEDRUN_KEY" \
  --header "Accept: text/event-stream"

2. Authentication#

The API uses API keys. Send Authorization: Bearer $MEDRUN_KEY with every call. Test keys (mr_test_…) run against the mock backend for free.

API key#

Protect your API key

Never ship a key in browser or mobile code. Call MedRun from your server, or use a server-side proxy.

3. Queue#

Long-running requests

Whole studies can take a minute or more. Rely on the event stream or webhooks instead of blocking while you wait.

Fetch request status#

Statuses run queued → preparing → running and end in succeeded, failed, canceled, rejected or expired.

curl --request GET \
  --url https://api.medrun.ai/v1/requests/$REQUEST_ID \
  --header "Authorization: Bearer $MEDRUN_KEY"

Get the result#

When the request has succeeded, output holds the result envelope. See the result format.

curl --request GET \
  --url https://api.medrun.ai/v1/requests/$REQUEST_ID \
  --header "Authorization: Bearer $MEDRUN_KEY" | jq .output

4. Files#

files is a flat list: DICOM files, folders, CD exports (DICOMDIR) and zip/tar archives. The platform groups them into series and runs.

Uploading files#

# 1. Create the upload (one PUT up to 100 MB; larger files get multipart part URLs)
upload=$(curl --request POST --url https://api.medrun.ai/v1/uploads \
  --header "Authorization: Bearer $MEDRUN_KEY" --header "Content-Type: application/json" \
  --data '{"filename": "study.zip", "bytes": 214000000, "media_type": "application/zip"}')
# 2. PUT the bytes to upload.url (with upload.headers)
curl --request PUT --upload-file study.zip "$(echo "$upload" | jq -r .upload.url)"
# 3. Complete it, then pass file.id in input.files
curl --request POST --url "$(echo "$upload" | jq -r .complete_url)" --header "Authorization: Bearer $MEDRUN_KEY"
FILE_ID=$(echo "$upload" | jq -r .file.id)

Hosted files (URL)#

You can also pass https URLs, for example signed S3 or GCS links. MedRun fetches them when the request starts.

5. Webhooks#

Add a webhook to the submit body. MedRun POSTs the request object, signed with Standard Webhooks headers, when the request ends. Configure secrets and see deliveries in Settings → Webhooks.

{
  "input": {
    "files": [
      "file_…"
    ]
  },
  "webhook": {
    "url": "https://example.org/medrun/webhook",
    "events": [
      "request.succeeded",
      "request.failed"
    ]
  }
}

6. Schema#

Input#

  • fileslist<string>* required

    The visit's fundus photographs of one or both eyes: DICOM files, a folder or a zip; PNG/JPEG/TIFF photographs are read too. `file_…` ids from /v1/uploads or https URLs.

  • clinical_contextobject

    Optional. Age and sex for the report; never names, IDs or dates.

    • age_yearsnumber

      Range: 0 … 130

    • sexenum

      Possible values: female, male, other, unknown

    • indicationstring

      For example "annual diabetic eye screening, type 2 diabetes".

  • optionsobject
    • operating_pointenum

      Standard refers from moderate non-proliferative DR (ICDR ≥ 2) or maculopathy. High sensitivity also refers eyes the grader places just below that (more referrals, fewer missed eyes).

      Default value: "standard"

      Possible values: standard, high_sensitivity

    • reportbooleanadd-on

      Adds a draft fundus photography report written from the structured result (English). +$0.02 per run.

      Default value: false

    • report_languageenum

      Default value: "en"

      Possible values: en

    • returnlist<enum>

      JSON is always returned, with one overlay image per graded photograph.

      Default value: ["json"]

      Possible values: json

Example input:

{
  "files": [
    "file_01K6R4X2Q9Y7T3V5W8Z0A1B2C3",
    "file_01K6R4X2Q9Y7T3V5W8Z0A1B2C4"
  ],
  "options": {
    "report": false
  }
}

Output#

The output is the MedRun result envelope: sections[] with a status per section, then findings, measurements, scores, classifications, guidance, the optional report and artifacts (DICOM SR/SEG, overlays, PDF, FHIR).

  • quality Image quality: Per photograph: fundus photograph or not, EyeQ quality grade (good / usable / reject), field (macula- or disc-centred) and, when it is not good, the likely cause (blur, dark or uneven lighting, haze, disc or fovea out of the field, dark periphery) with retake advice. Per eye: gradable, graded on reduced quality, or ungradable (DESP U).
  • dr-grading Diabetic retinopathy: Per eye: ICDR grade 0–4 with referable and vision-threatening flags, lesion findings with counts and areas (microaneurysms, haemorrhages, hard exudates, cotton-wool spots) shown on an overlay, the maculopathy surrogate (hard exudate within one disc diameter of the fovea, with the nearest-exudate distance), the NHS DESP R/M grade and the referral or recall. Patient: the worse eye's grade and the most urgent referral. Macular oedema is seen on photographs only through exudates; its severity needs OCT.
  • segment-lesions Retinopathy lesions: Microaneurysm, haemorrhage, hard-exudate and cotton-wool-spot masks as DICOM SEG (the overlays and counts are part of the DR section now).
  • glaucoma Glaucoma (optic disc): Optic disc and cup outlines, vertical cup-to-disc ratio, rim by sector (ISNT) and referable-glaucoma likelihood.
  • amd Age-related macular degeneration: Drusen, pigmentary abnormalities and late AMD per eye, AREDS simplified severity score.
  • vessels Retinal vessels: Artery and vein calibres (CRAE, CRVE, AV ratio), tortuosity and a hypertensive retinopathy grade.
  • triage Other referable findings: Normal versus referable, with other findings such as vein occlusion, pathologic myopia or optic atrophy.
  • papilledema Papilloedema: Papilloedema versus normal or pseudo-papilloedema with a Frisén grade.
  • segment-anatomy Retinal anatomy: Optic disc, cup, fovea and vessel masks.
  • cvd-risk Retinal age and cardiovascular risk: Retinal age gap and a cardiovascular-risk estimate.
  • report Draft report: Opt-in draft report (findings, impression, limitations) written from the structured result; every number is validated against it.

OpenAPI document: https://api.medrun.ai/v1/models/eye/fundus/interpret/openapi.json