{"openapi":"3.0.3","info":{"title":"Aroga Detailed Enterprise API","version":"0.1.0-preview","description":"Documentation preview: analysis is disabled on this host. Client processing requires approved account routing, runtime configuration, signed clinical and data approvals, and hosted synthetic acceptance.\n\nThe servers below describe the existing official website gateway route, not a claim that your account is enabled. The planned aroga-sandbox.api.nextgenerationmedicine.co custom domain serves documentation only in this preview; it is not an operational client analysis base URL. Sandbox routing must be confirmed by NGM; there is no public aroga-sandbox service slug.\n\nUse an account-issued ngm_dev_ bearer key. No OAuth or per-operation scopes exist in the current key model. Effective scope is this five-operation allowlist and the authenticated account's own jobs/objects. Every output remains a draft for physician review. See /docs for integration, recovery, limits and retention."},"servers":[{"url":"https://www.nextgenerationmedicine.co/api/developer/v1/aroga","description":"Official NGM Detailed gateway; requires separately enabled account routing. Preview host does not process analyses."}],"x-aroga-release-status":"documentation-preview","x-aroga-analysis-enabled":false,"x-aroga-planned-documentation-host":"aroga-sandbox.api.nextgenerationmedicine.co","x-aroga-environment":"sandbox","security":[{"DeveloperBearer":[]}],"tags":[{"name":"Files","description":"Owned private uploads and completed artifacts."},{"name":"Analysis","description":"Durable admission and read-only recovery. No cancellation operation."}],"paths":{"/api/files/presign-upload":{"post":{"tags":["Files"],"operationId":"presignArogaUpload","summary":"Obtain a private upload URL","description":"Upload URL expires after 900 seconds. PUT file bytes directly to uploadUrl using the same Content-Type and no NGM bearer credential. After a successful PUT, use key verbatim in start.file_keys. The declared size is validated; the preview does not certify storage-enforced upload limits.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PresignUpload"},"example":{"name":"synthetic-labs.pdf","mimeType":"application/pdf","size":2048}}}},"responses":{"200":{"description":"Upload receipt. Treat uploadUrl as a temporary secret.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PresignedUpload"}}}},"400":{"description":"Malformed request or missing/invalid Idempotency-Key.","headers":{"Retry-After":{"description":"Optional delay in seconds. Also inspect retry_after_seconds in the body.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Invalid or revoked developer key.","headers":{"Retry-After":{"description":"Optional delay in seconds. Also inspect retry_after_seconds in the body.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Aroga entitlement or object ownership is required.","headers":{"Retry-After":{"description":"Optional delay in seconds. Also inspect retry_after_seconds in the body.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown route, or an inaccessible/expired job. This does not authorize a replacement analysis.","headers":{"Retry-After":{"description":"Optional delay in seconds. Also inspect retry_after_seconds in the body.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Declared file size exceeds 200 MiB or gateway JSON exceeds 1,000,000 bytes.","headers":{"Retry-After":{"description":"Optional delay in seconds. Also inspect retry_after_seconds in the body.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Shared account request/start/concurrency or monthly admission limit. Respect the retry hint.","headers":{"Retry-After":{"description":"Optional delay in seconds. Also inspect retry_after_seconds in the body.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Upstream outcome may be uncertain. Preserve the original request key and recover before any replacement.","headers":{"Retry-After":{"description":"Optional delay in seconds. Also inspect retry_after_seconds in the body.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Documentation preview, configuration, approval, database or storage gate is unavailable.","headers":{"Retry-After":{"description":"Optional delay in seconds. Also inspect retry_after_seconds in the body.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/pipeline/start":{"post":{"tags":["Analysis"],"operationId":"startArogaAnalysis","summary":"Admit an analysis or replay its receipt","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Persist before starting. A UUID is recommended. Reuse the exact same key, original body, file keys and tier for retries. Never create a new key to bypass an uncertain outcome.","schema":{"type":"string","minLength":16,"maxLength":128,"pattern":"^[A-Za-z0-9_-]{16,128}$"},"example":"82a4e6ce-6dda-41c0-91af-4111515476de"}],"description":"HTTP 200 confirms admission, not clinical validation. Persist taskId, key, tier and original payload. Changing input or tier under one key yields 409. Reserved rejected/uncertain admissions can count toward the monthly allowance. Same-key replays do not create another monthly slot. The selected gateway slug determines the tier; do not supply variant to change it.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StartRequest"},"example":{"inputs":{"input_0":"SYNTHETIC TEST ONLY. Adult age 40. Glucose: 5.0 mmol/L. No other clinical data supplied.","patient_reference":"SYNTH-AROGA-001"}}}}},"responses":{"200":{"description":"Accepted or replayed receipt. Additional fields such as replayed are optional.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StartReceipt"},"example":{"taskId":"dd42b5c1-2e98-43f0-9972-11737f3294f1","status":"started","pipeline_id":"aroga-screening-detailed"}}}},"400":{"description":"Malformed request or missing/invalid Idempotency-Key.","headers":{"Retry-After":{"description":"Optional delay in seconds. Also inspect retry_after_seconds in the body.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Invalid or revoked developer key.","headers":{"Retry-After":{"description":"Optional delay in seconds. Also inspect retry_after_seconds in the body.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Aroga entitlement or object ownership is required.","headers":{"Retry-After":{"description":"Optional delay in seconds. Also inspect retry_after_seconds in the body.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown route, or an inaccessible/expired job. This does not authorize a replacement analysis.","headers":{"Retry-After":{"description":"Optional delay in seconds. Also inspect retry_after_seconds in the body.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"idempotency_conflict, start_outcome_pending or recovery_expired. Preserve the original intent and consult /docs before retrying.","headers":{"Retry-After":{"description":"Optional delay in seconds. Also inspect retry_after_seconds in the body.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Gateway JSON exceeds 1,000,000 bytes or overall_instructions exceeds 120,000 characters.","headers":{"Retry-After":{"description":"Optional delay in seconds. Also inspect retry_after_seconds in the body.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Shared account request/start/concurrency or monthly admission limit. Respect the retry hint.","headers":{"Retry-After":{"description":"Optional delay in seconds. Also inspect retry_after_seconds in the body.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Upstream outcome may be uncertain. Preserve the original request key and recover before any replacement.","headers":{"Retry-After":{"description":"Optional delay in seconds. Also inspect retry_after_seconds in the body.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Documentation preview, configuration, approval, database or storage gate is unavailable.","headers":{"Retry-After":{"description":"Optional delay in seconds. Also inspect retry_after_seconds in the body.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/pipeline/recover":{"get":{"tags":["Analysis"],"operationId":"recoverArogaAnalysis","summary":"Recover a lost start response","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Persist before starting. A UUID is recommended. Reuse the exact same key, original body, file keys and tier for retries. Never create a new key to bypass an uncertain outcome.","schema":{"type":"string","minLength":16,"maxLength":128,"pattern":"^[A-Za-z0-9_-]{16,128}$"},"example":"82a4e6ce-6dda-41c0-91af-4111515476de"}],"description":"Read-only lookup of the same account/tier/environment and Idempotency-Key. Never starts provider work or reserves a new job. An absent lookup returns 409 start_outcome_pending and is not proof that admission failed. Keep the original key and use bounded backoff. Job metadata is accessible for seven days from creation.","responses":{"200":{"description":"Known task and status.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StartReceipt"},"example":{"taskId":"dd42b5c1-2e98-43f0-9972-11737f3294f1","status":"running","pipeline_id":"aroga-screening-detailed"}}}},"400":{"description":"Malformed request or missing/invalid Idempotency-Key.","headers":{"Retry-After":{"description":"Optional delay in seconds. Also inspect retry_after_seconds in the body.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Invalid or revoked developer key.","headers":{"Retry-After":{"description":"Optional delay in seconds. Also inspect retry_after_seconds in the body.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Aroga entitlement or object ownership is required.","headers":{"Retry-After":{"description":"Optional delay in seconds. Also inspect retry_after_seconds in the body.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown route, or an inaccessible/expired job. This does not authorize a replacement analysis.","headers":{"Retry-After":{"description":"Optional delay in seconds. Also inspect retry_after_seconds in the body.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Admission outcome remains uncertain. A retry hint may be in the body or Retry-After header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"start_outcome_pending","retry_after_seconds":3}}}},"429":{"description":"Shared account request/start/concurrency or monthly admission limit. Respect the retry hint.","headers":{"Retry-After":{"description":"Optional delay in seconds. Also inspect retry_after_seconds in the body.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Upstream outcome may be uncertain. Preserve the original request key and recover before any replacement.","headers":{"Retry-After":{"description":"Optional delay in seconds. Also inspect retry_after_seconds in the body.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Documentation preview, configuration, approval, database or storage gate is unavailable.","headers":{"Retry-After":{"description":"Optional delay in seconds. Also inspect retry_after_seconds in the body.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/pipeline/status/{taskId}":{"get":{"tags":["Analysis"],"operationId":"getArogaStatus","summary":"Poll an owned analysis and retrieve completed outputs","parameters":[{"name":"taskId","in":"path","required":true,"description":"Owned job UUID returned as taskId by start or recover.","schema":{"type":"string","format":"uuid"},"example":"dd42b5c1-2e98-43f0-9972-11737f3294f1"}],"description":"Poll with a delay, normally at least 3 seconds for one job, and account-wide backoff. Require completed status AND both result.output_0 and result.Visual_Report. Validation false requires review; missing validation is unknown, never pass. Automated validation is not clinical approval. Preserve the task ID if artifacts cannot be recovered; do not restart to recover content.","responses":{"200":{"description":"Running, completed or failed job. HTTP 200 alone does not establish a successful report.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobStatus"},"example":{"status":"running","completed":false,"pipeline_id":"aroga-screening-detailed"}}}},"400":{"description":"Malformed request or missing/invalid Idempotency-Key.","headers":{"Retry-After":{"description":"Optional delay in seconds. Also inspect retry_after_seconds in the body.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Invalid or revoked developer key.","headers":{"Retry-After":{"description":"Optional delay in seconds. Also inspect retry_after_seconds in the body.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Aroga entitlement or object ownership is required.","headers":{"Retry-After":{"description":"Optional delay in seconds. Also inspect retry_after_seconds in the body.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown route, or an inaccessible/expired job. This does not authorize a replacement analysis.","headers":{"Retry-After":{"description":"Optional delay in seconds. Also inspect retry_after_seconds in the body.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Shared account request/start/concurrency or monthly admission limit. Respect the retry hint.","headers":{"Retry-After":{"description":"Optional delay in seconds. Also inspect retry_after_seconds in the body.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Upstream outcome may be uncertain. Preserve the original request key and recover before any replacement.","headers":{"Retry-After":{"description":"Optional delay in seconds. Also inspect retry_after_seconds in the body.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Documentation preview, configuration, approval, database or storage gate is unavailable.","headers":{"Retry-After":{"description":"Optional delay in seconds. Also inspect retry_after_seconds in the body.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/reports/{jobId}":{"get":{"tags":["Files"],"operationId":"getArogaReports","summary":"List completed artifact download links","parameters":[{"name":"jobId","in":"path","required":true,"description":"Owned job UUID returned as taskId by start or recover.","schema":{"type":"string","format":"uuid"},"example":"dd42b5c1-2e98-43f0-9972-11737f3294f1"}],"description":"Returns four persisted artifacts: output_0.md, Visual_Report.html, panel.json and meta.json. Signed links expire within one hour. Keep them private and download without sending the NGM developer key. Requires an owned completed job within the seven-day job access window.","responses":{"200":{"description":"Private report artifacts and temporary URLs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Reports"}}}},"400":{"description":"Malformed request or missing/invalid Idempotency-Key.","headers":{"Retry-After":{"description":"Optional delay in seconds. Also inspect retry_after_seconds in the body.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Invalid or revoked developer key.","headers":{"Retry-After":{"description":"Optional delay in seconds. Also inspect retry_after_seconds in the body.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Aroga entitlement or object ownership is required.","headers":{"Retry-After":{"description":"Optional delay in seconds. Also inspect retry_after_seconds in the body.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown route, or an inaccessible/expired job. This does not authorize a replacement analysis.","headers":{"Retry-After":{"description":"Optional delay in seconds. Also inspect retry_after_seconds in the body.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Shared account request/start/concurrency or monthly admission limit. Respect the retry hint.","headers":{"Retry-After":{"description":"Optional delay in seconds. Also inspect retry_after_seconds in the body.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Upstream outcome may be uncertain. Preserve the original request key and recover before any replacement.","headers":{"Retry-After":{"description":"Optional delay in seconds. Also inspect retry_after_seconds in the body.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Documentation preview, configuration, approval, database or storage gate is unavailable.","headers":{"Retry-After":{"description":"Optional delay in seconds. Also inspect retry_after_seconds in the body.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"DeveloperBearer":{"type":"http","scheme":"bearer","bearerFormat":"ngm_dev_","description":"Account-issued NGM developer key. Keep it on your backend. Effective access is account-bound; no OAuth scopes or engine credentials are supplied by clients."}},"schemas":{"Error":{"type":"object","additionalProperties":true,"properties":{"error":{"type":"string","description":"Safe machine-readable code where available."},"message":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"statusCode":{"type":"integer"},"retry_after_seconds":{"type":"integer","minimum":1},"request_id":{"type":"string"},"limit":{"type":"integer"},"used":{"type":"integer"}}},"PresignUpload":{"type":"object","required":["name","mimeType"],"properties":{"name":{"type":"string","description":"Neutral filename; avoid patient identifiers.","example":"synthetic-labs.pdf"},"mimeType":{"type":"string","enum":["application/pdf","image/jpeg","image/png","image/gif","image/webp","text/plain","text/csv","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"]},"size":{"type":"integer","minimum":0,"maximum":209715200,"description":"Declared byte size; strongly recommended."}}},"PresignedUpload":{"type":"object","required":["uploadUrl","key","fileId","expiresIn"],"properties":{"uploadUrl":{"type":"string","format":"uri","description":"Sensitive temporary PUT URL."},"key":{"type":"string","description":"Opaque owned object key; use verbatim."},"fileId":{"type":"string"},"expiresIn":{"type":"integer","enum":[900]}}},"StartRequest":{"type":"object","description":"Supply useful clinical input and/or owned uploaded files. Optional legacy engine fields are not needed for this integration.","properties":{"inputs":{"type":"object","additionalProperties":true,"properties":{"input_0":{"type":"string","description":"Clinical input text. primary_input is a legacy alias."},"patient_reference":{"type":"string","description":"Coded patient reference; do not use a patient name.","example":"SYNTH-AROGA-001"},"clinician":{"type":"object","properties":{"physician_name":{"type":"string","description":"Trimmed and truncated to 120 characters in the report header."},"practice":{"type":"string","description":"Trimmed and truncated to 120 characters in the report header."}}},"overall_instructions":{"type":"string","maxLength":120000,"description":"Optional context. Cannot override fixed Aroga template and safety rules."},"Previous_Data":{"type":"string","description":"Optional approved previous clinical text."},"file_keys":{"type":"array","items":{"type":"string"},"description":"Legacy nested form; takes precedence over top-level file_keys. Do not send both."}}},"file_keys":{"type":"array","items":{"type":"string"},"description":"Keys returned by successful uploads for this account, tier and environment."}}},"StartReceipt":{"type":"object","required":["taskId","status","pipeline_id"],"properties":{"taskId":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["started","pending","running","completed","failed"]},"pipeline_id":{"type":"string","enum":["aroga-screening-detailed","aroga-screening-lean"]},"totalStages":{"type":"integer"},"replayed":{"type":"boolean","description":"Optional: not retained in every gateway receipt."},"engine_url":{"type":"string","format":"uri","description":"Server-stamped provenance only; not a client API base URL."}}},"Validation":{"type":"object","required":["passed","errors","warnings"],"properties":{"passed":{"type":"boolean","description":"Automated rule validation, not physician approval. False requires review; missing is unknown."},"errors":{"type":"array","items":{"type":"string"},"description":"Stable diagnostic codes, not raw patient excerpts."},"warnings":{"type":"array","items":{"type":"string"},"description":"Preserve warning codes even when passed is true."}},"example":{"passed":false,"errors":["required_heading_missing"],"warnings":["unmapped_biomarkers"]}},"ReportResult":{"type":"object","required":["output_0","Visual_Report","validation","template_id","template_version","ranges_version","guidelines_version"],"additionalProperties":true,"properties":{"output_0":{"type":"string","minLength":1,"description":"Sensitive Markdown draft report for physician review."},"Visual_Report":{"type":"string","minLength":1,"description":"Sensitive HTML draft. Render in an isolated restricted viewer."},"panel":{"type":"object","additionalProperties":true,"description":"Structured clinical extraction; protect as report content."},"validation":{"$ref":"#/components/schemas/Validation"},"job_id":{"type":"string","format":"uuid"},"pipeline_id":{"type":"string"},"template_id":{"type":"string"},"template_version":{"type":"string"},"ranges_version":{"type":"string"},"guidelines_version":{"type":"string"}}},"JobStatus":{"type":"object","required":["status","completed"],"properties":{"status":{"type":"string","enum":["running","completed","failed"]},"completed":{"type":"boolean"},"result":{"$ref":"#/components/schemas/ReportResult"},"validation":{"$ref":"#/components/schemas/Validation"},"error":{"type":"string","description":"Safe job failure code; status failed is not a successful analysis."},"stage":{"type":"string"},"stageIndex":{"type":"integer"},"totalStages":{"type":"integer"},"pipeline_id":{"type":"string"},"template_version":{"type":"string"},"ranges_version":{"type":"string"}}},"Reports":{"type":"object","required":["jobId","reports"],"properties":{"jobId":{"type":"string","format":"uuid"},"reports":{"type":"array","items":{"type":"object","required":["key","type","size","lastModified","signedUrl"],"properties":{"key":{"type":"string"},"type":{"type":"string","enum":["output_0","Visual_Report","panel","meta"]},"size":{"type":"integer","minimum":0},"lastModified":{"type":"string","format":"date-time"},"signedUrl":{"type":"string","format":"uri","description":"Private download URL, valid for at most one hour."}}}}}}}}}