Use Cases
The iframe returns a JSON payload through the analysis_completed callback, and the full diagnostic report can be pulled from the API using the anonymousDiagnosticReportId it carries. That JSON is the raw material your host application uses to drive workflows.
The host app obtains the report by listening to analysis_completed and then calling the Output → API Endpoint. The schema of the JSON is described in the Output → JSON Schema section.
1. Skin-cancer triage in a patient app
Objective: When the iframe is embedded inside a patient-facing app, automatically route the patient to the appropriate level of care, without ever showing them the raw clinical output.
This pattern combines two iframe parameters:
isForPatient=1: simplifies questionnaire wording for non-clinical users.enableResult=0: hides the diagnostic result from the user, so the host app is the only consumer of the JSON.
The host app receives the report via analysis_completed, evaluates the keys returned under result, and decides what the patient sees next: a self-care message, a primary-care booking screen, or an urgent referral to a dermatologist.
The two signals that drive this decision are both returned by the device:
result.preliminaryFindings.isMalignantSuspicion: probability (0 to 100) that the lesion is malignant.result.scoringSystems[]: when the diagnostic-support algorithm reaches sufficient confidence, the relevant scoring system is computed (for pigmented lesions this is typically the 7-point checklist, codesevenPc). Each entry carries ascoreCategorySeverityof1(low),2(moderate) or3(high).
The patient never sees the underlying probabilities; they only see the action your app surfaces.
window.addEventListener("message", async function (event) {
if (event.data.message !== "analysis_completed") return;
const report = await fetchReportFromApi(event.data.id);
const { preliminaryFindings, scoringSystems } = report.result;
const sevenPc = scoringSystems?.find((s) => s.scoringSystem.code === "sevenPc");
if (preliminaryFindings.isMalignantSuspicion > 50) {
showUrgentDermatologistScreen();
} else if (sevenPc?.scoreCategorySeverity === 3) {
openDermatologyBooking();
} else if (preliminaryFindings.hasConditionSuspicion > 70) {
openPrimaryCareBooking();
} else {
showSelfCareGuidance();
}
});
The values X and Y (and the 50 / 70 shown above) are illustrative. Each managing organisation must choose its own thresholds based on its clinical protocols and the trade-off between false positives and false negatives. See the Thresholding section in the Legit.Health Plus workflows page for guidance, including a worked confusion-matrix example for malignancy probability.
2. Longitudinal severity monitoring
Objective: Track how a patient's condition evolves over time by storing severity scores returned by the iframe and rendering a trend in the host application.
The iframe itself does not retain information about users, so it cannot link two reports for the same patient. To enable longitudinal monitoring, the host app must:
- Pass a stable patient identifier through
extraDataevery time the iframe is launched (see the Customize page). - On
analysis_completed, fetch the report and persist the relevant severity values fromresult.scoringSystems[](thescore, thescoringSystem.codesuch assevenPc,apasiLocaloraladinLocal, and thescoreCategorySeveritybucket) in its own database, keyed by that identifier. - Render a historic chart from the persisted scores. This visualisation is built and maintained by the host application; the iframe does not provide it.
window.addEventListener("message", async function (event) {
if (event.data.message !== "analysis_completed") return;
const report = await fetchReportFromApi(event.data.id);
const patientId = report.extraData;
for (const entry of report.result.scoringSystems ?? []) {
await db.severityScores.insert({
patientId,
scoringSystemCode: entry.scoringSystem.code,
scoringSystemName: entry.scoringSystem.name,
score: entry.score,
scoreCategorySeverity: entry.scoreCategorySeverity,
reduction: entry.reduction,
timestamp: report.createdAt,
});
}
});
Each scoring-system entry already exposes a reduction field: the per-cent change versus the previous report for the same patient. It is null on the first report and populated thereafter, so the host app can surface a quick "improving / worsening" indicator without computing the delta itself.
Once the data is stored, the host app can build clinical features on top of it. For example, it can compare the latest score against the baseline at treatment start, flag worsening trajectories to a clinician, or show the patient a longitudinal chart of their own condition.
The two patterns are complementary: the smart-triage flow decides what to do right now, while longitudinal monitoring builds the historical context that lets a clinician interpret today's score against the patient's own trajectory.