Get an Anonymous Diagnostic Report
Besides getting the DiagnosticReports linked to patients between your system and our, you can also fetch the AnonymousDiagnosticReports that you had sent, ie, those which are not linked to any patient.
We provide an endpoint to fetch an anonymous diagnostic report already present in the system. You only need the encrypted id of the diagnostic report in Legit.Health. This identifier is received from the message posted by our Iframe to your app.
To get a diagnostic report, you must use the endpoint getAnonymousDiagnosticReport.
A Anonymous Diagnostic Report contains all the information related to an image uploaded for a not-linked patient and the corresponding result data generated by our AI algorithms.
JSON Structure
The typical JSON structure we will send to your servers is the following:
Raw
/anonymous-diagnostic-reports/{encryptedId}?format=raw
The raw format is the default JSON payload returned by GET /s2s-api/v3/anonymous-diagnostic-reports/{encryptedId}. It is a flat, integrator-friendly shape designed to be consumed directly without FHIR tooling.
Strings tagged (translated) in this schema follow the locale query parameter on the request (?locale=es, ?locale=fr, ?locale=de). The default is English.
Envelope fields
Every response is wrapped in the standard ApiResponseData envelope:
{
"success": true,
"message": "Diagnostic report <id>",
"errorCode": null,
"data": { ... }
}
success: boolean. Indicates whether the request was successfully processed.message: short text describing the action performed. Usually includes the diagnostic report identifier.errorCode:nullon success; an error code string when something fails.data: the diagnostic report payload described below.
Full example
{
"success": true,
"message": "Diagnostic report <0189bafa-0610-7349-a0ab-eb53695b27fd>",
"errorCode": null,
"data": {
"id": "0189bafa-0610-7349-a0ab-eb53695b27fd",
"url": "https://iframe.legit.health?companyId=XXXX&diagnosticReportId=signedId",
"pdf": "https://utils.legit.health/pdf/anonymous-diagnostic-report?diagnosticReportIdEncrypted=<encryptedId>&apiKey=<apiKey>&authKey=<authKey>&locale=en",
"visitIdentifier": "visit identifier",
"extraData": {
"internalCaseId": "ABC-123",
"department": "dermatology"
},
"pathology": {
"name": "Acne",
"code": "Acne",
"icd11": "ED80"
},
"bodySite": {
"code": "headFront",
"name": "Face and neck"
},
"createdAt": "2023-08-03T12:38:10+02:00",
"anamnesisGeneral": [
{
"question": "What is the reason for the consultation? How did the problem start? Describe the origin.",
"answer": "I have acne on my face and neck. It started 2 months ago."
},
{
"question": "Do you have any allergies, especially to medications? If yes, list allergies.",
"answer": "No"
},
{
"question": "Are you taking any medication or treatment? If yes, explain what treatment you are taking.",
"answer": "No"
},
{
"question": "Do you have any major illness? Have you had anything operated on?",
"answer": "No"
},
{
"question": "Is there a history of any major illness in your family?",
"answer": "No"
}
],
"macroscopicMedia": {
"url": "https://bucket/diagnostic-report-medias/bbb.png",
"type": "Image",
"annotations": []
},
"result": {
"id": "0189bafa-0610-7349-a0ab-eb536a2185f6",
"metrics": {
"sensitivity": 83.31,
"specificity": 99.53,
"entropy": null
},
"preliminaryFindings": {
"hasCondition": 100,
"malignancy": 0.02,
"adjustedMalignancy": null,
"pigmentedLesion": 0,
"urgentReferral": 100,
"highPriorityReferral": 100
},
"iaSeconds": 0.88,
"observations": [
{
"media": {
"type": "Image",
"modality": "Clinical",
"diqaScore": 86,
"url": "https://bucket/diagnostic-report-medias/bbb.png"
}
}
],
"conclusions": [
{
"probability": 99.65,
"pathology": {
"name": "Acne",
"code": "Acne",
"icd11": "ED80"
}
},
{
"probability": 0.06,
"pathology": {
"name": "Varicella",
"code": "Varicella",
"icd11": "1E90"
}
}
],
"scoringSystems": [
{
"scoringSystem": {
"name": "Acne lesion estimation grading index",
"code": "alegi"
},
"score": {
"value": 8,
"severity": {
"value": 1,
"interpretations": [
{
"min": 0.0,
"max": 0.0,
"text": "None",
"coding": [
{
"code": 1,
"display": "low"
}
]
},
{
"min": 0.0,
"max": 2.1,
"text": "Mild",
"coding": [
{
"code": 1,
"display": "low"
}
]
},
{
"min": 2.1,
"max": 4.5,
"text": "Moderate",
"coding": [
{
"code": 2,
"display": "moderate"
}
]
},
{
"min": 4.5,
"max": 21.6,
"text": "Severe",
"coding": [
{
"code": 3,
"display": "high"
}
]
}
]
}
},
"reduction": null,
"facets": [
{
"facet": {
"name": "Acne lesion density",
"description": ""
},
"value": {
"display": "None (0)",
"raw": 0
}
},
{
"facet": {
"name": "Number of lesions",
"description": ""
},
"value": {
"display": "Mild (0-10)",
"raw": 5
}
}
],
"explainabilityMedia": {
"url": "https://bucket/diagnostic-report-medias/explainability/aaa.png"
}
}
]
}
}
}
Top-level fields
id: unique identifier of the diagnostic report (encryptedDiagnosticReportId).url: iframe URL to visualize the diagnostic report inside Legit.Health.nullwhen the company has no valid app key configured.pdf: URL to download a printable PDF of the report. Calling the endpoint with?format=pdfissues an HTTP 302 redirect to this same URL. Treat it as an opaque, authenticated URL; refetch the diagnostic report if the link stops working.visitIdentifier: the visit or encounter identifier supplied by the integrator when the iframe was loaded (nullwhen not provided). Use it to map the diagnostic report back to your own scheduling system.extraData: free-form JSON object (ornull) passed by the integrator when the iframe was loaded. Use it to round-trip your own identifiers, tags, or context back into the diagnostic report.createdAt: ISO-8601 timestamp indicating when the diagnostic report was created.
Body site and pathology
These fields contain information about the location (bodySite) and type (pathology) of the lesion captured in the image. The bodySite object is ALWAYS present in the response (never null). The pathology object is null until the most-probable conclusion crosses the confidence threshold, or until an integrator supplied a value at image submission.
"bodySite": {
"code": "headFront",
"name": "Face and neck"
},
"pathology": {
"name": "Acne",
"code": "Acne",
"icd11": "ED80"
}
bodySite.code: camelCase identifier for the body site, for exampleheadFront,trunkFront,armLeft. Match on the exact camelCase string; do not assume SCREAMING_SNAKE_CASE.bodySite.name: human-readable label for the body site. Translated by thelocalequery parameter.- The
bodySiteobject is ALWAYS present in the response (nevernull).
The complete list of supported body-site codes and their multilingual names can be fetched from a public, unauthenticated endpoint:
GET https://medical-device-params.legit.health/v2.0/body-sites
The response is an array of objects with two fields:
code: the camelCase identifier emitted underbodySite.code(e.g.headFront,armLeft,trunkFront).name: an object keyed by locale (en_GB,es_ES,pt_BR,it_IT,fr_FR,de_DE,bg_BG,pl_PL,ko_KO,ca_ES) with the translated display name.
Use this endpoint as the source of truth: the list can grow over time as new body sites are added.
For pathology (the whole object may be null):
pathology.code: stable, human-readable internal identifier such asAcne,Psoriasis,Cutaneous melanoma. Drawn from a database-backed catalog of roughly 309 conditions, plus any custom condition a tenant has added via the admin. Treat it as a known-list-with-extensions: do not assume a closed set for validation, but you can switch on the well-known codes for routing.pathology.name: human-readable condition label. Translated by thelocalequery parameter.pathology.icd11: ICD-11 code for the condition;nullwhen no ICD-11 mapping has been recorded for that condition. A single pathology may carry several ICD-11 codes comma-separated, e.g."EA90.42, EA90.5Y".- The whole
pathologyobject isnulluntil the most-probable conclusion crosses the confidence threshold, or until an integrator supplied a value at image submission.
Anamnesis general
The anamnesisGeneral field is an array of questions and their corresponding answers. These questions are asked to the patient before the image is submitted for analysis and their objective is to gather information about the patient's medical history:
"anamnesisGeneral": [
{
"question": "What is the reason for the consultation? How did the problem start? Describe the origin.",
"answer": "I have acne on my face and neck. It started 2 months ago."
},
...
]
Macroscopic media
Details the image of the lesion or body part that was submitted for analysis. The whole object is null when no image was captured.
"macroscopicMedia": {
"url": "https://bucket/diagnostic-report-medias/bbb.png",
"type": "Image",
"annotations": []
}
url: signed S3 URL to the captured image. Time-limited (about 30 minutes).type: media format. One of"Image"or"Video".nullwhen no media was attached (in that case the wholemacroscopicMediaobject is itselfnull).annotations: array of detection objects overlaid on the image, possibly empty[]. Each entry has the shape:id: opaque 32-character identifier for the detection.rect.topLeft.x,rect.topLeft.y,rect.width,rect.height: pixel-space bounding box.type: detection label string. Opaque values with mixed casing, for example:"Lesion","Suspicious lesion","Acne lesion","Actinic keratosis lesion","New actinic keratosis lesion","Treatment","acne","wheal","drainingTunnel","nonDrainingTunnel","nodule","abscess". Match on the exact string.confidence: number between0and1, ornull.
- Note: the whole
macroscopicMediaobject isnullwhen no image was captured.
Diagnostic result
The result field encapsulates the comprehensive results of the diagnostic process.
id: UUID of the result record. Stable for a given diagnostic report; useful for client-side caching and deduplication.
Metrics
metrics reports classifier performance for the case. All values are percentages from 0 to 100, and any of them can be null if the metric is not applicable to this body site or pathology.
sensitivityandspecificity: classifier accuracy expressed as percentages.entropy: how confident the AI is in its own response. Entropy is computed over the probability distribution of the diagnostic hypotheses; lower entropy means higher confidence, and higher entropy means lower confidence. Triage flows often useentropyas an uncertainty gate.
"metrics": {
"sensitivity": 83.31,
"specificity": 99.53,
"entropy": null
}
Preliminary findings
preliminaryFindings is a set of preliminary suspicions and their likelihoods, expressed as percentages from 0 to 100. Any field can be null when not applicable to the case.
hasCondition: likelihood that a condition is present.malignancy: likelihood that the condition is malignant.adjustedMalignancy: malignancy probability after applying clinical adjustments (for example, lesion-density or context-based corrections). A number between0and100when the adjustment model has run for the case, ornullotherwise. Note: in the FHIR view this field is hard-codednull; the raw view is the only place where a numeric value can appear.pigmentedLesion: likelihood that the lesion is pigmented.urgentReferral: probability that the patient should be seen by a doctor within the next 48 hours. Higher values indicate a stronger recommendation to bring the patient forward into urgent care.highPriorityReferral: probability that the patient should be seen by a doctor within the next 15 days. It complementsurgentReferralby capturing cases that are not 48-hour-urgent but still warrant a fast-tracked appointment ahead of the routine queue.
"preliminaryFindings": {
"hasCondition": 100,
"malignancy": 0.02,
"adjustedMalignancy": null,
"pigmentedLesion": 0,
"urgentReferral": 100,
"highPriorityReferral": 100
}
iaSeconds
iaSeconds: wall-clock seconds the inference pipeline spent processing the case (image plus AI calls). Number with decimals; can be null if timing was not recorded.
Observations
The observations field is an array of medias, each containing one field: media.
media: the media sent to the algorithm to be analyzed. It includes:
url: signed S3 URL to the image. Time-limited (about 30 minutes); download within the window if you plan to use it later.type: media format. One of"Image"or"Video". Always present.modality: how the image was captured. One of"None","Clinical","Dermoscopic", ornull.nullfor video uploads or when image-validity (DIQA + modality detection) did not run. The value is"Dermoscopic", not"Dermoscopy".diqaScore: Dermatology Image Quality Assessment score on a0to100scale (float).nullfor videos or when DIQA was not computed.- Each entry contains only the
mediakey. The v3 response does not emitoriginalMedia(that field is v2-only).
"observations": [
{
"media": {
"type": "Image",
"modality": "Clinical",
"diqaScore": 86,
"url": "https://bucket/diagnostic-report-medias/bbb.png"
}
},
...
]
Diagnostic conclusions
The conclusions field is an array of diagnostic outcomes, each containing a pathology type and its associated probability. Conclusions are sorted by probability (descending). Probabilities are percentages from 0 to 100.
"conclusions": [
{
"probability": 99.65,
"pathology": {
"name": "Acne",
"code": "Acne",
"icd11": "ED80"
}
},
...
]
Scoring systems
The scoringSystems field houses one or more scoring models for the identified pathology. These models come into play when the likelihood of the most probable conclusion surpasses a certain threshold. They are used to estimate the severity of the most probable condition:
"scoringSystems": [
{
"scoringSystem": {
"name": "Acne lesion estimation grading index",
"code": "alegi"
},
"score": {
"value": 8,
"severity": {
"value": 1,
"interpretations": [
{
"min": 0.0,
"max": 0.0,
"text": "None",
"coding": [
{
"code": 1,
"display": "low"
}
]
},
...
]
}
},
"reduction": null,
"facets": [
{
"facet": {
"name": "Acne lesion density",
"description": ""
},
"value": {
"display": "None (0)",
"raw": 0
}
},
...
],
"explainabilityMedia": {
"url": "https://bucket/diagnostic-report-medias/explainability/aaa.png"
}
}
]
In each scoring system:
scoringSystemincludes the name and code of the scoring methodology.codeis a camelCase identifier (e.g.alegi,apasiLocal,pasiLocal,scoradLocal,ihs4Local,hiscr,dlqi). Match on the exact camelCase string; do not assume SCREAMING_SNAKE_CASE.
Naming pattern:
Localsuffix: the scoring system runs on a single body-site image.Globalsuffix: the scoring system aggregates across all body sites for the same encounter.a-prefix (e.g.apasiLocal,ascoradLocal,aihs4Local): AI-computed variants of the parent scoring system.
The complete list of supported scoring systems for a given pathology, together with their facet questionnaires, can be fetched from a public, unauthenticated endpoint:
GET https://medical-device-params.legit.health/v2.0/questionnaires?pathology=<ICD-11 code>
Pass the ICD-11 code of the pathology of interest as the pathology query parameter (e.g. EA90 for Psoriasis). The response is an array of objects describing each scoring system applicable to that pathology, with the following fields:
identifier: the camelCase scoring-system code emitted underscoringSystem.code(e.g.apasiLocal,pure4).code: short identifier used internally by the severity-assessment endpoint (e.g.apasi,pure4).mode:"local"or"global".path: the severity-assessment endpoint path.title,description: multilingual objects keyed by locale (en_GB,es_ES, ...).questionnaire: an array of facet objects, each withcode,name(multilingual),description(multilingual), andinput(type, min/max, options). These correspond to the facets emitted underfacets[]in the diagnostic-report response.
Use this endpoint as the source of truth: the catalog of scoring systems can grow over time.
score.valueindicates the calculated score according to the system's rules. Can benullif the score could not be computed.score.severity.value: integer severity code. One of1(low),2(moderate),3(high), ornullwhen the scoring system has no severity band for this body site or locale. The English string label is exposed underscore.severity.interpretations[].coding[0].display("low","moderate","high"); the localized BAND label (such as"None","Mild","Moderate","Severe","Grade 1","Stage 0") is exposed underscore.severity.interpretations[].text.score.severity.interpretationsis an array describing every severity band defined for this scoring system at the relevant body site and locale. Each entry contains:min: lower bound (inclusive) of the score range that maps to this band.max: upper bound of the score range that maps to this band.text: human-friendly label for the band (translated), e.g."Mild","Moderate","Severe".coding[]: machine-readable severity coding for the band, with each entry exposing acodeanddisplay.
reduction: object (ornull) describing automatic score reductions (for example, lesion-density adjustments). Most scoring systems returnnullhere.facetsis an array of facets used in score calculation, with each object containing the facet's information and the corresponding raw and displayed values.explainabilityMedia: an object with a singleurlfield. The object is always emitted;urlisnullwhen the scoring system did not produce an annotated overlay. When present,urlis a signed S3 URL to a heatmap or bounding-box image explaining how the score was produced.
Comprehensive scoring systems information
For an exhaustive understanding of scoring systems, their identifiers, and facets, you can download the detailed documentation:
- Preproduction Environment: Download here
- Production Environment: Download here
FHIR
/anonymous-diagnostic-reports/{encryptedId}?format=fhir
{
"success": true,
"message": "Diagnostic report <0194b1e2-d73e-71ba-9360-7b7a0ffa551b>",
"data": {
"resourceType": "DiagnosticReport",
"id": "cUVHY3lUcEFSdzdhVklrMXFKS2k5ZzBxaHBYWXNERTNFWjBqR0Rwd3AxeXkrc2hqNDNCdC8rM1NtUVhobEk0eQ==",
"presentedForm": {
"practitioner": {
"url": "https://iframe.legit.health?companyId=XXXX&diagnosticReportId=signedId",
"pdf": "https://utils.legit.health/pdf/anonymous-diagnostic-report?diagnosticReportIdEncrypted=<encryptedId>&apiKey=<apiKey>&authKey=<authKey>&locale=en"
},
"patient": {
"url": null,
"pdf": null
}
},
"encounter": {
"identifier": {
"value": "XYZ"
}
},
"issued": "2025-01-29T12:46:57+01:00",
"condition": {
"pathology": null,
"bodySite": {
"coding": [
{
"system": "https:\/\/legit.health\/integration\/json-only\/codes\/body-sites",
"code": "trunkFront",
"display": "Chest and belly"
}
]
}
},
"extraData": {
"externalCaseId": "CASE-123",
"referrer": "telemedicine-portal"
},
"anamnesisGeneral": {
"resourceType": "QuestionnaireResponse",
"status": "completed",
"item": [
{
"linkId": 1,
"text": "Question one?",
"answer": [
{
"valueString": "answer"
}
]
}
]
},
"macroscopicMedia": {
"resourceType": "Media",
"content": {
"url": "https://bucket/diagnostic-report-medias/bbb.png"
},
"type": "Image",
"annotations": null
},
"result": {
"id": "0194b1e2-d740-70d6-9435-a3606f0fa491",
"performanceIndicators": {
"resourceType": "Observation",
"component": [
{
"code": {
"coding": [
{
"code": "sensitivity",
"display": "Sensitivity"
}
]
},
"valueQuantity": {
"value": 91.16,
"unit": "%"
}
},
{
"code": {
"coding": [
{
"code": "specificity",
"display": "Specificity"
}
]
},
"valueQuantity": {
"value": 96.58,
"unit": "%"
}
},
{
"code": {
"coding": [
{
"code": "entropy",
"display": "Entropy"
}
]
},
"valueQuantity": {
"value": null,
"unit": "%"
}
}
]
},
"clinicalIndicators": {
"resourceType": "Observation",
"component": [
{
"code": {
"coding": [
{
"code": "hasCondition",
"display": "Has condition"
}
]
},
"valueQuantity": {
"value": 100.0,
"unit": "%"
}
},
{
"code": {
"coding": [
{
"code": "malignancy",
"display": "Malignancy"
}
]
},
"valueQuantity": {
"value": 0.0,
"unit": "%"
}
},
{
"code": {
"coding": [
{
"code": "adjustedMalignancy",
"display": "Adjusted malignancy"
}
]
},
"valueQuantity": {
"value": null,
"unit": "%"
}
},
{
"code": {
"coding": [
{
"code": "pigmentedLesion",
"display": "Pigmented lesion"
}
]
},
"valueQuantity": {
"value": null,
"unit": "%"
}
},
{
"code": {
"coding": [
{
"code": "urgentReferral",
"display": "Urgent referral"
}
]
},
"valueQuantity": {
"value": null,
"unit": "%"
}
},
{
"code": {
"coding": [
{
"code": "highPriorityReferral",
"display": "High priority referral"
}
]
},
"valueQuantity": {
"value": null,
"unit": "%"
}
}
]
},
"analysisDuration": 0.916,
"observations": [
{
"media": {
"resourceType": "Media",
"content": {
"url": "https://bucket/diagnostic-report-medias/bbb.png"
},
"type": "Image",
"modality": "Clinical",
"diqaScore": 86.0
}
},
{
"media": {
"resourceType": "Media",
"content": {
"url": "https://bucket/diagnostic-report-medias/bbb.png"
},
"type": "Image",
"modality": "Clinical",
"diqaScore": 92.0
}
}
],
"conclusions": [
{
"pathology": {
"coding": [
{
"code": "Psoriasis",
"display": "Psoriasis",
"system": "https:\/\/legit.health\/integration\/json-only\/codes\/conditions"
},
{
"code": "EA90",
"display": "Psoriasis",
"system": "ICD-11"
}
]
},
"probability": 80.0
},
{
"pathology": {
"coding": [
{
"code": "Palmoplantar psoriasis",
"display": "Palmoplantar psoriasis",
"system": "https:\/\/legit.health\/integration\/json-only\/codes\/conditions"
},
{
"code": "EA90.42, EA90.5Y",
"display": "Palmoplantar psoriasis",
"system": "ICD-11"
}
]
},
"probability": 20.0
}
],
"questionnaires": [
{
"resourceType": "QuestionnaireResponse",
"questionnaire": "apasiLocal",
"scoringSystem": {
"text": "Local automatic psoriasis area and severity index",
"coding": [
{
"code": "apasiLocal",
"display": "Local automatic psoriasis area and severity index"
}
]
},
"score": {
"valueQuantity": {
"value": 6.3
},
"system": "http:\/\/unitsofmeasure.org",
"unit": "points",
"interpretation": {
"coding": [
{
"code": 3,
"display": "Severe"
}
],
"text": "Severe"
},
"interpretations": [
{
"min": 0.0,
"max": 0.0,
"text": "None",
"coding": [
{
"code": 1,
"display": "low"
}
]
},
{
"min": 0.0,
"max": 2.1,
"text": "Mild",
"coding": [
{
"code": 1,
"display": "low"
}
]
},
{
"min": 2.1,
"max": 4.5,
"text": "Moderate",
"coding": [
{
"code": 2,
"display": "moderate"
}
]
},
{
"min": 4.5,
"max": 21.6,
"text": "Severe",
"coding": [
{
"code": 3,
"display": "high"
}
]
}
]
},
"explainabilityMedia": {
"resourceType": "Media",
"content": {
"url": "https://bucket/diagnostic-report-medias/bbb.png"
},
"annotations": [],
"type": "Image"
},
"item": [
{
"linkId": 30,
"text": "This value corresponds to the shedding intensity of the outermost layer of skin of the affected zone",
"code": [
{
"code": "Scaling",
"display": "Scaling"
}
],
"answer": [
{
"valueCoding": {
"code": 2,
"display": "Moderate (2)"
}
}
]
},
{
"linkId": 27,
"text": "This value corresponds to the redness intensity of the lesion",
"code": [
{
"code": "Erythema",
"display": "Erythema"
}
],
"answer": [
{
"valueCoding": {
"code": 3,
"display": "Severe (3)"
}
}
]
},
{
"linkId": 29,
"text": "This value corresponds to the hardening intensity of the lesion",
"code": [
{
"code": "Induration",
"display": "Induration"
}
],
"answer": [
{
"valueCoding": {
"code": 2,
"display": "Moderate (2)"
}
}
]
},
{
"linkId": 52,
"text": "This value corresponds to the percentage of involvement of the specific area of the body you are reporting",
"code": [
{
"code": "Affected area",
"display": "Affected area"
}
],
"answer": [
{
"valueCoding": {
"code": 3,
"display": "50% (3)"
}
}
]
}
],
"reduction": null,
"history": null
}
]
},
"patient": null,
"previousDiagnosticReportId": null,
"nextDiagnosticReportId": null,
"helpDiagnoseQuestionnaireAnswers": null,
"isPriority": null,
"isReviewed": null,
"patientVisibility": null
},
"errorCode": null
}
Top-level fields
The response begins with three fundamental fields that indicate the request’s outcome and location of data:
{
"success": true,
"message": "Diagnostic report <id>",
"data": { ... },
"errorCode": null
}
success: Indicates whether the request was successfully processed.message: A short text message describing the action performed. Often includes the diagnostic report’s internal identifier.data: Holds the main content of the diagnostic report in FHIR format.errorCode: Used to return an error code if something fails.
data object
Within "data", the diagnostic report follows the FHIR specification. It encloses all information about the patient’s encounter, clinical findings, images, and conclusions.
"data": {
"resourceType": "DiagnosticReport",
"id": "cUVHY3lUcEFSdzdhVklrMXFKS2k5ZzBxaHBYWXNERTNFWjBqR0Rwd3AxeXkrc2hqNDNCdC8rM1NtUVhobEk0eQ==",
"presentedForm": { ... },
"encounter": { ... },
"issued": "2025-01-29T12:46:57+01:00",
"condition": { ... },
"extraData": null,
"anamnesisGeneral": { ... },
"macroscopicMedia": { ... },
"result": { ... },
"patient": null,
"previousDiagnosticReportId": null,
"nextDiagnosticReportId": null,
"helpDiagnoseQuestionnaireAnswers": null,
"isPriority": null,
"isReviewed": null,
"patientVisibility": null
}
Below is a breakdown of its main sections:
resourceType: Specifies the FHIR resource type, which is"DiagnosticReport".id: An encrypted, URL-safe identifier for this Diagnostic Report. This is the same opaqueencryptedIdvalue used in the API path; treat it as an opaque string.presentedForm: Contains links that allow viewing the diagnostic report in different forms (browser or PDF). Typically includes:practitioner.url: A link where a practitioner can view the diagnostic report.nullif the company does not have a valid iframe app key configured.practitioner.pdf: A link to download the PDF of the report. Calling the API endpoint with?format=pdfissues an HTTP 302 redirect to this same URL; most HTTP clients follow it automatically and receive the PDF. Treat the URL as opaque and refetch the diagnostic report if it stops working.patient.url/patient.pdf: If relevant to the patient, these fields may provide them with URLs for viewing or downloading their report. If unused, they may remainnull.
"presentedForm": {
"practitioner": {
"url": "...",
"pdf": "..."
},
"patient": {
"url": null,
"pdf": null
}
}
encounter: Contains theidentifierthat links this diagnostic report to a particular healthcare encounter or visit.valueis the visit/encounter identifier passed in when the diagnostic report was created.nullif no visit identifier was provided.
"encounter": {
"identifier": {
"value": "some-unique-encounter-id"
}
}
issued: ISO-8601 timestamp (with timezone offset) indicating when the diagnostic report was issued or finalized, e.g.2025-01-29T12:46:57+01:00.condition: Describes the suspected or most likely condition and the body site:pathology: May contain the name or code for a confirmed condition.pathologyisnullwhen no condition has been set on the report. When set, it follows the samecoding[]array shape asresult.conclusions[].pathology: two entries, one in the proprietarylegit.health/integration/json-only/codes/conditionssystem and one in ICD-11.bodySite: Provides standardized information about the anatomical location usingcode,display, and asystemthat references a coding standard.
"condition": {
"pathology": null,
"bodySite": {
"coding": [
{
"system": "https://legit.health/integration/json-only/codes/body-sites",
"code": "trunkFront",
"display": "Chest and belly"
}
]
}
}
When pathology is populated, it looks like this:
"condition": {
"pathology": {
"coding": [
{
"code": "Psoriasis",
"display": "Psoriasis",
"system": "https://legit.health/integration/json-only/codes/conditions"
},
{
"code": "EA90",
"display": "Psoriasis",
"system": "ICD-11"
}
]
},
"bodySite": { ... }
}
pathology.coding[0] is the proprietary legit.health/integration/json-only/codes/conditions entry. pathology.coding[0].code is a stable, human-readable internal identifier ("Psoriasis", "Cutaneous melanoma", "Acne", ...) drawn from a database-backed catalog of roughly 309 base conditions, plus any per-tenant custom condition. Treat it as a known-list-with-extensions.
pathology.coding[1] is the ICD-11 mapping (system is the literal string "ICD-11" with a hyphen). pathology.coding[1].code may be a single ICD-11 code (e.g. "EA90") or several comma-separated codes when one proprietary condition maps to multiple ICD-11 entries (e.g. "EA90.42, EA90.5Y"). code is null when no ICD-11 mapping exists for that condition.
bodySite is always present in the response (never null). bodySite.coding[0].code is a camelCase identifier (e.g. headFront, trunkFront, armLeft). Match on the exact camelCase string; do not assume SCREAMING_SNAKE_CASE. bodySite.coding[0].display is the human-readable label, translated by the locale query parameter.
The complete list of supported body-site codes and their multilingual names can be fetched from a public, unauthenticated endpoint:
GET https://medical-device-params.legit.health/v2.0/body-sites
The response is an array of objects with two fields:
code: the camelCase identifier emitted underbodySite.coding[0].code(e.g.headFront,armLeft,trunkFront).name: an object keyed by locale (en_GB,es_ES,pt_BR,it_IT,fr_FR,de_DE,bg_BG,pl_PL,ko_KO,ca_ES) with the translated display name.
Use this endpoint as the source of truth: the list can grow over time as new body sites are added.
extraData: An optional free-form JSON object (ornull) that the client passed in when loading the iframe. Whatever structure was set on the source side is echoed back verbatim.anamnesisGeneral: Stores general Q&A information about the patient’s history in FHIR’sQuestionnaireResponseformat. It can contain items representing the questions and their answers.
"anamnesisGeneral": {
"resourceType": "QuestionnaireResponse",
"status": "completed",
"item": [
{
"linkId": 1,
"text": "Question one?",
"answer": [
{
"valueString": "answer"
}
]
},
...
]
}
resourceType: Always"QuestionnaireResponse".status: Indicates the status of the questionnaire (e.g."completed").item: An array of question-answer pairs. Each entry has alinkId(the question's identifier, emitted as a JSON integer; note that the FHIR R4 standard usually typeslinkIdas a string, but this API emits an integer primary key), atext(the human-readable question) and ananswer[]withvalueStrings.macroscopicMedia: Details an image or other media of the lesion or body part. Here, it references a resource of type"Media":resourceType: Always"Media".content.url: A direct URL to access the uploaded file, typically a signed URL valid for a limited time.type: media format. One of"Image"or"Video".nullwhen the original upload had no recorded type (which happens together with the wholemacroscopicMediaobject being itselfnull).annotations: alwaysnullin the FHIR view, even when the raw view exposes detections for the same image. Detection data is exposed instead per scoring system, inresult.questionnaires[].explainabilityMedia.annotations.
"macroscopicMedia": {
"resourceType": "Media",
"content": {
"url": "https://...jpg"
},
"type": "Image",
"annotations": null
}
result
The core field that captures the diagnostic process output. It includes identifiers, metrics, conclusions, and any scoring systems or questionnaires used to evaluate the condition.
"result": {
"id": "0194b1e2-d740-70d6-9435-a3606f0fa491",
"performanceIndicators": { ... },
"clinicalIndicators": { ... },
"analysisDuration": 0.916,
"observations": [ ... ],
"conclusions": [ ... ],
"questionnaires": [ ... ]
}
Below are its main subfields:
result.id: UUID for this specific result row (distinct from the top-levelid, which identifies the encrypted DiagnosticReport).performanceIndicators: A FHIRObservationthat shows performance metrics such as sensitivity, specificity, and entropy:code.coding: An array containing the codes that describe the metric name (e.g."sensitivity","specificity","entropy").valueQuantity.value: The numeric value of the metric.valueQuantity.unit: Usually"%"or other relevant units.entropy(component code"entropy"): a measure of how confident the AI is in its own response. Entropy is computed over the probability distribution of the diagnostic hypotheses; lower entropy means higher confidence, and higher entropy means lower confidence. Triage flows often useentropyas an uncertainty gate.
"performanceIndicators": {
"resourceType": "Observation",
"component": [
{
"code": {
"coding": [
{
"code": "sensitivity",
"display": "Sensitivity"
}
]
},
"valueQuantity": {
"value": 91.16,
"unit": "%"
}
},
...
]
}
clinicalIndicators: Another FHIRObservationdescribing clinical aspects such as the probability of having the condition or malignancy suspicion. Each component focuses on a specific clinical clue, with the value carried invalueQuantity.value(percentage from0to100):hasCondition: Likelihood that a condition is present.malignancy: Likelihood that the condition is malignant.urgentReferral: probability that the patient should be seen by a doctor within the next 48 hours. Higher values indicate a stronger recommendation to bring the patient forward into urgent care.highPriorityReferral: probability that the patient should be seen by a doctor within the next 15 days. It complementsurgentReferralby capturing cases that are not 48-hour-urgent but still warrant a fast-tracked appointment ahead of the routine queue.pigmentedLesion: Likelihood that the lesion is pigmented.adjustedMalignancy: In the FHIR view, theadjustedMalignancycomponent'svalueQuantity.valueis HARD-CODEDnullfor v3 anonymous reports, even when the raw view (result.preliminaryFindings.adjustedMalignancy) returns a number. Treat it as alwaysnullin FHIR responses.
"clinicalIndicators": {
"resourceType": "Observation",
"component": [
{
"code": {
"coding": [
{
"code": "hasCondition",
"display": "Has condition"
}
]
},
"valueQuantity": {
"value": 100.0,
"unit": "%"
}
},
...
]
}
analysisDuration: Seconds the AI engine spent analysing the images (floating-point).nullif the diagnostic engine did not record a duration.observations: An array of observations that reference each media file examined:media.resourceType: always"Media".media.content.url: signed S3 URL to the file. Time-limited (about 30 minutes).media.type: media format. One of"Image"or"Video". Always present.media.modality: how the image was captured. One of"None","Clinical","Dermoscopic", ornull.nullfor video uploads or when image-validity did not run. The value is"Dermoscopic", not"Dermoscopy".media.diqaScore: Dermatology Image Quality Assessment score on a0to100scale (float).nullfor videos or when DIQA was not computed.- Each observation contains only the
mediakey. The v3 FHIR response does not emitoriginalMedia(that field is v2-only).
"observations": [
{
"media": {
"resourceType": "Media",
"content": { "url": "..." },
"type": "Image",
"modality": "Clinical",
"diqaScore": 86.0
}
},
...
]
conclusions: Represents the list of possible conditions identified, each with a probability and standardized coding:
"conclusions": [
{
"pathology": {
"coding": [
{
"code": "Psoriasis",
"display": "Psoriasis",
"system": "https://legit.health/integration/json-only/codes/conditions"
},
{
"code": "EA90",
"display": "Psoriasis",
"system": "ICD-11"
}
]
},
"probability": 100.0
},
...
]
pathology.coding[0].code: The code that identifies the condition (e.g."Psoriasis"). Stable, human-readable internal identifier from the proprietary catalog.pathology.coding[0].display: Human-friendly label for the condition (e.g."Psoriasis").pathology.coding[1]: The ICD-11 mapping of the same condition.systemis the literal string"ICD-11"(with hyphen).codemay be a single ICD-11 code (e.g."EA90") or several comma-separated codes when one proprietary condition maps to multiple ICD-11 entries (e.g."EA90.42, EA90.5Y").codeisnullwhen no ICD-11 mapping has been recorded for that condition.displaymirrors the proprietary display.probability: The likelihood of this condition being correct, expressed as a percentage.
questionnaires
An array of QuestionnaireResponse objects, each containing details about a scoring system applied to the images:
"questionnaires": [
{
"resourceType": "QuestionnaireResponse",
"questionnaire": "apasiLocal",
"scoringSystem": {
"text": "Local automatic psoriasis area and severity index",
"coding": [
{ "code": "apasiLocal", "display": "Local automatic psoriasis area and severity index" }
]
},
"score": { ... },
"explainabilityMedia": { ... },
"item": [ ... ]
}
]
resourceType: Always"QuestionnaireResponse".questionnaire: The internal code/name of the scoring system (e.g.,"apasiLocal"). A camelCase identifier; match on the exact string. Do not assume SCREAMING_SNAKE_CASE.scoringSystem: Contains the name (text) andcoding[]array for the scoring methodology.coding[0].codeis the same camelCase identifier asquestionnaire.
Naming pattern:
Localsuffix: the scoring system runs on a single body-site image.Globalsuffix: the scoring system aggregates across all body sites for the same encounter.a-prefix (e.g.apasiLocal,ascoradLocal,aihs4Local): AI-computed variants of the parent scoring system.
The complete list of supported scoring systems for a given pathology, together with their facet questionnaires, can be fetched from a public, unauthenticated endpoint:
GET https://medical-device-params.legit.health/v2.0/questionnaires?pathology=<ICD-11 code>
Pass the ICD-11 code of the pathology of interest as the pathology query parameter (e.g. EA90 for Psoriasis). The response is an array of objects describing each scoring system applicable to that pathology, with the following fields:
identifier: the camelCase scoring-system code emitted underquestionnaireandscoringSystem.coding[0].code(e.g.apasiLocal,pure4).code: short identifier used internally by the severity-assessment endpoint (e.g.apasi,pure4).mode:"local"or"global".path: the severity-assessment endpoint path.title,description: multilingual objects keyed by locale (en_GB,es_ES, ...).questionnaire: an array of facet objects, each withcode,name(multilingual),description(multilingual), andinput(type, min/max, options). These correspond to the FHIRitem[]entries emitted under each questionnaire in the diagnostic-report response.
Use this endpoint as the source of truth: the catalog of scoring systems can grow over time.
score: The numeric outcome of the scoring system along with its severity interpretation. Note:unit("points") andsystem("http://unitsofmeasure.org") are emitted as siblings ofvalueQuantityinsidescore, not insidevalueQuantityitself.score.interpretation: The interpretation that applies to this particular score value (a single band).score.interpretation.coding[0].code: integer severity code. One of1(low),2(moderate),3(high), ornull.score.interpretation.coding[0].display: English string label for the severity tier. One of"low","moderate","high".score.interpretation.text: the localized BAND label, translated by thelocalequery parameter. Examples (English):"None","Mild","Moderate","Severe","Very severe","Grade 1"to"Grade 9","Stage 0"to"Stage 4", plus PROM-specific labels for DLQI, UCT, PURE4, and apulsi.
score.interpretations: All defined severity bands for this scoring system, in order. Each band hasmin(inclusive),max(exclusive),text(band label, translated) andcoding[](machine code + display:codeis the integer severity1/2/3/null;displayis the English string label"low"/"moderate"/"high"). Use these to render a band scale or to map a score onto a category client-side.
explainabilityMedia: an annotatedMediaresource that highlights how the score was determined. The whole object isnullwhen no annotated explainability media is available for this scoring system run. When present:resourceType: always"Media".content.url: signed S3 URL. Time-limited (about 30 minutes).type: always"Image"(scoring-system explainability is never a video).annotations: array of detection objects, possibly empty. Each entry hasid,rect.topLeft.{x,y},rect.width,rect.height,type(a detection label string from the same fixed set used in the raw view:"Lesion","Suspicious lesion","Acne lesion","Actinic keratosis lesion","New actinic keratosis lesion","Treatment","acne","wheal","drainingTunnel","nonDrainingTunnel","nodule","abscess"), andconfidence(number0to1ornull).
item: An array of question-answer objects relevant to the scoring, each containing:linkId: the stable, locale-independent identifier for the facet. Emitted as a JSON integer (a primary key from the backing entity). Note that the FHIR R4 standard usually typeslinkIdas a string; this API emits an integer.code[]: an array with one coding entry whosecodeanddisplayboth carry the TRANSLATED facet name (e.g."Erythema"in English,"Eritema"in Spanish). Important:code[].codeCHANGES with thelocalequery parameter; do not use it as a stable identifier in your integration logic. The stable, locale-independent identifier isitem[].linkId. Switch onlinkId, not oncode[].code.answer: The recorded response, often including a numeric level (e.g., "Moderate (2)").answer[].valueCoding.codeis the facet value as a JSON number; whole-number values serialize WITHOUT a trailing.0(e.g.2, not2.0), while non-integer values serialize normally (e.g.2.5).
reduction: Reserved for a future "score change vs previous report" payload. Alwaysnullfor anonymous reports.history: Reserved for a future "previous scores" payload. Alwaysnullfor anonymous reports.
Always-null top-level fields
After result, the FHIR response always emits these sibling keys at the top of data:
"patient": null,
"previousDiagnosticReportId": null,
"nextDiagnosticReportId": null,
"helpDiagnoseQuestionnaireAnswers": null,
"isPriority": null,
"isReviewed": null,
"patientVisibility": null
patientpreviousDiagnosticReportIdnextDiagnosticReportIdhelpDiagnoseQuestionnaireAnswersisPriorityisReviewedpatientVisibility
These keys are always present in the response and currently always null for v3 anonymous diagnostic reports. They are reserved for future authenticated/non-anonymous flows; integrators should ignore them but parsers must tolerate them.
Obtaining a PDF
You can generate a PDF with the contents of anonymous diagnostic report by calling the endpoint getAnonymousDiagnosticReport with the query param format=pdf:
/anonymous-diagnostic-reports/{encryptedId}?format=pdf