MySimpleReport API Integration Guide
Submit medical files or text, receive structured analysis, and build plain-language health report workflows into your own product.
curl -X POST https://dev.mysimplereport.com/v1/analyze-file \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "file_url": "https://example.com/report.pdf" }'
Build against MySimpleReport
The MySimpleReport API enables developers to programmatically submit medical documents, images, and text for AI analysis. The API returns a structured analysis object in JSON format — a plain-language title and explanation, detailed findings, key result cards, and suggested questions for your doctor — ready to integrate into your application workflow.
1. How Authentication Works
All API requests must be authenticated using an API key passed as a Bearer token in the Authorization header.
The Bearer Token Lifecycle
Every request must include your API Key inside the Authorization HTTP header using the standard Bearer scheme (defined in RFC 6750):
Authorization: Bearer YOUR_API_KEY
Behind the scenes: The server reads the header, strips out the Bearer prefix, and hashes your raw key utilizing secure SHA-256 algorithms. It checks its presence against the active database clusters, ensuring the key hasn't expired or crossed rate thresholds before granting request processing rights.
Required Request Headers
| Header | Value | Required | Notes |
|---|---|---|---|
Authorization |
Bearer YOUR_API_KEY |
Yes | Prefix must be exactly Bearer (including the trailing space) |
Content-Type |
application/json |
Yes | All inbound request bodies must be JSON format |
Accept |
application/json |
Yes | All outbound responses are served in JSON format |
Example Raw Header Block
POST /v1/analyze-file HTTP/1.1
Host: dev.mysimplereport.com
Authorization: Bearer msr_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4
Content-Type: application/json
Accept: application/json
2. Base Configuration
| Base URL | https://dev.mysimplereport.com/v1 |
| Protocol | HTTPS (TLS 1.2+ required) |
| Data Format | JSON (Request body & Response parsing) |
| Auth Method | Bearer Token (API Key Verified) |
| Encoding | UTF-8 |
3. API Endpoints
3.1 Analyze Single File
Submits a single medical document or image for analysis — either uploaded directly (multipart/form-data) or referenced by a publicly accessible URL.
Request Body Fields
| Parameter | Type | Required | Description |
|---|---|---|---|
file |
File (multipart) | Either | The document/image to analyze, uploaded directly as multipart/form-data. Use this or file_url. |
file_url |
String (JSON) | Either | A publicly accessible URL to the file. The server downloads it. Use this or upload a file. |
purpose |
String | No | Optional context hint (e.g., "lab_report", "radiology", "prescription") |
Code Examples — Option A: upload a file directly
curl -X POST https://dev.mysimplereport.com/v1/analyze-file \
-H "Authorization: Bearer msr_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4" \
-F "file=@/path/to/blood-test.pdf" \
-F "purpose=lab_report"
import requests
url = "https://dev.mysimplereport.com/v1/analyze-file"
headers = {"Authorization": "Bearer msr_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4"}
with open("blood-test.pdf", "rb") as f:
response = requests.post(
url,
headers=headers,
files={"file": ("blood-test.pdf", f, "application/pdf")},
data={"purpose": "lab_report"},
)
result = response.json()
print(response.status_code)
print(result["analysis"]["title"])
print(result["analysis"]["simple_explanation"])
import fs from "node:fs";
const form = new FormData();
form.append("file", new Blob([fs.readFileSync("blood-test.pdf")]), "blood-test.pdf");
form.append("purpose", "lab_report");
const response = await fetch("https://dev.mysimplereport.com/v1/analyze-file", {
method: "POST",
headers: { "Authorization": "Bearer msr_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4" },
body: form
});
const result = await response.json();
console.log(response.status);
console.log(result.analysis.title);
console.log(result.analysis.simple_explanation);
using System.Net.Http.Headers;
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer msr_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4");
using var form = new MultipartFormDataContent();
using var stream = File.OpenRead("blood-test.pdf");
var fileContent = new StreamContent(stream);
fileContent.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
form.Add(fileContent, "file", "blood-test.pdf");
form.Add(new StringContent("lab_report"), "purpose");
var response = await client.PostAsync("https://dev.mysimplereport.com/v1/analyze-file", form);
var json = await response.Content.ReadAsStringAsync();
Console.WriteLine((int)response.StatusCode);
Console.WriteLine(json);
<?php
$ch = curl_init("https://dev.mysimplereport.com/v1/analyze-file");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer msr_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4",
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, [
"file" => new CURLFile("blood-test.pdf", "application/pdf"),
"purpose" => "lab_report",
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
echo $status . PHP_EOL;
$result = json_decode($response, true);
echo $result["analysis"]["simple_explanation"];
cURL — Option B: pass a file URL (JSON)
curl -X POST https://dev.mysimplereport.com/v1/analyze-file \
-H "Authorization: Bearer msr_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"file_url": "https://yourdomain.com/files/blood-test.pdf",
"purpose": "lab_report"
}'
Expected Response (200 OK)
{
"status": "success",
"request_id": "5b5ccc65-9005-46dd-85cf-757c915bd386",
"processed_at": "2026-07-16T15:23:18.4466629Z",
"file_url": "https://yourdomain.com/files/blood-test.pdf",
"purpose": "lab_report",
"analysis": {
"title": "Understanding Your Blood Test Results",
"simple_explanation": "<h2>About Your Blood Work</h2><p>You recently had a blood test to check the health of your blood cells... Every single one of your blood counts is in a healthy range.</p>",
"detailed_findings": "<h2>Detailed Findings</h2><h3>Blood Count Results</h3><ul><li><strong>Oxygen-Carrying Protein (Hemoglobin):</strong> Your result: 14.2 g/dL... within the normal range of 13.5 to 17.5 g/dL.</li></ul>",
"important_findings_summary": "<h2>Important Findings Summary</h2><h3>Results That Need Attention</h3><p>Great news — all your results are within healthy ranges.</p>",
"glossary": "<h2>Medical Terms Explained</h2><ul><li><strong>Hemoglobin:</strong> The protein in red blood cells that carries oxygen through your body.</li></ul>",
"summary_cards": [
{ "label": "Oxygen-Carrying Protein (Hemoglobin)", "value": "14.2", "unit": "g/dL", "status": "normal", "note": "Healthy range: 13.5–17.5" },
{ "label": "White Blood Cell Count (WBC)", "value": "8200", "unit": "/mcL", "status": "normal", "note": "Healthy range: 4500–11000" },
{ "label": "Clotting Cells (Platelets)", "value": "225000", "unit": "/mcL", "status": "normal", "note": "Healthy range: 150000–450000" }
],
"ask_your_doctor": [
"Since my blood counts are all healthy, is there anything specific I should keep doing to maintain this good health?",
"How often should I have these blood tests repeated as part of my general check-ups?"
]
},
"usage": {
"documents_analyzed": 1,
"credits_used": 1,
"credits_remaining": null
}
}
Important:
simple_explanation, detailed_findings,
important_findings_summary and glossary contain
ready-to-render HTML (<h2>, <p>,
<ul>, <strong>) — not plain text. Inject them into your page
as HTML. title, summary_cards and ask_your_doctor are plain
text. credits_remaining is null when the key has no prepaid credit balance.
3.2 Analyze Multiple Files
Submits two or more files in a single request for batch analysis (maximum of 20 elements per batch array request).
Supported Formats Matrix
| Category | Formats Extension Mapping |
|---|---|
| Documents | .pdf |
| Images | .jpg, .jpeg, .png, .gif, .webp, .tiff, .bmp |
Code Examples — Option A: upload files directly
curl -X POST https://dev.mysimplereport.com/v1/analyze-multiple-files \
-H "Authorization: Bearer msr_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4" \
-F "files=@/path/to/blood-test.pdf" \
-F "files=@/path/to/xray.jpg" \
-F "purpose=lab_report"
import requests
url = "https://dev.mysimplereport.com/v1/analyze-multiple-files"
headers = {"Authorization": "Bearer msr_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4"}
files = [
("files", ("blood-test.pdf", open("blood-test.pdf", "rb"), "application/pdf")),
("files", ("xray.jpg", open("xray.jpg", "rb"), "image/jpeg")),
]
response = requests.post(url, headers=headers, files=files, data={"purpose": "lab_report"})
result = response.json()
for item in result["results"]:
print(item["filename"], "->", item["status"])
if item["status"] == "success":
print(" ", item["analysis"]["title"])
import fs from "node:fs";
const form = new FormData();
form.append("files", new Blob([fs.readFileSync("blood-test.pdf")]), "blood-test.pdf");
form.append("files", new Blob([fs.readFileSync("xray.jpg")]), "xray.jpg");
form.append("purpose", "lab_report");
const response = await fetch("https://dev.mysimplereport.com/v1/analyze-multiple-files", {
method: "POST",
headers: { "Authorization": "Bearer msr_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4" },
body: form
});
const result = await response.json();
for (const item of result.results) {
console.log(item.filename, "->", item.status);
if (item.status === "success") console.log(" ", item.analysis.title);
}
using System.Net.Http.Headers;
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer msr_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4");
using var form = new MultipartFormDataContent();
foreach (var (path, mime) in new[] { ("blood-test.pdf", "application/pdf"), ("xray.jpg", "image/jpeg") })
{
var bytes = await File.ReadAllBytesAsync(path);
var part = new ByteArrayContent(bytes);
part.Headers.ContentType = new MediaTypeHeaderValue(mime);
form.Add(part, "files", Path.GetFileName(path));
}
form.Add(new StringContent("lab_report"), "purpose");
var response = await client.PostAsync("https://dev.mysimplereport.com/v1/analyze-multiple-files", form);
Console.WriteLine(await response.Content.ReadAsStringAsync());
<?php
$ch = curl_init("https://dev.mysimplereport.com/v1/analyze-multiple-files");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer msr_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4",
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, [
"files[0]" => new CURLFile("blood-test.pdf", "application/pdf"),
"files[1]" => new CURLFile("xray.jpg", "image/jpeg"),
"purpose" => "lab_report",
]);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
foreach ($result["results"] as $item) {
echo $item["filename"] . " -> " . $item["status"] . PHP_EOL;
}
cURL — Option B: pass file URLs (JSON)
curl -X POST https://dev.mysimplereport.com/v1/analyze-multiple-files \
-H "Authorization: Bearer msr_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"file_urls": [
"https://yourdomain.com/files/blood-test.pdf",
"https://yourdomain.com/files/xray.jpg"
],
"purpose": "lab_report"
}'
Expected Response (200 OK)
{
"status": "success",
"request_id": "z9y8x7w6-v5u4-t3s2-r1q0-p9o8n7m6l5k4",
"processed_at": "2026-07-16T11:00:09Z",
"total_files": 2,
"purpose": "lab_report",
"results": [
{
"file_url": "https://yourdomain.com/files/blood-test.pdf",
"filename": "blood-test.pdf",
"status": "success",
"error": null,
"analysis": {
"title": "Understanding Your Blood Test Results",
"simple_explanation": "<h2>About Your Blood Work</h2><p>Every single one of your blood counts is in a healthy range.</p>",
"detailed_findings": "<h2>Detailed Findings</h2><ul><li><strong>Hemoglobin:</strong> 14.2 g/dL — within the normal range.</li></ul>",
"important_findings_summary": "<h2>Important Findings Summary</h2><p>All results are within healthy ranges.</p>",
"glossary": "<h2>Medical Terms Explained</h2><ul><li><strong>Hemoglobin:</strong> Carries oxygen through your body.</li></ul>",
"summary_cards": [
{ "label": "Hemoglobin", "value": "14.2", "unit": "g/dL", "status": "normal", "note": "Healthy range: 13.5–17.5" }
],
"ask_your_doctor": [ "How often should I repeat these blood tests?" ]
}
},
{
"file_url": "https://yourdomain.com/files/xray.jpg",
"filename": "xray.jpg",
"status": "error",
"error": "The provided content could not be analyzed.",
"analysis": null
}
],
"usage": {
"documents_analyzed": 1,
"credits_used": 1,
"credits_remaining": null
}
}
Billing — one request, one report:
all files in a single call are treated as pages/images of one medical report, so the
request costs 1 report no matter how many files you attach. Note the example above
sends 2 files yet reports "documents_analyzed": 1. Batching the pages of one report is
therefore cheaper than sending them as separate requests. A request where every file fails
bills 0 and returns 422.
Per-file results: each file is still analyzed independently — the
example shows one success and one failure. A failed file returns "status": "error", an
error message and "analysis": null, while the others still succeed. The
HTML-content note from 3.1 applies to each item's analysis block.
3.3 Analyze Text
Submits raw text content directly for processing. No file host requirement is needed (max limit of 100,000 characters).
Code Examples
curl -X POST https://dev.mysimplereport.com/v1/analyze-text \
-H "Authorization: Bearer msr_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"text": "Hemoglobin 14.2 g/dL, WBC 8200/mcL, Platelets 225000/mcL. All within normal limits.",
"purpose": "lab_report"
}'
import requests
response = requests.post(
"https://dev.mysimplereport.com/v1/analyze-text",
headers={
"Authorization": "Bearer msr_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4",
"Content-Type": "application/json",
},
json={
"text": "Hemoglobin 14.2 g/dL, WBC 8200/mcL, Platelets 225000/mcL. All within normal limits.",
"purpose": "lab_report",
},
)
result = response.json()
print(result["analysis"]["title"])
print(result["analysis"]["simple_explanation"])
const response = await fetch("https://dev.mysimplereport.com/v1/analyze-text", {
method: "POST",
headers: {
"Authorization": "Bearer msr_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4",
"Content-Type": "application/json"
},
body: JSON.stringify({
text: "Hemoglobin 14.2 g/dL, WBC 8200/mcL, Platelets 225000/mcL. All within normal limits.",
purpose: "lab_report"
})
});
const result = await response.json();
console.log(result.analysis.title);
console.log(result.analysis.simple_explanation);
using System.Text;
using System.Text.Json;
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer msr_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4");
var payload = new
{
text = "Hemoglobin 14.2 g/dL, WBC 8200/mcL, Platelets 225000/mcL. All within normal limits.",
purpose = "lab_report"
};
var content = new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json");
var response = await client.PostAsync("https://dev.mysimplereport.com/v1/analyze-text", content);
Console.WriteLine(await response.Content.ReadAsStringAsync());
<?php
$ch = curl_init("https://dev.mysimplereport.com/v1/analyze-text");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer msr_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4",
"Content-Type: application/json",
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
"text" => "Hemoglobin 14.2 g/dL, WBC 8200/mcL, Platelets 225000/mcL.",
"purpose" => "lab_report",
]));
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
echo $result["analysis"]["simple_explanation"];
Expected Response (200 OK)
{
"status": "success",
"request_id": "5b5ccc65-9005-46dd-85cf-757c915bd386",
"processed_at": "2026-07-16T15:23:18.4466629Z",
"file_url": null,
"purpose": "lab_report",
"analysis": {
"title": "Understanding Your Blood Test Results",
"simple_explanation": "<h2>About Your Blood Work</h2><p>You recently had a blood test to check the health of your blood cells... Every single one of your blood counts is in a healthy range.</p>",
"detailed_findings": "<h2>Detailed Findings</h2><h3>Blood Count Results</h3><ul><li><strong>White Blood Cell Count (WBC):</strong> Your result: 8200/mcL... within the normal range of 4500 to 11000/mcL.</li></ul>",
"important_findings_summary": "<h2>Important Findings Summary</h2><h3>Results That Need Attention</h3><p>Great news — all your results are within healthy ranges.</p>",
"glossary": "<h2>Medical Terms Explained</h2><ul><li><strong>WBC:</strong> Stands for White Blood Cells, your body's defense team against germs.</li></ul>",
"summary_cards": [
{ "label": "Oxygen-Carrying Protein (Hemoglobin)", "value": "14.2", "unit": "g/dL", "status": "normal", "note": "Healthy range: 13.5–17.5" },
{ "label": "White Blood Cell Count (WBC)", "value": "8200", "unit": "/mcL", "status": "normal", "note": "Healthy range: 4500–11000" }
],
"ask_your_doctor": [
"Since my blood counts are all healthy, is there anything specific I should keep doing to maintain this good health?",
"How often should I have these blood tests repeated as part of my general check-ups?"
]
},
"usage": {
"documents_analyzed": 1,
"credits_used": 1,
"credits_remaining": null
}
}
Live response: this is a real, unedited response shape from the
API. file_url is always null for text analysis. The HTML-content note
from 3.1 applies here too.
4. Request Parameters Reference
| Parameter Name | Target Endpoint(s) | Type Specification | Required Status | Functional Description |
|---|---|---|---|---|
file_url |
analyze-file |
String | Yes | URL route pointing to a single file object layout |
file_urls |
analyze-multiple-files |
String[] (Array) | Yes | Array structure storing file URLs (maximum capacity size: 20) |
text |
analyze-text |
String | Yes | Raw body content strings intended for validation parsing |
purpose |
All Endpoints | String | No | Context hint parameter targeting processing accuracy bounds |
language |
analyze-text |
String | No | Language explicit indicator tracking standard ISO 639-1 layout formats |
5. Status & Error Reference
All structured responses that fail processing return consistent error objects. Click an entry in the list down below to inspect detailed schema implementations:
| HTTP Status | Error Payload Code | Root Core Cause Condition |
|---|---|---|
400 Bad Request |
BAD_REQUEST | Malformed payload JSON strings or absent mandatory parameters. |
401 Unauthorized |
UNAUTHORIZED | Missing credentials or invalid bearer token configurations. |
401 Unauthorized |
KEY_EXPIRED | The allocated API key has passed its preconfigured retention lifespan. |
403 Forbidden |
KEY_DISABLED | Key execution parameters suspended via developer administration consoles. |
402 Payment Required |
QUOTA_EXPIRED | Subscription tiers or assigned runtime quotas have reached end-of-life status. |
422 Unprocessable Entity |
VALIDATION_ERROR | Unreachable source URL, corrupted files, or unsupported type schemas. |
429 Too Many Requests |
RATE_LIMIT_EXCEEDED_DAILY | The workspace has depleted its rolling daily request count limit constraints. |
429 Too Many Requests |
RATE_LIMIT_EXCEEDED_MONTHLY | Monthly processing transaction quotas have been completely filled out. |
429 Too Many Requests |
SPEND_LIMIT_EXCEEDED | Financial safety limits or billing cap milestones were reached. |
500 Internal Error |
INTERNAL_SERVER_ERROR | Unexpected system state exceptions in backend server engine pools. |
// Select a row from the validation matrix above to load contextual response payload schemas...