Blood Test API Endpoints

Last updated:

Complete reference for all Kantesti Blood Test API endpoints with code examples in multiple languages.

New on 23 September 2026: the DNA Health API

We are proud to announce three DNA modules for the Kantesti API. DNA Test Interpretation turns raw DNA data or a genetic report into a comprehensive genetic health report, the DNA + Blood Health Report combines it with a blood test, and the Supplement Advisor writes a personalised supplement plan with your clinic's own products. Read the DNA Health API reference.

New in September 2026

Blood Test Analysis v12 is the current release. Two new API families join the platform: the Body Map API, which places out-of-range results on 13 body regions, and the Biological Blood Age API, which computes PhenoAge blood age and up to 18 derived clinical indices.

Base URL
https://app.aibloodtestinterpret.com

Changelog

Track API versions, updates, and migration information. Use the recommended endpoints for new integrations.

Latest Updates (2026)

All three 2026 updates were applied to every API version listed below. Version numbers and endpoint paths did not change, so no migration is required.

  • 8 September 2026 AI model update and platform-wide improvements
  • 21 July 2026 Comprehensive improvements and bug fixes
  • 8 May 2026 Comprehensive improvements and bug fixes

Current Stable Endpoints

These endpoints are recommended for production use and new integrations.

APIEndpointStatus
Blood Test Analysis v12 /api/v12/18-09-2026/analyze Recommended New 18 Sept 2026
Blood Test Analysis (Health Score) v12 /api/v12/health-score/analyze Recommended New 18 Sept 2026
Body Map v1 /api/v1/body-map/analyze Released 18 Sept 2026 New
Biological Blood Age v1 /api/v1/blood-age/analyze Released 18 Sept 2026 New
DNA Test Interpretation v1 /api/v1/dna-interpretation/analyze Released 23 Sept 2026 New
DNA + Blood Health Report v1 /api/v1/dna-blood-report/analyze Released 23 Sept 2026 New
DNA Supplement Advisor v1 /api/v1/dna-supplements/analyze Released 23 Sept 2026 New
Blood Test Analysis v11 /api/v11/01-06-2025/analyze Stable Updated 8 Sept 2026
Blood Test Analysis (Health Score) v11 /api/v11/health-score/analyze Stable Updated 8 Sept 2026
Nutrition Diet AI v1 /api/v1/nutrition/diet-plan/analyze Stable Updated 8 Sept 2026
AI Blood Test Comparison v1 /api/v1/bloodtest/comparison/analyze Stable Updated 8 Sept 2026
Family Health Risk Assessment v1 /api/v1/family-health/analyze Released 23 Mar 2026 Updated 8 Sept 2026
ICR - Intelligent Character Recognition v1 /api/icr/v1/extract Released 14 Feb 2026 Updated 8 Sept 2026
ICR Kan - Blood Test Extraction v1 /api/icr/v1/kan Released 14 Feb 2026 Updated 8 Sept 2026
Trend Analysis v1 /api/v1/analytics/trends/analyze Stable Updated 8 Sept 2026

Version History

DateVersionChanges
5 November 2026 Blood Test Analysis v12, Nutrition API v1 Qualitative (binary) rows: range fields are null, evaluation is good or bad; every evaluation value is listed under evaluation. lab_date falls back to the result date. Nutrition plans follow dietary_preferences, dietary_restrictions and allergies in every section; supplements follow the abnormal markers.
23 September 2026 DNA Test Interpretation v1, DNA + Blood Health Report v1, DNA Supplement Advisor v1 DNA Health API released — DNA test interpretation from raw DNA data (23andMe, AncestryDNA, MyHeritage, FTDNA, LivingDNA, VCF) or genetic report files against 334 curated markers, a combined DNA + blood health report, and a supplement advisor with the clinic's own product catalogue; async mode and sandbox
September 2026 Blood Test Analysis v12 Blood Test Analysis v12 released — multi-file upload, 100-language reporting, optional health score and disease risk analysis, sandbox mode
September 2026 Body Map v1, Biological Blood Age v1 Body Map API and Biological Blood Age API released — organ-level mapping of out-of-range results across 13 anatomical regions, and PhenoAge biological age with up to 18 derived clinical indices; both offer a deterministic mode and a sandbox
September 2026 All versions AI model update pinned to the latest model version; comprehensive improvements and bug fixes across all API versions; version numbers unchanged; 98.89% accuracy on medical faculty exams (latest open-source benchmark)
July 2026 All versions Comprehensive improvements and bug fixes applied to all API versions; version numbers unchanged
May 2026 All versions Comprehensive improvements and bug fixes applied to all API versions; version numbers unchanged
March 2026 Family Health v1 Family Health Risk Assessment API released — AI-powered hereditary risk analysis, 100+ language support, family tree analysis, preventive care timeline, genetic screening recommendations, sandbox mode
February 2026 ICR v1 ICR (Intelligent Character Recognition) API released — 79% faster than OCR, structured JSON output, document type detection, table extraction, Kan blood test integration
December 2025 Latest Improved error handling, 98.7% accuracy, 100 language support
June 2025 v11 v11 Blood Test Analysis, health score endpoint, multi-file support
April 2025 v9 api_parameters_v9 model, enhanced parameter extraction
March 2025 v8 Multi-file upload support, batch processing

Legacy Endpoints

These endpoints are maintained for backward compatibility but are not recommended for new integrations.

VersionEndpointStatus
v10 /api/v10/health-score/analyze Legacy
v9 /api/v9/14-04-2025/analyze Legacy
v8 /api/v8/31-03-2025/analyze Legacy
v6 /api/v6-1/21-11-2024/analyze Legacy
v3 /api/v3/10-10-2024/analyze Legacy
Note

Legacy endpoints are maintained for backward compatibility but are not recommended for new integrations. Please migrate to the current stable endpoints for better performance and support.

Supported Languages Reference

The Kantesti API supports 100 languages for response localization. Use the language parameter with any ISO 639-1 code listed below. If not specified, responses default to English (en).

Default Language

If no language parameter is provided, the API returns responses in English (en).

Major World Languages

CodeLanguageNative Name
enEnglishEnglish
zhChinese中文
esSpanishEspañol
arArabicالعربية
hiHindiहिन्दी
ptPortuguesePortuguês
ruRussianРусский
jaJapanese日本語
frFrenchFrançais
deGermanDeutsch
koKorean한국어
trTurkishTürkçe

European Languages

CodeLanguageNative Name
itItalianItaliano
nlDutchNederlands
plPolishPolski
elGreekΕλληνικά
svSwedishSvenska
noNorwegianNorsk
daDanishDansk
fiFinnishSuomi
csCzechČeština
ukUkrainianУкраїнська
roRomanianRomână
huHungarianMagyar
bgBulgarianБългарски
hrCroatianHrvatski
skSlovakSlovenčina
slSlovenianSlovenščina
srSerbianСрпски
ltLithuanianLietuvių
lvLatvianLatviešu
etEstonianEesti
caCatalanCatalà
euBasqueEuskara
glGalicianGalego
cyWelshCymraeg
gaIrishGaeilge
isIcelandicÍslenska
mtMalteseMalti
sqAlbanianShqip
mkMacedonianМакедонски
bsBosnianBosanski
lbLuxembourgishLëtzebuergesch
beBelarusianБеларуская

Middle Eastern & Central Asian Languages

CodeLanguageNative Name
heHebrewעברית
faPersianفارسی
azAzerbaijaniAzərbaycan
kaGeorgianქართული
hyArmenianՀայերdelays
kkKazakhҚазақша
uzUzbekOʻzbek
tgTajikТоҷикӣ
kyKyrgyzКыргызча
tkTurkmenTürkmen
mnMongolianМонгол
psPashtoپښتو
kuKurdishKurdî

South Asian Languages

CodeLanguageNative Name
bnBengaliবাংলা
taTamilதமிழ்
teTeluguతెలుగు
mrMarathiमराठी
guGujaratiગુજરાતી
knKannadaಕನ್ನಡ
mlMalayalamമലയാളം
paPunjabiਪੰਜਾਬੀ
urUrduاردو
neNepaliनेपाली
siSinhalaසිංහල
sdSindhiسنڌي
asAssameseঅসমীয়া
orOdiaଓଡ଼ିଆ

Southeast Asian Languages

CodeLanguageNative Name
idIndonesianBahasa Indonesia
thThaiไทย
viVietnameseTiếng Việt
msMalayBahasa Melayu
myMyanmar (Burmese)မြန်မာ
kmKhmerភាសាខ្មែរ
loLaoລາວ
filFilipinoFilipino
tlTagalogTagalog
jvJavaneseBasa Jawa
suSundaneseBasa Sunda

African Languages

CodeLanguageNative Name
afAfrikaansAfrikaans
swSwahiliKiswahili
amAmharicአማርኛ
haHausaHausa
yoYorubaYorùbá
igIgboIgbo
zuZuluisiZulu
xhXhosaisiXhosa
soSomaliSoomaali
mgMalagasyMalagasy

Other Languages

CodeLanguageNative Name
laLatinLatina
eoEsperantoEsperanto
yiYiddishייִדיש
htHaitian CreoleKreyòl Ayisyen
miMaoriTe Reo Māori
smSamoanGagana Samoa
toTonganLea Faka-Tonga
hawHawaiianʻŌlelo Hawaiʻi

Blood Test Analysis API

Analyze blood test images or PDFs using AI to extract parameters and generate comprehensive medical interpretations.

POST /api/v12/18-09-2026/analyze Latest

Production endpoint for blood test analysis. Upload one or more blood test images or a PDF and receive structured parameters, patient and laboratory metadata, and a full clinical interpretation in any of the 100 supported languages. Consumes 1 credit per request.

Request Parameters

ParameterTypeRequiredDescription
usernamestringYesYour API username
passwordstringYesYour API password
filefileYesBlood test image (PNG, JPG, WEBP) or PDF. Max 20MB. Repeat the field to send several images.
languagestringNoResponse language code (default: en). See supported languages.
pdf_passwordstringNoPassword for encrypted PDFs

cURL Example

curl -X POST "https://app.aibloodtestinterpret.com/api/v12/18-09-2026/analyze" \
  -F "username=YOUR_USERNAME" \
  -F "password=YOUR_PASSWORD" \
  -F "language=en" \
  -F "file=@blood_test.pdf"

Python Example

import requests

def analyze_blood_test(file_paths, username, password, language="en"):
    """
    Analyze a blood test with Kantesti Blood Test Analysis v12.

    Args:
        file_paths: One or more paths to blood test images, or a single PDF
        username: API username
        password: API password
        language: Report language code (default: en)

    Returns:
        dict: Structured parameters, metadata and clinical interpretation
    """
    url = "https://app.aibloodtestinterpret.com/api/v12/18-09-2026/analyze"

    handles = [open(path, "rb") for path in file_paths]
    try:
        files = [("file", (path, handle)) for path, handle in zip(file_paths, handles)]
        data = {"username": username, "password": password, "language": language}
        response = requests.post(url, files=files, data=data, timeout=300)
        response.raise_for_status()
        return response.json()
    finally:
        for handle in handles:
            handle.close()

# Example usage
if __name__ == "__main__":
    result = analyze_blood_test(
        file_paths=["blood_test.pdf"],
        username="your_username",
        password="your_password",
        language="en"
    )
    print(f"Status: {result['status']}")
    for param in result["data"]["parameters"]:
        print(f"  {param['short_name']}: {param['result']} {param['unit']} ({param['evaluation']})")

Example Response

{
  "status": "success",
  "api_version": "v12",
  "data": {
    "metadata": {
      "patient_name": "Jan Novak",
      "patient_age": "45",
      "patient_sex": "Male",
      "lab_name": "BioLAB Medical Center",
      "lab_city": "Prague",
      "lab_country": "Czech Republic",
      "lab_date": "2026-09-11",
      "results_date": "2026-09-12"
    },
    "parameters": [
      {"short_name": "Glucose", "long_name": "Fasting Blood Glucose", "result": "92", "unit": "mg/dL", "reference_range": "74 - 100", "range_normal_min": 74, "range_normal_max": 100, "type": "range", "evaluation": "normal"},
      {"short_name": "ALT", "long_name": "Alanine aminotransferase", "result": "65", "unit": "U/L", "reference_range": "< 45", "range_normal_min": 7, "range_normal_max": 45, "type": "range", "evaluation": "high"},
      {"short_name": "Creatinine", "long_name": "Creatinine", "result": "0.9", "unit": "mg/dL", "reference_range": "0.7 - 1.2", "range_normal_min": 0.7, "range_normal_max": 1.2, "type": "range", "evaluation": "normal"}
    ],
    "interpretation": [
      {"shortcode": "overview", "item": "Most parameters are within their reference ranges."},
      {"shortcode": "key_findings", "item": "Alanine aminotransferase is above the reference range, which warrants a follow-up liver panel."}
    ]
  },
  "timestamp": "2026-09-18T10:30:00Z"
}
POST /api/v11/01-06-2025/analyze Stable

Production endpoint for blood test analysis. Consumes 1 credit per request.

Request Parameters

ParameterTypeRequiredDescription
usernamestringYesYour API username
passwordstringYesYour API password
filefileYesBlood test image (PNG, JPG, WEBP) or PDF. Max 20MB.
languagestringNoResponse language code (default: en). See supported languages.

cURL Example

curl -X POST "https://app.aibloodtestinterpret.com/api/v11/01-06-2025/analyze" \
  -F "username=YOUR_USERNAME" \
  -F "password=YOUR_PASSWORD" \
  -F "language=en" \
  -F "file=@blood_test.pdf"

Python Example

import requests

def analyze_blood_test(file_path: str, username: str, password: str, language: str = "en"):
    """
    Analyze a blood test file using Kantesti API.

    Args:
        file_path: Path to the blood test PDF or image
        username: API username
        password: API password
        language: Response language code (default: en)

    Returns:
        dict: API response with analysis results
    """
    url = "https://app.aibloodtestinterpret.com/api/v11/01-06-2025/analyze"

    with open(file_path, "rb") as f:
        files = {"file": (file_path, f, "application/pdf")}
        data = {
            "username": username,
            "password": password,
            "language": language
        }

        response = requests.post(url, files=files, data=data, timeout=120)
        response.raise_for_status()
        return response.json()

# Example usage
if __name__ == "__main__":
    result = analyze_blood_test(
        file_path="blood_test.pdf",
        username="your_username",
        password="your_password",
        language="en"
    )
    print(f"Status: {result['status']}")
    print(f"Parameters found: {len(result['data']['parameters'])}")

C++ Example (libcurl)

#include <iostream>
#include <string>
#include <curl/curl.h>

size_t WriteCallback(void* contents, size_t size, size_t nmemb, std::string* userp) {
    userp->append((char*)contents, size * nmemb);
    return size * nmemb;
}

std::string analyzeBloodTest(const std::string& filePath,
                              const std::string& username,
                              const std::string& password,
                              const std::string& language = "en") {
    CURL* curl = curl_easy_init();
    std::string response;

    if (curl) {
        curl_mime* form = curl_mime_init(curl);
        curl_mimepart* field;

        // Add username
        field = curl_mime_addpart(form);
        curl_mime_name(field, "username");
        curl_mime_data(field, username.c_str(), CURL_ZERO_TERMINATED);

        // Add password
        field = curl_mime_addpart(form);
        curl_mime_name(field, "password");
        curl_mime_data(field, password.c_str(), CURL_ZERO_TERMINATED);

        // Add language
        field = curl_mime_addpart(form);
        curl_mime_name(field, "language");
        curl_mime_data(field, language.c_str(), CURL_ZERO_TERMINATED);

        // Add file
        field = curl_mime_addpart(form);
        curl_mime_name(field, "file");
        curl_mime_filedata(field, filePath.c_str());

        curl_easy_setopt(curl, CURLOPT_URL,
            "https://app.aibloodtestinterpret.com/api/v11/01-06-2025/analyze");
        curl_easy_setopt(curl, CURLOPT_MIMEPOST, form);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
        curl_easy_setopt(curl, CURLOPT_TIMEOUT, 120L);

        CURLcode res = curl_easy_perform(curl);

        curl_mime_free(form);
        curl_easy_cleanup(curl);
    }
    return response;
}

int main() {
    std::string result = analyzeBloodTest("blood_test.pdf", "username", "password");
    std::cout << result << std::endl;
    return 0;
}

Postman Configuration

{
  "info": {
    "name": "Kantesti Blood Test API",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "item": [
    {
      "name": "Analyze Blood Test",
      "request": {
        "method": "POST",
        "header": [],
        "body": {
          "mode": "formdata",
          "formdata": [
            {"key": "username", "value": "{{api_username}}", "type": "text"},
            {"key": "password", "value": "{{api_password}}", "type": "text"},
            {"key": "language", "value": "en", "type": "text"},
            {"key": "file", "type": "file", "src": "/path/to/blood_test.pdf"}
          ]
        },
        "url": {
          "raw": "https://app.aibloodtestinterpret.com/api/v11/01-06-2025/analyze",
          "protocol": "https",
          "host": ["app", "aibloodtestinterpret", "com"],
          "path": ["api", "v11", "01-06-2025", "analyze"]
        }
      }
    }
  ]
}

Example Response

{
  "status": "success",
  "data": {
    "metadata": {
      "patient_name": "Jan Novák",
      "lab_name": "BioLAB Medical Center",
      "lab_city": "Prague",
      "lab_country": "Czech Republic",
      "lab_date": "2025-05-11",
      "patient_age": "45",
      "patient_sex": "Male"
    },
    "parameters": [
      {
        "short_name": "WBC",
        "long_name": "White Blood Cell Count",
        "category": "Complete Blood Count",
        "result": 7.2,
        "unit": "10^9/L",
        "evaluation": "normal",
        "range_min": 2.0,
        "range_max": 12.0,
        "range_normal_min": 4.0,
        "range_normal_max": 10.0,
        "short_description": "Measures the total white blood cells in blood.",
        "long_description": "White blood cells (leukocytes) are essential for immune function..."
      },
      {
        "short_name": "HGB",
        "long_name": "Hemoglobin",
        "category": "Complete Blood Count",
        "result": 14.5,
        "unit": "g/dL",
        "evaluation": "normal",
        "range_min": 10.0,
        "range_max": 18.0,
        "range_normal_min": 13.5,
        "range_normal_max": 17.5,
        "short_description": "Protein in red blood cells that carries oxygen.",
        "long_description": "Hemoglobin is the iron-containing protein responsible for oxygen transport..."
      }
    ],
    "interpretation": [
      {
        "title": "Overall Health Assessment",
        "shortcode": "overall_health_assessment",
        "subsections": [
          {
            "subtitle": "Comprehensive Overview",
            "shortcode": "overall_health_assessment_overview",
            "items": [
              {"item": "The patient demonstrates preserved overall organ function with normal hematological parameters."},
              {"item": "No significant abnormalities detected in the complete blood count."}
            ]
          }
        ]
      }
    ]
  },
  "api_version": "v11",
  "timestamp": "2025-12-22T10:30:00Z"
}

Response Fields Reference

Root Level
FieldTypeDescription
statusstring"success" or "error"
dataobjectContains all analysis results
timestampstringISO 8601 timestamp of response
api_versionstringAPI version used for processing
data.metadata Object
FieldTypeDescription
lab_datestringBlood collection date (YYYY-MM-DD). When the report prints only its result date, that date. Empty when the report shows no date at all.
results_datestringResults issue date (YYYY-MM-DD)
lab_namestringLaboratory name
lab_citystringLaboratory city
lab_countrystringLaboratory country
patient_namestringPatient's full name (metadata only, not sent to interpretation)
patient_agestringPatient's age
patient_sexstring"male", "female", or "other"
data.parameters Array Item
FieldTypeDescription
categorystringParameter category (e.g., "Complete Blood Count", "Lipid Panel")
long_namestringFull parameter name
short_namestringAbbreviated parameter name
resultstringMeasured value
unitstringUnit of measurement
typestringrange: a numeric result rated against reference ranges. binary: a qualitative result (Negative, Positive, Reactive, a titre ...) — its range fields are null, there is nothing to chart, and evaluation is good or bad.
range_optimal_minnumber|nullLower bound of the optimal range: the ideal zone, inside the normal range. How to show the three ranges (null for a binary row)
range_optimal_maxnumber|nullUpper bound of the optimal range (null for a binary row)
range_normal_minnumber|nullLower bound of the normal range: the laboratory's reference range (null for a binary row)
range_normal_maxnumber|nullUpper bound of the normal range (null for a binary row)
range_minnumber|nullLower borderline limit: between it and the normal range a result is borderline (slightly_low); below it, low (null for a binary row)
range_maxnumber|nullUpper borderline limit: between the normal range and it a result is borderline (slightly_high); above it, high (null for a binary row)
evaluationstringResult status. See evaluation values
data.interpretation Array Item
FieldTypeDescription
titlestringSection title (e.g., "Overall Health Assessment")
contentstringAI-generated medical interpretation

Complete Response Example

{
  "status": "success",
  "data": {
    "metadata": {
      "patient_name": "Anna Müller",
      "lab_name": "MedLab Diagnostics International",
      "lab_city": "Munich",
      "lab_country": "Germany",
      "lab_date": "2025-12-15",
      "results_date": "2025-12-16",
      "patient_age": "38",
      "patient_sex": "female"
    },
    "parameters": [
      {
        "short_name": "WBC",
        "long_name": "White Blood Cell Count",
        "category": "Complete Blood Count",
        "result": "6.8",
        "unit": "10^9/L",
        "evaluation": "normal",
        "range_min": "4.0",
        "range_max": "11.0",
        "range_normal_min": "4.5",
        "range_normal_max": "10.0",
        "short_description": "Measures the total number of white blood cells.",
        "long_description": "White blood cells (leukocytes) are essential components of the immune system..."
      },
      {
        "short_name": "RBC",
        "long_name": "Red Blood Cell Count",
        "category": "Complete Blood Count",
        "result": "4.52",
        "unit": "10^12/L",
        "evaluation": "normal",
        "range_min": "3.8",
        "range_max": "5.8",
        "range_normal_min": "4.0",
        "range_normal_max": "5.5",
        "short_description": "Measures the total number of red blood cells.",
        "long_description": "Red blood cells (erythrocytes) carry oxygen from the lungs to body tissues..."
      },
      {
        "short_name": "HGB",
        "long_name": "Hemoglobin",
        "category": "Complete Blood Count",
        "result": "13.2",
        "unit": "g/dL",
        "evaluation": "normal",
        "range_min": "11.5",
        "range_max": "16.0",
        "range_normal_min": "12.0",
        "range_normal_max": "15.5",
        "short_description": "Protein in red blood cells that carries oxygen.",
        "long_description": "Hemoglobin is the iron-containing protein in red blood cells responsible for oxygen transport..."
      },
      {
        "short_name": "HCT",
        "long_name": "Hematocrit",
        "category": "Complete Blood Count",
        "result": "39.8",
        "unit": "%",
        "evaluation": "normal",
        "range_min": "35.0",
        "range_max": "47.0",
        "range_normal_min": "36.0",
        "range_normal_max": "44.0",
        "short_description": "Percentage of blood volume occupied by red blood cells.",
        "long_description": "Hematocrit measures the proportion of blood that consists of red blood cells..."
      },
      {
        "short_name": "PLT",
        "long_name": "Platelet Count",
        "category": "Complete Blood Count",
        "result": "245",
        "unit": "10^9/L",
        "evaluation": "normal",
        "range_min": "150",
        "range_max": "400",
        "range_normal_min": "150",
        "range_normal_max": "350",
        "short_description": "Measures the number of platelets in blood.",
        "long_description": "Platelets (thrombocytes) are essential for blood clotting and wound healing..."
      },
      {
        "short_name": "GLU",
        "long_name": "Fasting Glucose",
        "category": "Metabolic Panel",
        "result": "102",
        "unit": "mg/dL",
        "evaluation": "borderline_high",
        "range_min": "70",
        "range_max": "140",
        "range_normal_min": "70",
        "range_normal_max": "99",
        "short_description": "Measures blood sugar level after fasting.",
        "long_description": "Fasting glucose is a key indicator of how well the body metabolizes sugar..."
      },
      {
        "short_name": "TC",
        "long_name": "Total Cholesterol",
        "category": "Lipid Panel",
        "result": "218",
        "unit": "mg/dL",
        "evaluation": "borderline_high",
        "range_min": "0",
        "range_max": "300",
        "range_normal_min": "0",
        "range_normal_max": "200",
        "short_description": "Measures total cholesterol in blood.",
        "long_description": "Total cholesterol is the sum of HDL, LDL, and VLDL cholesterol levels..."
      },
      {
        "short_name": "HDL",
        "long_name": "HDL Cholesterol",
        "category": "Lipid Panel",
        "result": "58",
        "unit": "mg/dL",
        "evaluation": "normal",
        "range_min": "35",
        "range_max": "100",
        "range_normal_min": "50",
        "range_normal_max": "90",
        "short_description": "Measures 'good' cholesterol level.",
        "long_description": "HDL (high-density lipoprotein) cholesterol helps remove other forms of cholesterol..."
      },
      {
        "short_name": "LDL",
        "long_name": "LDL Cholesterol",
        "category": "Lipid Panel",
        "result": "142",
        "unit": "mg/dL",
        "evaluation": "high",
        "range_min": "0",
        "range_max": "200",
        "range_normal_min": "0",
        "range_normal_max": "100",
        "short_description": "Measures 'bad' cholesterol level.",
        "long_description": "LDL (low-density lipoprotein) cholesterol can build up in artery walls..."
      },
      {
        "short_name": "TRIG",
        "long_name": "Triglycerides",
        "category": "Lipid Panel",
        "result": "156",
        "unit": "mg/dL",
        "evaluation": "borderline_high",
        "range_min": "0",
        "range_max": "500",
        "range_normal_min": "0",
        "range_normal_max": "150",
        "short_description": "Measures fat in the blood.",
        "long_description": "Triglycerides are a type of fat found in the blood that stores excess energy..."
      }
    ],
    "interpretation": [
      {
        "title": "Overall Health Assessment",
        "shortcode": "overall_health_assessment",
        "subsections": [
          {
            "subtitle": "Comprehensive Overview",
            "shortcode": "overall_health_assessment_overview",
            "items": [
              {"item": "The patient demonstrates generally healthy hematological parameters with all blood count values within normal ranges."},
              {"item": "Complete blood count results indicate adequate oxygen-carrying capacity and immune function."},
              {"item": "Lipid panel shows areas requiring attention, particularly LDL cholesterol levels."}
            ]
          }
        ]
      },
      {
        "title": "Metabolic Analysis",
        "shortcode": "metabolic_analysis",
        "subsections": [
          {
            "subtitle": "Blood Sugar Assessment",
            "shortcode": "metabolic_analysis_glucose",
            "items": [
              {"item": "Fasting glucose at 102 mg/dL is slightly elevated, indicating pre-diabetic range."},
              {"item": "Recommend lifestyle modifications including regular exercise and reduced simple carbohydrate intake."},
              {"item": "Follow-up HbA1c testing recommended in 3 months to assess long-term glucose control."}
            ]
          }
        ]
      },
      {
        "title": "Cardiovascular Risk Assessment",
        "shortcode": "cardiovascular_risk",
        "subsections": [
          {
            "subtitle": "Lipid Profile Analysis",
            "shortcode": "cardiovascular_risk_lipids",
            "items": [
              {"item": "LDL cholesterol at 142 mg/dL exceeds optimal levels and warrants intervention."},
              {"item": "HDL cholesterol at 58 mg/dL provides moderate cardiovascular protection."},
              {"item": "Triglycerides slightly elevated; consider dietary modifications to reduce saturated fat intake."},
              {"item": "Total cholesterol to HDL ratio of 3.76 indicates moderate cardiovascular risk."}
            ]
          }
        ]
      },
      {
        "title": "Recommendations",
        "shortcode": "recommendations",
        "subsections": [
          {
            "subtitle": "Lifestyle Modifications",
            "shortcode": "recommendations_lifestyle",
            "items": [
              {"item": "Increase aerobic physical activity to at least 150 minutes per week."},
              {"item": "Adopt a Mediterranean-style diet rich in vegetables, fruits, and healthy fats."},
              {"item": "Limit processed foods, saturated fats, and added sugars."},
              {"item": "Consider consultation with a nutritionist for personalized dietary guidance."}
            ]
          },
          {
            "subtitle": "Follow-up Testing",
            "shortcode": "recommendations_followup",
            "items": [
              {"item": "Repeat lipid panel in 3 months after implementing lifestyle changes."},
              {"item": "HbA1c test recommended to assess average blood glucose levels."},
              {"item": "Annual comprehensive metabolic panel for ongoing monitoring."}
            ]
          }
        ]
      }
    ]
  },
  "api_version": "v11",
  "timestamp": "2025-12-16T14:32:18Z"
}
Response Keywords

The evaluation field uses standardized values. See evaluation values.

POST /api/v12/health-score/analyze Latest

Production endpoint with comprehensive health score calculation and disease risk analysis. Takes the same request as /api/v12/18-09-2026/analyze and adds the fields below to the response. Consumes 1 credit per request.

cURL Example

curl -X POST "https://app.aibloodtestinterpret.com/api/v12/health-score/analyze" \
  -F "username=YOUR_USERNAME" \
  -F "password=YOUR_PASSWORD" \
  -F "language=en" \
  -F "file=@blood_test.pdf"

Additional Response Fields

{
  "health_score": {
    "overall": 78,
    "optimal": 4,
    "normal": 12,
    "warning": 3,
    "critical": 1,
    "total_parameters": 20,
    "score_interpretation": "good",
    "recommendations": [
      "Consider increasing vitamin D intake",
      "Schedule follow-up for cholesterol levels"
    ]
  },
  "disease_risks": [
    {"name": "Cardiovascular Disease", "percentage": "18%", "severity": "low"},
    {"name": "Type 2 Diabetes", "percentage": "12%", "severity": "low"},
    {"name": "Metabolic Syndrome", "percentage": "25%", "severity": "moderate"}
  ]
}
Response Keywords

The score_interpretation field uses standardized values. See health score values.

POST /api/v11/health-score/analyze Stable

Production endpoint with comprehensive health score calculation and disease risk analysis.

Additional Response Fields

{
  "health_score": {
    "overall": 78,
    "optimal": 4,
    "normal": 12,
    "warning": 3,
    "critical": 1,
    "total_parameters": 20,
    "score_interpretation": "good",
    "recommendations": [
      "Consider increasing vitamin D intake",
      "Schedule follow-up for cholesterol levels"
    ]
  },
  "disease_risks": [
    {"name": "Cardiovascular Disease", "percentage": "18%", "severity": "low"},
    {"name": "Type 2 Diabetes", "percentage": "12%", "severity": "low"},
    {"name": "Metabolic Syndrome", "percentage": "25%", "severity": "moderate"}
  ]
}
Response Keywords

The score_interpretation field uses standardized values. See health score values.

Sandbox Endpoints

Sandbox endpoints return realistic test data without consuming API quota. Use them for development and integration testing.

Sandbox Benefits
  • No quota consumption
  • Returns realistic test data
  • Same request format as production
  • Test your integration before going live
  • Available for all API versions
APISandbox Endpoint
Blood Test v12/api/v12/18-09-2026/sandbox
Blood Test v12-health/api/v12/health-score/sandbox
Body Map/api/v1/body-map/sandbox
Biological Blood Age/api/v1/blood-age/sandbox
DNA Test Interpretation/api/v1/dna-interpretation/sandbox
DNA + Blood Health Report/api/v1/dna-blood-report/sandbox
DNA Supplement Advisor/api/v1/dna-supplements/sandbox
Blood Test v11/api/v11/01-06-2025/sandbox
Blood Test v11-health/api/v11/health-score/sandbox
Nutrition Diet AI/api/v1/nutrition/diet-plan/sandbox
Blood Test Comparison/api/v1/bloodtest/comparison/sandbox
Trend Analysis/api/v1/analytics/trends/sandbox
ICR Extract/api/icr/v1/sandbox
ICR Kan (Blood Test)/api/icr/v1/kan/sandbox
Comparison API vs Trend Analysis API

Choose the right API for your use case:

FeatureAI Blood Test ComparisonTrend Analysis
Primary FocusAI narrative comparisonStatistical trend analysis
AI ProcessingFull AI narrativeAI-enhanced + statistics
Output TypeNarrative summariesCharts, statistics, patterns
Best ForWhat changed between testsLong-term parameter tracking
Min Tests22
Max Tests2050

Trend Analysis API

Analyze health parameter trends over time using AI-powered pattern recognition. Identify improvements, deteriorations, and actionable insights from historical blood test data.

Nutrition Diet AI with Supplements

Generate personalized nutrition plans, diet recommendations, and supplement suggestions based on blood test analysis using advanced AI algorithms.

POST /api/v1/nutrition/diet-plan/analyze New

Generates comprehensive nutrition and supplement recommendations based on blood test parameters and patient profile.

Request Parameters

ParameterTypeRequiredDescription
usernamestringYesYour API username
passwordstringYesYour API password
languagestringNoResponse language (default: en). See supported languages.
patientobjectYesPatient demographics and health info
blood_testobjectYesBlood test parameters
health_goalsarrayNoHealth goals. See values.
dietary_restrictionsarrayNoDietary restrictions. See values.

Patient Object Schema

Patient demographics object with gender (see values) and activity_level (see values).

FieldTypeRequiredDefaultDescription
ageintegerYes-Patient age in years (18-120)
genderstringYes-Patient gender. See values
weightnumberNonullWeight in kg (for caloric calculations)
heightnumberNonullHeight in cm (for BMI calculations)
conditionsarrayNo[]Medical conditions (e.g., ["diabetes", "hypertension"])
allergiesarrayNo[]Food/supplement allergies (e.g., ["shellfish", "nuts"])
dietary_preferencesarrayNo[]Dietary preferences. See values
activity_levelstringNo"moderate"Physical activity level. See values
dietary_restrictionsarrayNo[]Dietary restrictions. See values
liked_foodsarrayNo[]Preferred foods to include (e.g., ["salmon", "spinach"])
disliked_foodsarrayNo[]Foods to avoid in recommendations (e.g., ["broccoli"])
meal_frequencyinteger or stringNo5Meals per day: every day of the plan has exactly these meals, e.g. 2 = lunch and dinner. See values
budgetstring or objectNo"moderate"Food budget: a level, or an amount per day such as "10-20 EUR/day". See values
medicationsarrayNo[]Current medications for interaction checks
{
  "age": 45,
  "gender": "male",
  "weight": 82,
  "height": 178,
  "activity_level": "moderate",
  "conditions": ["hypertension"],
  "medications": ["lisinopril"],
  "allergies": ["shellfish"]
}

cURL Example

curl -X POST "https://app.aibloodtestinterpret.com/api/v1/nutrition/diet-plan/analyze" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "YOUR_USERNAME",
    "password": "YOUR_PASSWORD",
    "language": "en",
    "patient": {
      "age": 45,
      "gender": "male",
      "weight": 82,
      "height": 178,
      "activity_level": "moderate",
      "conditions": ["hypertension"],
      "allergies": ["shellfish"]
    },
    "blood_test": {
      "lab_date": "2025-12-01",
      "parameters": [
        {"short_name": "VITD", "result": 18, "unit": "ng/mL"},
        {"short_name": "FER", "result": 25, "unit": "ng/mL"},
        {"short_name": "B12", "result": 280, "unit": "pg/mL"},
        {"short_name": "CHOL", "result": 210, "unit": "mg/dL"},
        {"short_name": "HDL", "result": 42, "unit": "mg/dL"},
        {"short_name": "LDL", "result": 140, "unit": "mg/dL"}
      ]
    },
    "health_goals": ["lower_cholesterol", "increase_energy"],
    "dietary_restrictions": ["low_sodium"]
  }'

Python Example

import requests
from typing import Dict, List, Optional

def get_nutrition_plan(
    username: str,
    password: str,
    patient: Dict,
    blood_test: Dict,
    health_goals: Optional[List[str]] = None,
    dietary_restrictions: Optional[List[str]] = None,
    language: str = "en"
) -> Dict:
    """
    Get personalized nutrition and supplement recommendations.

    Args:
        username: API username
        password: API password
        patient: Patient demographics and health info
        blood_test: Blood test parameters
        health_goals: Optional health goals
        dietary_restrictions: Optional dietary restrictions
        language: Response language

    Returns:
        dict: Nutrition plan with supplements
    """
    url = "https://app.aibloodtestinterpret.com/api/v1/nutrition/diet-plan/analyze"

    payload = {
        "username": username,
        "password": password,
        "language": language,
        "patient": patient,
        "blood_test": blood_test
    }

    if health_goals:
        payload["health_goals"] = health_goals
    if dietary_restrictions:
        payload["dietary_restrictions"] = dietary_restrictions

    response = requests.post(url, json=payload, timeout=120)
    response.raise_for_status()
    return response.json()

# Example usage
if __name__ == "__main__":
    patient = {
        "age": 45,
        "gender": "male",
        "weight": 82,
        "height": 178,
        "activity_level": "moderate",
        "conditions": ["hypertension"],
        "allergies": ["shellfish"]
    }

    blood_test = {
        "lab_date": "2025-12-01",
        "parameters": [
            {"short_name": "VITD", "result": 18, "unit": "ng/mL"},
            {"short_name": "FER", "result": 25, "unit": "ng/mL"},
            {"short_name": "CHOL", "result": 210, "unit": "mg/dL"}
        ]
    }

    result = get_nutrition_plan(
        username="your_username",
        password="your_password",
        patient=patient,
        blood_test=blood_test,
        health_goals=["lower_cholesterol", "increase_energy"]
    )

    # Print supplement recommendations
    for supp in result['data']['nutrition_plan']['supplement_recommendations']:
        print(f"{supp['name']}: {supp['dosage']} - {supp['reason']}")

Example Response

{
  "status": "success",
  "data": {
    "analysis_id": "NUT-1A2B3C4D",
    "generated_at": "2026-11-04T10:30:00Z",
    "patient_summary": {
      "age": 34,
      "gender": "female",
      "weight": 62,
      "height": 165,
      "conditions": [],
      "dietary_preferences": "omnivore"
    },
    "nutrition_plan": {
      "nutrition_summary": {
        "daily_calories": 2046,
        "macro_distribution": {
          "protein_g": 153,
          "fat_g": 57,
          "carbs_g": 230,
          "fiber_g": 29
        },
        "key_focus_areas": [
          "Rebuild iron stores (low ferritin and haemoglobin)",
          "Raise vitamin D into the optimal range",
          "Lower LDL cholesterol with fibre and unsaturated fats"
        ],
        "primary_recommendations": [
          "Eat a heme-iron source (red meat, poultry, fish or shellfish) at least once a day",
          "Pair plant iron with vitamin C and keep tea and coffee one hour away from meals",
          "Have oily fish 2-3 times a week and oats, legumes or psyllium every day"
        ]
      },
      "weekly_meal_plan": {
        "monday": {
          "breakfast": {
            "main_dish": "Spinach and mushroom omelette (2 eggs) on wholegrain toast",
            "sides": ["Orange segments", "Cherry tomatoes"],
            "calories": 510,
            "protein": 30,
            "preparation_time": "15 minutes",
            "cost_estimate": "$3-4"
          },
          "morning_snack": {
            "items": ["Pumpkin seeds (30 g)", "Kiwi"],
            "calories": 150
          },
          "lunch": {
            "main_dish": "Lentil and vegetable soup",
            "sides": ["Wholegrain bread", "Red pepper salad with lemon"],
            "calories": 640,
            "protein": 32,
            "preparation_time": "25 minutes",
            "cost_estimate": "$3-5"
          },
          "afternoon_snack": {
            "items": ["Greek yogurt (150 g)", "Strawberries"],
            "calories": 150
          },
          "dinner": {
            "main_dish": "Grilled lean beef steak (150 g)",
            "sides": ["Roasted sweet potato", "Steamed broccoli with lemon"],
            "calories": 600,
            "protein": 45,
            "preparation_time": "30 minutes",
            "cost_estimate": "$6-8"
          }
        }
        // "tuesday" ... "sunday": the same meals as "monday"
      },
      "food_recommendations": {
        "power_foods": [
          {
            "name": "Lean red meat (beef, lamb)",
            "benefits": "Heme iron is absorbed two to three times better than plant iron and refills ferritin fastest; also supplies B12 and zinc.",
            "serving_size": "120-150 g",
            "frequency": "3 times a week",
            "blood_marker_impact": "Ferritin, Hemoglobin"
          },
          {
            "name": "Mussels and clams",
            "benefits": "Among the richest heme-iron foods, with B12 and omega-3 fats.",
            "serving_size": "100 g (cooked, shelled)",
            "frequency": "Once a week",
            "blood_marker_impact": "Ferritin, Hemoglobin"
          }
          // 12-15 foods in a live plan
        ],
        "foods_to_limit": [
          {
            "name": "Tea and coffee with meals",
            "reason": "Tannins and polyphenols can cut iron absorption from a meal by more than half.",
            "alternative": "Drink them at least one hour before or after eating; water or rooibos with meals",
            "impact_on_health": "Slows the rebuilding of ferritin"
          },
          {
            "name": "Processed meats (sausages, salami, bacon)",
            "reason": "High in saturated fat and salt, which raise LDL and blood pressure.",
            "alternative": "Grilled chicken, turkey or lean beef",
            "impact_on_health": "Keeps LDL cholesterol high"
          }
          // 12-15 foods in a live plan
        ],
        "hydration": {
          "daily_water": "3.1 L",
          "timing": "A glass on waking, then evenly through the day; less in the hour before bed",
          "special_considerations": "Keep tea and coffee at least one hour away from iron-rich meals"
        }
      },
      "supplement_recommendations": [
        {
          "name": "Iron bisglycinate",
          "dosage": "25 mg elemental iron a day",
          "timing": "In the morning on an empty stomach, with vitamin C",
          "reason": "Ferritin 14 ng/mL and haemoglobin 11.8 g/dL show depleted iron stores",
          "duration": "3 months, then retest ferritin",
          "contraindications": "Haemochromatosis; take 2 hours apart from calcium, antacids and thyroid medication",
          "source": "evidence_based",
          "priority": "high",
          "blood_marker_addressed": "Ferritin, Hemoglobin",
          "priority_label": "High",
          "source_label": "Evidence-Based"
        },
        {
          "name": "Vitamin D3",
          "dosage": "2000 IU a day",
          "timing": "With the largest meal of the day",
          "reason": "Vitamin D 18 ng/mL is below the 30 ng/mL threshold",
          "duration": "3 months, then retest",
          "contraindications": "Hypercalcaemia, sarcoidosis",
          "source": "evidence_based",
          "priority": "high",
          "blood_marker_addressed": "Vitamin D (25-OH)",
          "priority_label": "High",
          "source_label": "Evidence-Based"
        }
        // 5-8 supplements in a live plan
      ],
      "lifestyle_integration": {
        "meal_prep_tips": [
          "Cook a large pot of lentils or chickpeas on Sunday for three lunches",
          "Keep cut peppers and kiwi ready to add vitamin C to meals",
          "Portion nuts and seeds into small boxes for snacks"
        ],
        "shopping_list": {
          "proteins": ["Lean beef", "Salmon", "Sardines", "Mussels", "Chicken liver", "Eggs"],
          "vegetables": ["Spinach", "Kale", "Broccoli", "Bell peppers", "Tomatoes"],
          "fruits": ["Kiwi", "Oranges", "Strawberries", "Dried apricots"],
          "grains": ["Oats", "Quinoa", "Brown rice", "Wholegrain bread"],
          "dairy_alternatives": ["Greek yogurt", "Kefir", "Cottage cheese"],
          "pantry_staples": ["Lentils", "Chickpeas", "Pumpkin seeds", "Olive oil", "Psyllium husk"]
        },
        "eating_schedule": {
          "breakfast": "07:30-08:30",
          "morning_snack": "10:30",
          "lunch": "12:30-13:30",
          "afternoon_snack": "16:00",
          "dinner": "19:00-20:00"
        },
        "special_occasions": "When eating out, choose grilled meat or fish with salad, and keep coffee for after the meal."
      },
      "monitoring_plan": {
        "weekly_goals": [
          "Heme iron at least 5 days a week",
          "Oily fish twice a week",
          "No tea or coffee within an hour of meals"
        ],
        "tracking_metrics": [
          "Energy levels",
          "Fatigue and breathlessness",
          "Weight",
          "Digestive tolerance of the iron supplement"
        ],
        "adjustment_signs": [
          "Constipation or stomach upset from the iron supplement",
          "No improvement in energy after 6 weeks"
        ],
        "follow_up_tests": [
          "Ferritin, iron and haemoglobin in 8-12 weeks",
          "Vitamin D (25-OH) in 3 months",
          "Lipid panel in 3 months"
        ],
        "expected_improvements": [
          "Ferritin up 15-30 ng/mL within 3 months",
          "Vitamin D above 30 ng/mL within 3 months",
          "LDL down 10-15% within 3 months"
        ]
      },
      "educational_insights": {
        "blood_test_connections": [
          {
            "parameter": "Ferritin",
            "current_value": "14 ng/mL",
            "dietary_impact": "Iron stores are low; heme iron and vitamin C with meals refill them fastest.",
            "foods_that_help": ["Lean red meat", "Mussels", "Chicken liver", "Lentils with peppers"]
          },
          {
            "parameter": "Hemoglobin",
            "current_value": "11.8 g/dL",
            "dietary_impact": "Slightly below range, consistent with iron deficiency; it rises as ferritin recovers.",
            "foods_that_help": ["Beef", "Spinach with lemon", "Eggs"]
          }
          // one entry per relevant blood test parameter
        ],
        "nutritional_science": [
          "Heme iron from animal foods is absorbed at 15-35%, plant iron at 2-20%.",
          "Vitamin C turns plant iron into a form the gut absorbs more easily.",
          "Beta-glucan from oats forms a gel that carries cholesterol-rich bile out of the body."
        ],
        "success_strategies": [
          "Plan the week's meals and shop once",
          "Add a vitamin C food to every iron-rich meal",
          "Retest on schedule to see the progress"
        ]
      },
      "metadata": {
        "generated_at": "2026-11-04T10:30:00",
        "patient_id": "api_1a2b3c4d",
        "bmr": 1320.25,
        "tdee": 2046.39,
        "nutritional_concerns": ["vitamin_d_deficiency", "anemia", "iron_deficiency", "elevated_ldl"],
        "version": "2.2",
        "used_clinic_supplements": false,
        "clinic_supplements_count": 0,
        "report_language": "english",
        "meal_slots": ["breakfast", "morning_snack", "lunch", "afternoon_snack", "dinner"],
        "meal_frequency": "3 meals and 2 snacks a day (breakfast, morning snack, lunch, afternoon snack, dinner)",
        "budget": "moderate",
        "api_provider": "KantestiAI Engine",
        "model": "KantestiAI Engine"
      }
    },
    "labels": {
      "nutrition_summary": "Nutrition Summary",
      "key_focus_areas": "Key Focus Areas",
      "weekly_meal_plan": "Weekly Meal Plan",
      "monday": "Monday",
      "breakfast": "Breakfast",
      "morning_snack": "Morning Snack",
      "main_dish": "Main Dish",
      "supplement_recommendations": "Supplement Recommendations",
      "priority": "Priority",
      "high": "High",
      "evidence_based": "Evidence-Based"
      // ... one entry for every key of nutrition_plan and every priority / source code
    },
    "language": "en",
    "sandbox_mode": false
  },
  "timestamp": "2026-11-04T10:30:00Z",
  "api_version": "1.0.0",
  "message": "Nutrition analysis completed successfully"
}

Response Fields Reference

The live endpoint (/analyze) and the sandbox return this same structure. JSON keys and codes are always in English; all text is in the requested language (sandbox text is always in English). Do not show keys or codes to users: take titles from labels, and show priority_label and source_label for a supplement's priority and source. Every day of weekly_meal_plan, monday to sunday, has the same meals: those of meal_frequency, five by default.

The plan is written in 39 languages: en, de, fr, it, es, pt, ar, he, el, pl, tr, zh, ru, fa, ja, ko, nl, hi, id, th, vi, sv, no, da, fi, cs, ms, af, uk, ro, hu, sk, sl, hr, bg, sr, lv, lt, et. Any other supported language returns the plan and its labels in English.

data object
FieldTypeDescription
analysis_idstringUnique ID of this analysis (e.g. "NUT-1A2B3C4D")
generated_atstringGeneration time (ISO 8601, UTC)
patient_summaryobjectThe patient data you sent: age, gender, weight, height, conditions, dietary_preferences
nutrition_planobjectThe nutrition plan (sections below)
labelsobjectDisplay text in the requested language for every key of nutrition_plan and every code of priority and source, e.g. labels.key_focus_areas, labels.monday, labels.high
languagestringLanguage code of the response
sandbox_modebooleantrue only in sandbox responses
nutrition_plan object
FieldTypeDescription
nutrition_summaryobjectDaily calorie and macro targets and the plan's focus areas
weekly_meal_planobjectmonday to sunday, each day with the meals of meal_frequency (below); five by default
food_recommendationsobjectpower_foods, foods_to_limit (below) and hydration (daily_water, timing, special_considerations)
supplement_recommendationsarraySupplement recommendations (below). One for each abnormal or borderline marker a supplement can help, none for a marker in range; no fixed number.
lifestyle_integrationobjectmeal_prep_tips, shopping_list (by food group), eating_schedule (time of each meal), special_occasions
monitoring_planobjectweekly_goals, tracking_metrics, adjustment_signs, follow_up_tests, expected_improvements (lists of text)
educational_insightsobjectblood_test_connections (parameter, current_value, dietary_impact, foods_that_help), nutritional_science, success_strategies
metadataobjectTechnical details, not for display: bmr and tdee (kcal/day), nutritional_concerns (codes), version, report_language, meal_slots (the meals every day has, e.g. ["lunch", "dinner"]), meal_frequency and budget (how the request's values were understood)
nutrition_plan.nutrition_summary object
FieldTypeDescription
daily_caloriesintegerDaily calorie target (kcal)
macro_distributionobjectprotein_g, fat_g, carbs_g, fiber_g: grams per day
key_focus_areasarrayMain focus areas of the plan
primary_recommendationsarrayThe most important recommendations
weekly_meal_plan.<day> object
FieldTypeDescription
breakfast, lunch, dinnerobjectMain meals (fields below)
morning_snack, afternoon_snackobjectSnacks: items (array of text) and calories (integer, kcal)

A day has exactly the meals of meal_frequency, and metadata.meal_slots lists them: with 2, only lunch and dinner. Show the meals a day has, not a fixed list of five.

breakfast / lunch / dinner object
FieldTypeDescription
main_dishstringName of the main dish
sidesarraySide dishes
caloriesintegerCalories (kcal)
proteinintegerProtein (g)
preparation_timestringPreparation time (e.g. "15 minutes")
cost_estimatestringEstimated cost (e.g. "$3-5")
food_recommendations.power_foods array item
FieldTypeDescription
namestringFood name
benefitsstringWhy it helps, tied to the blood test results
serving_sizestringServing size
frequencystringHow often to eat it
blood_marker_impactstringBlood marker(s) it helps
food_recommendations.foods_to_limit array item
FieldTypeDescription
namestringFood name
reasonstringWhy to limit it
alternativestringHealthier alternative
impact_on_healthstringEffect on the patient's health
supplement_recommendations array item
FieldTypeDescription
namestringSupplement name
dosagestringDosage (e.g. "2000 IU a day")
timingstringWhen to take it
reasonstringWhy it is recommended, based on the blood test results
durationstringHow long to take it
contraindicationsstringContraindications and interactions
sourcestringCode: clinic_library (from your supplement library) or evidence_based
source_labelstringsource as text in the requested language, ready to display
prioritystringCode: high, medium or low
priority_labelstringpriority as text in the requested language, ready to display
blood_marker_addressedstringBlood marker(s) it addresses

Complete cURL Example with Response

curl -X POST "https://app.aibloodtestinterpret.com/api/v1/nutrition/diet-plan/analyze" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "demo_user",
    "password": "demo_pass",
    "language": "en",
    "patient": {
      "age": 42,
      "gender": "female",
      "weight": 68,
      "height": 165,
      "activity_level": "moderate",
      "conditions": ["iron_deficiency_anemia"],
      "allergies": ["gluten"],
      "dietary_preferences": ["mediterranean"],
      "dietary_restrictions": ["gluten_free"],
      "liked_foods": ["salmon", "spinach", "quinoa"],
      "disliked_foods": ["liver"],
      "meal_frequency": 5,
      "budget": "moderate",
      "medications": ["ferrous_sulfate"]
    },
    "blood_test": {
      "lab_date": "2025-12-20",
      "parameters": [
        {"short_name": "FER", "result": 12, "unit": "ng/mL"},
        {"short_name": "HGB", "result": 10.8, "unit": "g/dL"},
        {"short_name": "VITD", "result": 22, "unit": "ng/mL"},
        {"short_name": "B12", "result": 320, "unit": "pg/mL"},
        {"short_name": "FOLATE", "result": 8.5, "unit": "ng/mL"}
      ]
    },
    "health_goals": ["increase_energy", "improve_iron_levels"]
  }'
Response:
{
  "status": "success",
  "data": {
    "analysis_id": "NUT-1A2B3C4D",
    "generated_at": "2026-11-04T10:30:00Z",
    "patient_summary": {
      "age": 34,
      "gender": "female",
      "weight": 62,
      "height": 165,
      "conditions": [],
      "dietary_preferences": "omnivore"
    },
    "nutrition_plan": {
      "nutrition_summary": {
        "daily_calories": 2046,
        "macro_distribution": {
          "protein_g": 153,
          "fat_g": 57,
          "carbs_g": 230,
          "fiber_g": 29
        },
        "key_focus_areas": [
          "Rebuild iron stores (low ferritin and haemoglobin)",
          "Raise vitamin D into the optimal range",
          "Lower LDL cholesterol with fibre and unsaturated fats"
        ],
        "primary_recommendations": [
          "Eat a heme-iron source (red meat, poultry, fish or shellfish) at least once a day",
          "Pair plant iron with vitamin C and keep tea and coffee one hour away from meals",
          "Have oily fish 2-3 times a week and oats, legumes or psyllium every day"
        ]
      },
      "weekly_meal_plan": {
        "monday": {
          "breakfast": {
            "main_dish": "Spinach and mushroom omelette (2 eggs) on wholegrain toast",
            "sides": ["Orange segments", "Cherry tomatoes"],
            "calories": 510,
            "protein": 30,
            "preparation_time": "15 minutes",
            "cost_estimate": "$3-4"
          },
          "morning_snack": {
            "items": ["Pumpkin seeds (30 g)", "Kiwi"],
            "calories": 150
          },
          "lunch": {
            "main_dish": "Lentil and vegetable soup",
            "sides": ["Wholegrain bread", "Red pepper salad with lemon"],
            "calories": 640,
            "protein": 32,
            "preparation_time": "25 minutes",
            "cost_estimate": "$3-5"
          },
          "afternoon_snack": {
            "items": ["Greek yogurt (150 g)", "Strawberries"],
            "calories": 150
          },
          "dinner": {
            "main_dish": "Grilled lean beef steak (150 g)",
            "sides": ["Roasted sweet potato", "Steamed broccoli with lemon"],
            "calories": 600,
            "protein": 45,
            "preparation_time": "30 minutes",
            "cost_estimate": "$6-8"
          }
        }
        // "tuesday" ... "sunday": the same meals as "monday"
      },
      "food_recommendations": {
        "power_foods": [
          {
            "name": "Lean red meat (beef, lamb)",
            "benefits": "Heme iron is absorbed two to three times better than plant iron and refills ferritin fastest; also supplies B12 and zinc.",
            "serving_size": "120-150 g",
            "frequency": "3 times a week",
            "blood_marker_impact": "Ferritin, Hemoglobin"
          },
          {
            "name": "Mussels and clams",
            "benefits": "Among the richest heme-iron foods, with B12 and omega-3 fats.",
            "serving_size": "100 g (cooked, shelled)",
            "frequency": "Once a week",
            "blood_marker_impact": "Ferritin, Hemoglobin"
          }
          // 12-15 foods in a live plan
        ],
        "foods_to_limit": [
          {
            "name": "Tea and coffee with meals",
            "reason": "Tannins and polyphenols can cut iron absorption from a meal by more than half.",
            "alternative": "Drink them at least one hour before or after eating; water or rooibos with meals",
            "impact_on_health": "Slows the rebuilding of ferritin"
          },
          {
            "name": "Processed meats (sausages, salami, bacon)",
            "reason": "High in saturated fat and salt, which raise LDL and blood pressure.",
            "alternative": "Grilled chicken, turkey or lean beef",
            "impact_on_health": "Keeps LDL cholesterol high"
          }
          // 12-15 foods in a live plan
        ],
        "hydration": {
          "daily_water": "3.1 L",
          "timing": "A glass on waking, then evenly through the day; less in the hour before bed",
          "special_considerations": "Keep tea and coffee at least one hour away from iron-rich meals"
        }
      },
      "supplement_recommendations": [
        {
          "name": "Iron bisglycinate",
          "dosage": "25 mg elemental iron a day",
          "timing": "In the morning on an empty stomach, with vitamin C",
          "reason": "Ferritin 14 ng/mL and haemoglobin 11.8 g/dL show depleted iron stores",
          "duration": "3 months, then retest ferritin",
          "contraindications": "Haemochromatosis; take 2 hours apart from calcium, antacids and thyroid medication",
          "source": "evidence_based",
          "priority": "high",
          "blood_marker_addressed": "Ferritin, Hemoglobin",
          "priority_label": "High",
          "source_label": "Evidence-Based"
        },
        {
          "name": "Vitamin D3",
          "dosage": "2000 IU a day",
          "timing": "With the largest meal of the day",
          "reason": "Vitamin D 18 ng/mL is below the 30 ng/mL threshold",
          "duration": "3 months, then retest",
          "contraindications": "Hypercalcaemia, sarcoidosis",
          "source": "evidence_based",
          "priority": "high",
          "blood_marker_addressed": "Vitamin D (25-OH)",
          "priority_label": "High",
          "source_label": "Evidence-Based"
        }
        // 5-8 supplements in a live plan
      ],
      "lifestyle_integration": {
        "meal_prep_tips": [
          "Cook a large pot of lentils or chickpeas on Sunday for three lunches",
          "Keep cut peppers and kiwi ready to add vitamin C to meals",
          "Portion nuts and seeds into small boxes for snacks"
        ],
        "shopping_list": {
          "proteins": ["Lean beef", "Salmon", "Sardines", "Mussels", "Chicken liver", "Eggs"],
          "vegetables": ["Spinach", "Kale", "Broccoli", "Bell peppers", "Tomatoes"],
          "fruits": ["Kiwi", "Oranges", "Strawberries", "Dried apricots"],
          "grains": ["Oats", "Quinoa", "Brown rice", "Wholegrain bread"],
          "dairy_alternatives": ["Greek yogurt", "Kefir", "Cottage cheese"],
          "pantry_staples": ["Lentils", "Chickpeas", "Pumpkin seeds", "Olive oil", "Psyllium husk"]
        },
        "eating_schedule": {
          "breakfast": "07:30-08:30",
          "morning_snack": "10:30",
          "lunch": "12:30-13:30",
          "afternoon_snack": "16:00",
          "dinner": "19:00-20:00"
        },
        "special_occasions": "When eating out, choose grilled meat or fish with salad, and keep coffee for after the meal."
      },
      "monitoring_plan": {
        "weekly_goals": [
          "Heme iron at least 5 days a week",
          "Oily fish twice a week",
          "No tea or coffee within an hour of meals"
        ],
        "tracking_metrics": [
          "Energy levels",
          "Fatigue and breathlessness",
          "Weight",
          "Digestive tolerance of the iron supplement"
        ],
        "adjustment_signs": [
          "Constipation or stomach upset from the iron supplement",
          "No improvement in energy after 6 weeks"
        ],
        "follow_up_tests": [
          "Ferritin, iron and haemoglobin in 8-12 weeks",
          "Vitamin D (25-OH) in 3 months",
          "Lipid panel in 3 months"
        ],
        "expected_improvements": [
          "Ferritin up 15-30 ng/mL within 3 months",
          "Vitamin D above 30 ng/mL within 3 months",
          "LDL down 10-15% within 3 months"
        ]
      },
      "educational_insights": {
        "blood_test_connections": [
          {
            "parameter": "Ferritin",
            "current_value": "14 ng/mL",
            "dietary_impact": "Iron stores are low; heme iron and vitamin C with meals refill them fastest.",
            "foods_that_help": ["Lean red meat", "Mussels", "Chicken liver", "Lentils with peppers"]
          },
          {
            "parameter": "Hemoglobin",
            "current_value": "11.8 g/dL",
            "dietary_impact": "Slightly below range, consistent with iron deficiency; it rises as ferritin recovers.",
            "foods_that_help": ["Beef", "Spinach with lemon", "Eggs"]
          }
          // one entry per relevant blood test parameter
        ],
        "nutritional_science": [
          "Heme iron from animal foods is absorbed at 15-35%, plant iron at 2-20%.",
          "Vitamin C turns plant iron into a form the gut absorbs more easily.",
          "Beta-glucan from oats forms a gel that carries cholesterol-rich bile out of the body."
        ],
        "success_strategies": [
          "Plan the week's meals and shop once",
          "Add a vitamin C food to every iron-rich meal",
          "Retest on schedule to see the progress"
        ]
      },
      "metadata": {
        "generated_at": "2026-11-04T10:30:00",
        "patient_id": "api_1a2b3c4d",
        "bmr": 1320.25,
        "tdee": 2046.39,
        "nutritional_concerns": ["vitamin_d_deficiency", "anemia", "iron_deficiency", "elevated_ldl"],
        "version": "2.2",
        "used_clinic_supplements": false,
        "clinic_supplements_count": 0,
        "report_language": "english",
        "meal_slots": ["breakfast", "morning_snack", "lunch", "afternoon_snack", "dinner"],
        "meal_frequency": "3 meals and 2 snacks a day (breakfast, morning snack, lunch, afternoon snack, dinner)",
        "budget": "moderate",
        "api_provider": "KantestiAI Engine",
        "model": "KantestiAI Engine"
      }
    },
    "labels": {
      "nutrition_summary": "Nutrition Summary",
      "key_focus_areas": "Key Focus Areas",
      "weekly_meal_plan": "Weekly Meal Plan",
      "monday": "Monday",
      "breakfast": "Breakfast",
      "morning_snack": "Morning Snack",
      "main_dish": "Main Dish",
      "supplement_recommendations": "Supplement Recommendations",
      "priority": "Priority",
      "high": "High",
      "evidence_based": "Evidence-Based"
      // ... one entry for every key of nutrition_plan and every priority / source code
    },
    "language": "en",
    "sandbox_mode": false
  },
  "timestamp": "2026-11-04T10:30:00Z",
  "api_version": "1.0.0",
  "message": "Nutrition analysis completed successfully"
}

Blood Test Comparison API

Compare multiple blood tests to identify changes, improvements, and areas requiring attention with AI-powered analysis. Get full AI narrative summaries explaining what changed between tests.

POST /api/v1/bloodtest/comparison/analyze

Analyzes 2-20 blood tests and provides detailed comparison with AI-generated narrative insights.

Requirements
  • Minimum 2 blood tests required
  • Maximum 20 blood tests per request
  • Each test must include lab_date or results_date
  • At least one common parameter across tests

Request Parameters

ParameterTypeRequiredDefaultDescription
usernamestringYes-Your API username
passwordstringYes-Your API password
languagestringNoenResponse language. See supported languages
blood_testsarrayYes-Array of blood test objects (2-20 tests)

blood_tests Array Structure

FieldTypeRequiredDescription
lab_datestringYes*Test date in YYYY-MM-DD format
results_datestringYes*Alternative to lab_date (YYYY-MM-DD)
parametersarrayYesArray of blood test parameters
metadataobjectNoAdditional metadata (lab_name, notes, etc.)

*Either lab_date or results_date is required for each blood test.

cURL Example

curl -X POST "https://app.aibloodtestinterpret.com/api/v1/bloodtest/comparison/analyze" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "YOUR_USERNAME",
    "password": "YOUR_PASSWORD",
    "language": "en",
    "blood_tests": [
      {
        "lab_date": "2025-06-15",
        "lab_name": "City Medical Lab",
        "parameters": [
          {"short_name": "HGB", "result": 12.8, "unit": "g/dL"},
          {"short_name": "WBC", "result": 8.2, "unit": "10^9/L"},
          {"short_name": "PLT", "result": 245, "unit": "10^9/L"}
        ]
      },
      {
        "lab_date": "2025-12-15",
        "lab_name": "City Medical Lab",
        "parameters": [
          {"short_name": "HGB", "result": 14.2, "unit": "g/dL"},
          {"short_name": "WBC", "result": 7.1, "unit": "10^9/L"},
          {"short_name": "PLT", "result": 238, "unit": "10^9/L"}
        ]
      }
    ]
  }'

Python Example

import requests
from typing import Dict, List

def compare_blood_tests(
    username: str,
    password: str,
    blood_tests: List[Dict],
    language: str = "en"
) -> Dict:
    """
    Compare multiple blood tests with AI-powered narrative analysis.

    Args:
        username: API username
        password: API password
        blood_tests: List of blood test objects (2-20 tests)
        language: Response language

    Returns:
        dict: Comparison results with AI narrative insights
    """
    url = "https://app.aibloodtestinterpret.com/api/v1/bloodtest/comparison/analyze"

    if len(blood_tests) < 2:
        raise ValueError("Minimum 2 blood tests required")
    if len(blood_tests) > 20:
        raise ValueError("Maximum 20 blood tests allowed")

    payload = {
        "username": username,
        "password": password,
        "language": language,
        "blood_tests": blood_tests
    }

    response = requests.post(url, json=payload, timeout=120)
    response.raise_for_status()
    return response.json()

# Example usage
if __name__ == "__main__":
    tests = [
        {
            "lab_date": "2024-06-15",
            "parameters": [
                {"short_name": "HGB", "result": 12.2, "unit": "g/dL"},
                {"short_name": "CHOL", "result": 235, "unit": "mg/dL"},
                {"short_name": "LDL", "result": 155, "unit": "mg/dL"}
            ]
        },
        {
            "lab_date": "2024-12-15",
            "parameters": [
                {"short_name": "HGB", "result": 14.5, "unit": "g/dL"},
                {"short_name": "CHOL", "result": 185, "unit": "mg/dL"},
                {"short_name": "LDL", "result": 98, "unit": "mg/dL"}
            ]
        }
    ]

    result = compare_blood_tests("your_username", "your_password", tests)

    print(f"Overall trend: {result['data']['comparison_summary']['overall_trend']}")
    for param in result['data']['parameter_analysis']:
        print(f"{param['parameter_name']}: {param['trend_assessment']}")

Response Fields Reference

FieldTypeDescription
comparison_idstringUnique identifier for this comparison (format: CMP-XXXXXXXX)
comparison_summaryobjectOverall summary: key_findings, overall_trend, report dates, time_interval
parameter_analysisarrayDetailed analysis per parameter with change type and clinical significance
health_assessmentobjectAreas of concern, improvement, positive developments, risk factors
recommendationsobjectFollow-up tests, immediate actions, lifestyle modifications, specialist referrals
detailed_interpretationobjectAI narrative sections with executive summary and clinical recommendations

parameter_analysis Object Structure

FieldTypeDescription
parameter_namestringParameter name
report1_valuestringValue from first report with unit
report2_valuestringValue from second report with unit
change_typestringincreased, decreased, or stable
change_magnitudestringsignificant, moderate, or minor
clinical_significancestringAI explanation of what the change means
trend_assessmentstringpositive, negative, or neutral

Example Response

{
  "api_version": "1.0.0",
  "status": "success",
  "message": "Blood test comparison completed successfully",
  "timestamp": "2025-12-22T01:12:43.057537Z",
  "data": {
    "comparison_id": "CMP-F4ACEE52",
    "tests_compared": 2,
    "date_range": {
      "earliest": "2024-06-15",
      "latest": "2024-12-15",
      "span_days": 183
    },
    "comparison_summary": {
      "overall_trend": "improved",
      "report1_date": "2024-06-15",
      "report2_date": "2024-12-15",
      "time_interval": "183 days between reports",
      "key_findings": [
        "Hemoglobin and RBC levels normalized indicating resolution of anemia",
        "Glucose and HbA1c improved to normal range suggesting better glycemic control",
        "Lipid profile improved with total cholesterol, LDL, HDL, and triglycerides normalized"
      ]
    },
    "parameter_analysis": [
      {
        "parameter_name": "Hemoglobin",
        "report1_value": "12.2 g/dL",
        "report2_value": "14.5 g/dL",
        "change_type": "increased",
        "change_magnitude": "significant",
        "clinical_significance": "Improvement from anemia to normal hemoglobin levels",
        "trend_assessment": "positive"
      },
      {
        "parameter_name": "LDL Cholesterol",
        "report1_value": "155 mg/dL",
        "report2_value": "98 mg/dL",
        "change_type": "decreased",
        "change_magnitude": "significant",
        "clinical_significance": "LDL near optimal range, reducing atherosclerosis risk",
        "trend_assessment": "positive"
      },
      {
        "parameter_name": "HDL Cholesterol",
        "report1_value": "38 mg/dL",
        "report2_value": "55 mg/dL",
        "change_type": "increased",
        "change_magnitude": "significant",
        "clinical_significance": "Improved HDL protective against heart disease",
        "trend_assessment": "positive"
      }
    ],
    "health_assessment": {
      "overall_health_trend": "improved",
      "areas_of_improvement": [
        "Anemia correction",
        "Glycemic control",
        "Lipid profile normalization",
        "Vitamin D and iron status"
      ],
      "areas_of_concern": [],
      "positive_developments": [
        "Resolution of anemia",
        "Normal glucose and HbA1c",
        "Improved cardiovascular risk profile"
      ],
      "risk_factors": [
        "Previous iron deficiency anemia",
        "Prior dyslipidemia",
        "History of impaired glucose metabolism"
      ]
    },
    "recommendations": {
      "immediate_actions": [
        "Continue current supplementation for iron and vitamin D",
        "Maintain glycemic and lipid control with diet and exercise"
      ],
      "follow_up_tests": [
        "Repeat CBC and iron studies in 3 months",
        "Monitor fasting glucose and HbA1c quarterly",
        "Lipid panel recheck in 6 months"
      ],
      "lifestyle_modifications": [
        "Adopt heart-healthy diet low in saturated fats",
        "Increase physical activity to maintain metabolic health"
      ],
      "specialist_referrals": [
        "Consult hematologist if anemia recurs",
        "Endocrinologist referral if glucose control worsens"
      ],
      "monitoring_frequency": "3 months"
    },
    "detailed_interpretation": {
      "sections": [
        {
          "title": "Executive Summary",
          "content": "The patient shows marked improvement in anemia, glucose metabolism, lipid profile, and vitamin status over 6 months."
        },
        {
          "title": "Clinical Recommendations",
          "content": "Continue supplementation and lifestyle measures. Monitor blood counts, iron, glucose, and lipids regularly."
        }
      ]
    },
    "summary": {
      "improved_parameters": 13,
      "stable_parameters": 0,
      "worsened_parameters": 0,
      "overall_trend": "improved"
    },
    "sandbox_mode": false
  }
}
Response Keywords

Response fields use standardized values: overall_trend and trend_assessment (see trend assessment), change_type (increased, decreased, stable).

Keywords Reference

Complete reference for all input keyword values used across Kantesti API endpoints. Use these exact values when making API requests.

analysis_type Trend Analysis API

Specifies the type of trend analysis to perform.

ValueDefaultDescription
comprehensive✓Full analysis with statistics, charts, and AI interpretation
statisticalStatistical analysis only
summaryHigh-level summary only

health_goals Nutrition API

Health objectives for personalized nutrition recommendations. Multiple values can be provided as an array.

ValueDescription
maintainMaintain current health (default)
improve_energyFocus on energy levels
weight_managementHealthy weight management
heart_healthCardiovascular health
immune_supportImmune system support
digestive_healthDigestive wellness
bone_healthBone health
mental_clarityCognitive function

dietary_restrictions Nutrition API

Dietary restrictions and allergies. Multiple values can be provided as an array. Free text is also accepted for custom restrictions.

ValueDescription
low_sodiumReduced sodium intake
low_sugarReduced sugar intake
low_fatReduced fat intake
gluten_freeNo gluten
dairy_freeNo dairy
nut_freeNo nuts
soy_freeNo soy
egg_freeNo eggs
halalHalal-compliant
kosherKosher-compliant
Note

Free text is also accepted for custom dietary restrictions not listed above.

dietary_preferences Nutrition API

Dietary lifestyle preferences for meal planning.

ValueDescription
omnivoreNo restrictions (default)
vegetarianNo meat
veganNo animal products
pescatarianVegetarian + fish
ketoKetogenic diet
paleoPaleolithic diet
mediterraneanMediterranean diet

The plan follows dietary_preferences, dietary_restrictions and allergies in every section: meals, recommended foods and supplements (vegetarian: no meat, fish, liver or fish oil; omega-3 from algae oil, flaxseed or walnuts).

activity_level Nutrition API

Physical activity level for caloric and nutritional calculations.

ValueDescription
sedentaryLittle or no exercise
lightLight exercise 1-3 days/week
moderateModerate exercise 3-5 days/week (default)
activeHard exercise 6-7 days/week
very_activeVery hard exercise or physical job

meal_frequency Nutrition API

The meals every day of the plan has, and nothing else. The response lists them in nutrition_plan.metadata.meal_slots. The sandbox answers with the same meals, so you can try every option without consuming API quota.

ValueMeals of each day
1dinner
2lunch, dinner
3breakfast, lunch, dinner
4breakfast, lunch, afternoon_snack, dinner
5 or morebreakfast, morning_snack, lunch, afternoon_snack, dinner (default)
"2 meals + 1 snack", "3 meals and 2 snacks"The meals and snacks written (at most 3 meals and 2 snacks)
"intermittent", "16:8"lunch, afternoon_snack, dinner, all between 12:00 and 20:00
["breakfast", "dinner"]Exactly the meals listed

budget Nutrition API

Food budget of the meal plan: a level, or an amount. With an amount, every cost_estimate is in its currency and each day's meals stay within it.

ValueDescription
lowBudget-conscious options
moderateBalanced options (default)
highPremium options
"10-20 EUR/day", "€15 a day", "100 EUR per week"An amount per day, week or month, with its currency (EUR, USD, GBP, TRY, ... or € $ £ ₺)
{"min": 10, "max": 20, "currency": "EUR"}The same amount as an object (optional "period": "day", "week" or "month")

gender All APIs

Patient gender for personalized reference ranges and recommendations.

ValueDescription
maleMale patient
femaleFemale patient
otherOther or unspecified

Output Keywords

The following keywords appear in API responses. Understanding these values helps you interpret and display results correctly.

evaluation Blood Test & Comparison APIs

Parameter evaluation status indicating how the result compares to reference ranges.

ValueDescription
normalWithin normal reference range
lowBelow normal range
highAbove normal range
critical_lowCritically low (immediate attention required)
critical_highCritically high (immediate attention required)
borderline_lowSlightly below normal range
borderline_highSlightly above normal range

What the Blood Test Analysis API returns per type:

ValueRow typeShow as
optimal, normalrangeNormal
slightly_low, slightly_highrangeBorderline (outside the normal range, inside the outer range)
low, highrangeAbnormal
goodbinaryNormal (e.g. "Negative" where negative is expected)
badbinaryAbnormal (e.g. "Positive" where negative is expected)
UnknowneitherNot rated (no result, or no reference to rate it against) — neither normal nor abnormal

Reference ranges Blood Test & Comparison APIs

Every range marker comes with three nested ranges, from the tightest to the widest. Show each with its label and unit (e.g. Optimal: 0.0 – 0.51 %) and mark the one that holds the result, using evaluation. Hide a range whose fields are null; binary rows have no ranges.

Label to showFieldsThe result is here when evaluation is
Optimalrange_optimal_min – range_optimal_maxoptimal
Normal (reference range)range_normal_min – range_normal_maxnormal
Borderline limitrange_min – range_maxslightly_low, slightly_high (between the normal range and this limit: borderline)
Outside the borderline limit—low, high (abnormal)

Example: a result of 0.2 % with Optimal 0.0 – 0.51 %, Normal 0.0 – 0.6 % and Borderline limit 0.0 – 0.9 % is in the optimal range (evaluation: optimal).

trend_assessment Comparison & Trend APIs

Overall assessment of parameter trends between tests.

ValueDescription
positiveImproved (moving toward normal range)
negativeWorsened (moving away from normal range)
stableRelatively unchanged between tests
improvingOverall improvement trend
worseningOverall deterioration trend

trend_direction Trend Analysis API

Direction of parameter value changes over time.

ValueDescription
upwardValues increasing over time
downwardValues decreasing over time
stableMinimal change over time

trend_strength Trend Analysis API

Magnitude of the observed trend.

ValueDescription
strong>15% change between periods
moderate5-15% change between periods
mild<5% change between periods

health_score / score_interpretation Health Score API

Overall health score interpretation based on analyzed parameters.

ValueDescription
excellentAll markers within optimal range
goodMost markers within normal range
fairSome markers need attention
poorMultiple markers need attention

Utility Endpoints

GET /api/info

Returns API platform information, available versions, and supported features. No authentication required.

Example Response

{
  "platform": "Kantesti Blood Test Analysis API",
  "versions": ["v6", "v8", "v9", "v10", "v11"],
  "latest_version": "v11",
  "supported_languages": 100,
  "documentation": "https://www.kantesti.net/docs/",
  "status": "operational"
}
GET /api/health

Health check endpoint for monitoring. Returns service status. No authentication required.

Example Response

{
  "status": "healthy",
  "timestamp": "2025-12-22T10:30:00Z",
  "uptime": "99.99%"
}
POST /api/quota/check

Check your remaining API quota. Requires authentication.

cURL Example

curl -X POST "https://app.aibloodtestinterpret.com/api/quota/check" \
  -H "Content-Type: application/json" \
  -d '{"username": "YOUR_USERNAME", "password": "YOUR_PASSWORD"}'

Example Response

{
  "status": "success",
  "quota": {
    "remaining": 847,
    "total": 1000,
    "reset_date": "2026-01-01",
    "plan": "professional"
  }
}

Family Health Risk Assessment API

Released: March 23, 2026

The Kantesti Family Health Risk Assessment API is an AI-powered hereditary health risk analysis platform. It generates comprehensive family health reports by analyzing family medical history, patient health profiles, and blood test data to identify hereditary risk factors and provide personalized preventive care recommendations.

100+
Languages
9
Condition Categories
14
Family Relations

AI-Powered Hereditary Risk Analysis

The Family Health API uses advanced AI models to cross-reference family medical history with patient blood test data, identifying hereditary risk patterns across cardiovascular, metabolic, cancer, neurological, respiratory, autoimmune, genetic, mental health, and kidney/liver condition categories. Reports include risk scoring, preventive care timelines, genetic screening recommendations, and lifestyle guidance — all localized in 100+ languages.

Key Features
  • Hereditary Risk Analysis — High, moderate, and low risk classification with detailed scoring
  • Family Tree Analysis — Paternal and maternal lineage risk mapping with combined risk factors
  • Blood Test Correlation — Cross-references family history with blood test parameters
  • Genetic Screening Recommendations — Personalized genetic testing suggestions
  • Preventive Care Timeline — Age-appropriate screening schedules based on family risk
  • Medication Analysis — Drug interaction and hereditary sensitivity assessment
  • 100+ Language Support — Full report localization in over 100 languages
  • Sandbox Mode — Test integration without consuming credits
  • 9 Condition Categories — Cardiovascular, Metabolic, Cancer, Neurological, Respiratory, Autoimmune, Genetic, Mental Health, Kidney/Liver
  • 14 Family Relations — Father, mother, siblings, grandparents, uncles, aunts, children

Endpoints Summary

EndpointMethodDescriptionAuth
/api/v1/family-health/analyze POST Generate comprehensive family health risk assessment report Required (1 credit)
/api/v1/family-health/validate POST Validate request data before analysis (no quota consumed) Required (Free)
/api/v1/family-health/supported-languages GET List all 100+ supported languages Not required
/api/v1/family-health/condition-categories GET List all medical condition categories Not required
/api/v1/family-health/family-relations GET List all supported family relation types Not required
/api/v1/family-health/sandbox/analyze POST Sandbox testing with mock data (no quota consumed) Required (Free)
POST /api/v1/family-health/analyze Released 23 Mar 2026

Generate a comprehensive AI-powered family health risk assessment report. Analyzes family medical history, patient health profiles, and blood test data to identify hereditary risk factors with personalized preventive care recommendations.

Request Parameters (JSON Body)

ParameterTypeRequiredDescription
usernamestringYesYour API username
passwordstringYesYour API password
patient_dataobjectYesPatient information (see below)
family_membersarrayYes*Array of family member objects (max 100). *Required if health_profile is absent
health_profileobjectYes*Patient health profile. *Required if family_members is absent
blood_test_dataarrayNoArray of blood test data objects for correlation analysis
languagestringNoResponse language code (default: en). 100+ languages supported

patient_data Object

FieldTypeRequiredDescription
namestringNoPatient full name
ageintegerYesPatient age in years
genderstringYesmale, female, or other
dobstringNoDate of birth (YYYY-MM-DD)

family_members Array Item

FieldTypeRequiredDescription
relationstringYesRelation type: father, mother, brother, sister, paternal_grandfather, paternal_grandmother, maternal_grandfather, maternal_grandmother, paternal_uncle, paternal_aunt, maternal_uncle, maternal_aunt, son, daughter
ageintegerNoFamily member age
conditionsarrayNoArray of known medical conditions (strings)
age_at_diagnosisintegerNoAge when condition was diagnosed
deceasedbooleanNoWhether the family member is deceased
age_at_deathintegerNoAge at death (if deceased)
cause_of_deathstringNoCause of death (if deceased)

cURL Example

curl -X POST "https://app.aibloodtestinterpret.com/api/v1/family-health/analyze" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "YOUR_USERNAME",
    "password": "YOUR_PASSWORD",
    "patient_data": {
      "name": "Jane Doe",
      "age": 42,
      "gender": "female",
      "dob": "1984-03-15"
    },
    "family_members": [
      {
        "relation": "father",
        "age": 70,
        "conditions": ["hypertension", "type2_diabetes"],
        "deceased": false
      },
      {
        "relation": "mother",
        "age": 67,
        "conditions": ["breast_cancer", "osteoporosis"],
        "deceased": false
      },
      {
        "relation": "paternal_grandfather",
        "conditions": ["coronary_artery_disease"],
        "deceased": true,
        "age_at_death": 72,
        "cause_of_death": "heart_attack"
      }
    ],
    "health_profile": {
      "current_medications": ["metformin"],
      "allergies": ["penicillin"],
      "chronic_conditions": ["prediabetes"],
      "lifestyle_factors": ["sedentary", "non_smoker"]
    },
    "blood_test_data": [
      {"parameter": "glucose", "value": 110, "unit": "mg/dL"},
      {"parameter": "HbA1c", "value": 5.9, "unit": "%"},
      {"parameter": "total_cholesterol", "value": 220, "unit": "mg/dL"}
    ],
    "language": "en"
  }'

Python Example

import requests

def family_health_analyze(username: str, password: str, patient_data: dict,
                          family_members: list = None, health_profile: dict = None,
                          blood_test_data: list = None, language: str = "en"):
    """
    Generate a family health risk assessment report using Kantesti API.
    AI-powered hereditary risk analysis with 100+ language support.

    Args:
        username: API username
        password: API password
        patient_data: Patient info dict with 'age' and 'gender' (required)
        family_members: List of family member dicts with medical history
        health_profile: Patient health profile dict
        blood_test_data: Optional blood test data for correlation
        language: Report language code (default: en)

    Returns:
        dict: Full family health risk assessment report
    """
    url = "https://app.aibloodtestinterpret.com/api/v1/family-health/analyze"

    payload = {
        "username": username,
        "password": password,
        "patient_data": patient_data,
        "language": language
    }

    if family_members:
        payload["family_members"] = family_members
    if health_profile:
        payload["health_profile"] = health_profile
    if blood_test_data:
        payload["blood_test_data"] = blood_test_data

    response = requests.post(url, json=payload, timeout=120)
    response.raise_for_status()
    return response.json()

# Example usage
if __name__ == "__main__":
    result = family_health_analyze(
        username="your_username",
        password="your_password",
        patient_data={"name": "Jane Doe", "age": 42, "gender": "female"},
        family_members=[
            {"relation": "father", "age": 70, "conditions": ["hypertension", "type2_diabetes"]},
            {"relation": "mother", "age": 67, "conditions": ["breast_cancer"]},
        ],
        health_profile={"chronic_conditions": ["prediabetes"]},
        blood_test_data=[{"parameter": "glucose", "value": 110, "unit": "mg/dL"}],
        language="en"
    )
    print(f"Status: {result['status']}")
    report = result["data"]["report_data"]
    print(f"Risk Level: {report['risk_assessment']['overall_risk_level']}")
    for category, risk in report["risk_assessment"].items():
        if isinstance(risk, dict):
            print(f"  {category}: {risk.get('level', 'N/A')} (score: {risk.get('score', 'N/A')})")

C++ Example (libcurl)

#include <iostream>
#include <string>
#include <curl/curl.h>

size_t WriteCallback(void* contents, size_t size, size_t nmemb, std::string* userp) {
    userp->append((char*)contents, size * nmemb);
    return size * nmemb;
}

std::string familyHealthAnalyze(const std::string& username,
                                 const std::string& password,
                                 const std::string& jsonPayload) {
    CURL* curl = curl_easy_init();
    std::string response;

    if (curl) {
        struct curl_slist* headers = NULL;
        headers = curl_slist_append(headers, "Content-Type: application/json");

        curl_easy_setopt(curl, CURLOPT_URL,
            "https://app.aibloodtestinterpret.com/api/v1/family-health/analyze");
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, jsonPayload.c_str());
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
        curl_easy_setopt(curl, CURLOPT_TIMEOUT, 120L);

        CURLcode res = curl_easy_perform(curl);
        curl_slist_free_all(headers);
        curl_easy_cleanup(curl);
    }
    return response;
}

int main() {
    std::string payload = R"({
        "username": "your_username",
        "password": "your_password",
        "patient_data": {"name": "Jane Doe", "age": 42, "gender": "female"},
        "family_members": [
            {"relation": "father", "age": 70, "conditions": ["hypertension"]},
            {"relation": "mother", "age": 67, "conditions": ["breast_cancer"]}
        ],
        "language": "en"
    })";
    std::string result = familyHealthAnalyze("user", "pass", payload);
    std::cout << result << std::endl;
    return 0;
}

Postman Example

Method: POST
URL: https://app.aibloodtestinterpret.com/api/v1/family-health/analyze
Headers:
  Content-Type: application/json
Body (raw JSON):
{
  "username": "YOUR_USERNAME",
  "password": "YOUR_PASSWORD",
  "patient_data": {
    "age": 42,
    "gender": "female"
  },
  "family_members": [
    {"relation": "father", "age": 70, "conditions": ["hypertension"]}
  ],
  "language": "en"
}

Example Response

{
  "status": "success",
  "data": {
    "report_data": {
      "report_title": "Family Health Risk Assessment Report",
      "executive_summary": "Based on family medical history analysis...",
      "hereditary_risk_analysis": {
        "high_risk": [
          {
            "condition": "Cardiovascular Disease",
            "risk_score": 75,
            "contributing_factors": ["Paternal hypertension", "Grandfather coronary artery disease"],
            "recommendation": "Regular cardiac screening recommended"
          }
        ],
        "moderate_risk": [
          {
            "condition": "Type 2 Diabetes",
            "risk_score": 60,
            "contributing_factors": ["Paternal type 2 diabetes", "Elevated glucose levels"],
            "recommendation": "Annual HbA1c and fasting glucose monitoring"
          }
        ],
        "low_risk": []
      },
      "medication_analysis": {
        "current_medications": ["metformin"],
        "hereditary_sensitivities": [],
        "recommendations": ["Continue metformin for prediabetes management"]
      },
      "blood_test_family_correlation": {
        "correlated_findings": [
          "Elevated glucose (110 mg/dL) correlates with paternal diabetes history",
          "Cholesterol level (220 mg/dL) warrants monitoring given cardiovascular family history"
        ]
      },
      "genetic_screening_recommendations": [
        "BRCA1/BRCA2 genetic testing (maternal breast cancer history)",
        "Cardiovascular genetic panel (strong paternal cardiac history)"
      ],
      "lifestyle_recommendations": [
        "Adopt heart-healthy Mediterranean diet",
        "150 minutes weekly moderate aerobic exercise",
        "Maintain healthy BMI (18.5-24.9)"
      ],
      "family_tree_summary": {
        "paternal_lineage": {"risk_factors": ["hypertension", "type2_diabetes", "coronary_artery_disease"]},
        "maternal_lineage": {"risk_factors": ["breast_cancer", "osteoporosis"]},
        "combined_risk_factors": ["cardiovascular", "metabolic", "oncological"]
      },
      "preventive_care_timeline": [
        {"age_range": "40-45", "screenings": ["Annual mammogram", "Cardiac stress test", "HbA1c every 6 months"]},
        {"age_range": "45-50", "screenings": ["Colonoscopy baseline", "Bone density scan", "Lipid panel annually"]},
        {"age_range": "50+", "screenings": ["Biennial mammogram", "Annual cardiac checkup", "Diabetes screening"]}
      ]
    }
  },
  "message": "Family health risk assessment completed successfully",
  "timestamp": "2026-03-23T10:30:00Z",
  "api_version": "1.0.0"
}

Family Health API Error Codes

Error CodeHTTP StatusDescription
AUTH_1001401Missing authentication credentials
AUTH_1002401Invalid username or password
QUOTA_1101403Insufficient API quota
QUOTA_1103429Rate limit exceeded
VAL_2001400Required field is missing (patient_data.age, patient_data.gender)
VAL_2002400Invalid data format
VAL_2003400Unsupported language code
VAL_2005400Request data cannot be empty
VAL_2006400Array exceeds maximum size (max 100 family members)
VAL_2007400Invalid patient data structure
PROC_3001500Report generation failed
PROC_3003500AI processing error
SRV_5001500Internal server error
POST /api/v1/family-health/validate

Validate your request data before submitting for analysis. No quota is consumed. Use this endpoint to verify your payload structure is correct before calling /analyze.

cURL Example

curl -X POST "https://app.aibloodtestinterpret.com/api/v1/family-health/validate" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "YOUR_USERNAME",
    "password": "YOUR_PASSWORD",
    "patient_data": {"age": 42, "gender": "female"},
    "family_members": [{"relation": "father", "conditions": ["hypertension"]}],
    "language": "en"
  }'

Example Response

{
  "status": "success",
  "data": {
    "validation": {
      "valid": true,
      "data_validation": {"valid": true, "error": null},
      "language_valid": true
    }
  },
  "message": "Validation completed",
  "timestamp": "2026-03-23T10:30:00Z",
  "api_version": "1.0.0"
}

Family Health Sandbox Endpoint

Test your Family Health API integration without consuming credits. The sandbox endpoint returns realistic sample report data.

APISandbox EndpointDescription
Family Health Analyze/api/v1/family-health/sandbox/analyzeReturns sample family health risk assessment report data

Reference Endpoints (No Auth Required)

These endpoints provide reference data for building your integration. No authentication is required.

EndpointMethodDescription
/api/v1/family-health/supported-languages GET Returns all 100+ supported language codes and names
/api/v1/family-health/condition-categories GET Returns all 9 condition categories with their conditions (Cardiovascular, Metabolic, Cancer, Neurological, Respiratory, Autoimmune, Genetic, Mental Health, Kidney/Liver)
/api/v1/family-health/family-relations GET Returns all 14 supported family relation types

Body Map API

Released: September 18, 2026

The Kantesti Body Map API turns a laboratory panel into anatomy. Every out-of-range and borderline result is placed on one of 13 body regions, and the API returns both the legend — which region, how severe, which markers put it there — and a URL for a matching illustration of the body.

13
Body Regions
39
Input Languages
0
Model Calls by Default

Deterministic by Default

Marker names are matched against multilingual alias tables covering 39 report languages, including non-Latin scripts — you send the analyte names exactly as your laboratory printed them, in whatever language it printed them. No model is called and no illustration is generated unless you ask, so the default request is free of AI cost and returns the same answer every time for the same panel.

Key Features
  • 13 Anatomical Regions — Brain & nerves, thyroid, heart & vessels, liver, pancreas, adrenals, kidneys, gut, reproductive, blood, immune, bones, muscles
  • Severity Levels — Level 2 for out-of-range results, level 1 for borderline, so a legend can be coloured without further logic
  • Marker Attribution — Every region lists the markers that put it there, worst first
  • Language-Free Output — Region keys and your own marker names; the illustration carries no text, so one picture serves every language
  • Signed Illustration URLs — Each illustration URL carries an HMAC signature, so nobody can enumerate or forge one
  • Honest Empty States — A clean panel returns the shared "all clear" body; a panel whose flagged markers cannot be placed returns an error rather than a misleading green body
  • Deterministic Mode — Default. No model call, no image credit, reproducible output
  • Sandbox Mode — Test your integration without consuming credits

Endpoints Summary

EndpointMethodDescriptionAuth
/api/v1/body-map/analyze POST Build a body map from a laboratory panel Required (1 credit)
/api/v1/body-map/validate POST Validate a payload and see which markers are recognised (no quota consumed) Required (Free)
/api/v1/body-map/sandbox POST Sandbox testing with sample data (no quota consumed) Required (Free)
/api/v1/body-map/regions GET List all 13 body regions and the severity levels Not required
/api/v1/body-map/info GET Capability metadata, limits and authentication details Not required
POST /api/v1/body-map/analyze Released 18 Sept 2026

Maps every flagged result in a laboratory panel onto the body. Consumes 1 credit per successful request. A request that fails validation, or whose flagged markers cannot be placed, is not charged.

Request Parameters

ParameterTypeRequiredDescription
usernamestringYesYour API username
passwordstringYesYour API password
parametersarrayYesLaboratory result objects. Max 500. Each needs an analyte name and an evaluation.
interpretationarrayNoClinical interpretation, used as context only when ai_assist is enabled
ai_assistbooleanNoLet the model place markers the alias tables do not recognise (default: false)
include_imagebooleanNoRequest the rendered illustration (default: false)
image_waitintegerNoSeconds to wait for a freshly generated illustration, 0-30 (default: 0)

Parameter Object Fields

FieldTypeRequiredDescription
short_namestringYes*Analyte name as printed by the laboratory. *At least one of short_name, long_name, name, parameter_name or parameter is required.
long_namestringNoFull analyte name; improves matching for abbreviations
evaluationstringNoOne of high, low, bad, slightly_high, slightly_low, normal. Only flagged values appear on the map.
resultstring|numberNoThe measured value; used to rank which regions are drawn
unitstringNoResult unit, any spelling
range_normal_minnumberNoLower bound of the reference range
range_normal_maxnumberNoUpper bound of the reference range
categorystringNoLaboratory category; used as a fallback when the analyte name is unknown

cURL Example

curl -X POST "https://app.aibloodtestinterpret.com/api/v1/body-map/analyze" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "YOUR_USERNAME",
    "password": "YOUR_PASSWORD",
    "parameters": [
      {"short_name": "ALT", "long_name": "Alanine aminotransferase", "result": "65", "unit": "U/L", "range_normal_min": 7, "range_normal_max": 45, "evaluation": "high"},
      {"short_name": "AST", "long_name": "Aspartate aminotransferase", "result": "48", "unit": "U/L", "range_normal_min": 8, "range_normal_max": 40, "evaluation": "slightly_high"},
      {"short_name": "TSH", "long_name": "Thyrotropin", "result": "6.2", "unit": "mIU/L", "range_normal_min": 0.4, "range_normal_max": 4.0, "evaluation": "high"}
    ]
  }'

Python Example

import requests

def build_body_map(parameters, username, password, include_image=False):
    """
    Map out-of-range blood test results onto the body.

    Args:
        parameters: List of laboratory result objects
        username: API username
        password: API password
        include_image: Request the rendered illustration (spends image credit)

    Returns:
        dict: Body map block with regions, legend and illustration URLs
    """
    url = "https://app.aibloodtestinterpret.com/api/v1/body-map/analyze"

    response = requests.post(url, json={
        "username": username,
        "password": password,
        "parameters": parameters,
        "include_image": include_image,
    }, timeout=60)
    response.raise_for_status()
    return response.json()

# Example usage
if __name__ == "__main__":
    result = build_body_map(
        parameters=[
            {"short_name": "ALT", "result": "65", "unit": "U/L",
             "range_normal_min": 7, "range_normal_max": 45, "evaluation": "high"},
            {"short_name": "TSH", "result": "6.2", "unit": "mIU/L",
             "range_normal_min": 0.4, "range_normal_max": 4.0, "evaluation": "high"},
        ],
        username="your_username",
        password="your_password",
    )

    body_map = result["data"]["body_map"]
    if result["data"]["all_clear"]:
        print("All clear — nothing flagged.")
    for region in body_map["regions"]:
        severity = "out of range" if region["level"] == 2 else "borderline"
        print(f"  {region['key']}: {severity} ({', '.join(region['markers'])})")
    print(f"Illustration: {body_map['image_url'] or body_map['fallback_url']}")

Example Response

{
  "status": "success",
  "api_version": "1.0.0",
  "message": "Body map generated successfully",
  "data": {
    "body_map": {
      "v": 4,
      "spec": "v4-thy2-liv2",
      "unmapped": 0,
      "image_url": "/static/body_maps/v4-thy2-liv2.webp",
      "fallback_url": "/body-map/v4-thy2-liv2.0123456789abcdef.webp",
      "regions": [
        {"key": "thyroid", "level": 2, "drawn": true, "markers": ["TSH"]},
        {"key": "liver", "level": 2, "drawn": true, "markers": ["ALT", "AST"]}
      ]
    },
    "engine_version": 4,
    "region_keys": ["brain_nerves", "thyroid", "heart_vessels", "liver", "pancreas", "adrenals", "kidneys", "gut", "reproductive", "blood", "immune", "bones", "muscles"],
    "mode": "deterministic",
    "all_clear": false
  },
  "timestamp": "2026-09-18T10:30:00Z"
}

Response Fields Reference

FieldTypeDescription
body_map.specstringCanonical identifier for this combination of regions and severities. Identical panels share a spec, and therefore share a cached illustration.
body_map.regions[].keystringOne of the 13 region keys
body_map.regions[].levelinteger2 = out of range, 1 = borderline
body_map.regions[].drawnbooleanWhether this region is painted on the illustration. The legend always lists every region; at most six are drawn.
body_map.regions[].markersarrayMarker names that put this region on the map, worst first
body_map.unmappedintegerFlagged markers that could not be placed on any region
body_map.image_urlstring|nullCached illustration. null until the file exists — fall back to fallback_url.
body_map.fallback_urlstringSigned generating URL. Always present. Answers 503 with Retry-After while the illustration is still being produced.
all_clearbooleantrue when nothing was flagged; the shared "all clear" body applies
modestringdeterministic or ai_assisted
Rendering the Legend

The response is language-free by design: it carries region keys and your laboratory's own marker names. Translate the 13 region keys in your own client, and prefer the legend over the illustration — if the image model ever paints the wrong organ, the legend beside it is still right.

POST /api/v1/body-map/validate Released 18 Sept 2026

Checks a payload without running the analysis, and reports which of your analyte names the engine recognises. Authentication is required; no quota is consumed, and the endpoint keeps working on an account with no credit left.

cURL Example

curl -X POST "https://app.aibloodtestinterpret.com/api/v1/body-map/validate" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "YOUR_USERNAME",
    "password": "YOUR_PASSWORD",
    "parameters": [
      {"short_name": "ALT", "result": "65", "evaluation": "high"},
      {"short_name": "Unobtainium", "result": "9", "evaluation": "high"}
    ]
  }'

Example Response

{
  "status": "success",
  "api_version": "1.0.0",
  "message": "Payload is valid",
  "data": {
    "valid": true,
    "errors": [],
    "parameter_count": 2,
    "flagged_count": 2,
    "recognised": [
      {"name": "ALT", "region": "liver", "level": 2}
    ],
    "unrecognised": [
      {"name": "Unobtainium", "region": null, "level": 2}
    ]
  },
  "timestamp": "2026-09-18T10:30:00Z"
}

Reference Endpoints

Both reference endpoints are unauthenticated and free.

GET /api/v1/body-map/regions

Lists the 13 body regions in canonical order, together with the severity levels. Use it to build your own legend translations.

cURL Example

curl "https://app.aibloodtestinterpret.com/api/v1/body-map/regions"

Example Response

{
  "status": "success",
  "data": {
    "regions": [
      {"key": "brain_nerves", "code": "brn", "order": 0},
      {"key": "thyroid", "code": "thy", "order": 1},
      {"key": "heart_vessels", "code": "hrt", "order": 2},
      {"key": "liver", "code": "liv", "order": 3}
    ],
    "region_keys": ["brain_nerves", "thyroid", "heart_vessels", "liver", "pancreas", "adrenals", "kidneys", "gut", "reproductive", "blood", "immune", "bones", "muscles"],
    "levels": {
      "0": "within range — not shown",
      "1": "borderline (slightly high / slightly low)",
      "2": "out of range (high / low / abnormal)"
    },
    "count": 13
  }
}
GET /api/v1/body-map/info

Capability metadata: whether the engine is enabled on this deployment, the request limits, the authentication scheme and the full endpoint list.

cURL Example

curl "https://app.aibloodtestinterpret.com/api/v1/body-map/info"

Sandbox

POST /api/v1/body-map/sandbox returns a sample response in exactly the shape /analyze produces, so a client written against the sandbox works unchanged against production. Authentication is required so the call also proves your credentials, but no quota is consumed and no analysis is performed.

Error CodeHTTPMeaning
AUTH_1001401Missing authentication credentials
AUTH_1002401Invalid username or password
AUTH_1004400Malformed credentials (wrong type or oversize)
QUOTA_1101403Insufficient API quota
VAL_2001400parameters is missing
VAL_2002400Invalid data format
VAL_2005400parameters is empty
VAL_2006400More than 500 parameters
VAL_2008400A parameter row is malformed or unnamed
RES_4004422Flagged results exist but none maps to a body region
RES_4005503The body map engine is disabled on this deployment

Biological Blood Age API

Released: September 18, 2026

The Kantesti Biological Blood Age API answers a question a reference range cannot: how old does this blood look? It computes biological age from a routine panel using the published Levine PhenoAge model, and alongside it derives up to 18 clinical indices — FIB-4, HOMA-IR, TyG, eGFR, AIP, NLR, anion gap and more — that a laboratory report rarely prints.

9
PhenoAge Markers
18
Derived Indices
39
Input Languages

A Number Even From a Partial Panel

PhenoAge needs nine markers and most panels carry fewer. Where all nine are present the API returns the published formula unchanged. Where they are not, the missing inputs are filled from population medians and the answer is returned as source: "partial", so you always know which you received. Both paths are deterministic: no model call, no extra cost, the same answer every time for the same panel.

Key Features
  • Levine PhenoAge — The published model, computed unchanged when all nine markers are present
  • Graceful Degradation — A partial panel still yields a number, clearly labelled as such, with the missing markers listed
  • 18 Clinical Indices — FIB-4, De Ritis, A/G ratio, HOMA-IR, TyG, eAG, eGFR, anion gap, BUN/creatinine, non-HDL, TG/HDL, AIP, TC/HDL, remnant cholesterol, NLR, Mentzer, transferrin saturation, corrected calcium
  • Automatic Unit Conversion — SI and conventional units, any spelling, with physiological plausibility checks that reject impossible values
  • Multilingual Marker Matching — Analyte names in 39 report languages including non-Latin scripts; you never send internal keys
  • Deterministic Mode — Default. No network call, no AI cost, reproducible output
  • Optional Model Layers — Row identification, an improved estimate and a personal note, each behind its own flag. A complete nine-marker PhenoAge is never overridden by the model.
  • 100 Languages — For the optional personal note
  • Sandbox Mode — Test your integration without consuming credits

Endpoints Summary

EndpointMethodDescriptionAuth
/api/v1/blood-age/analyze POST Compute biological blood age and derived clinical indices Required (1 credit)
/api/v1/blood-age/validate POST Validate a payload and see which markers the panel supports (no quota consumed) Required (Free)
/api/v1/blood-age/sandbox POST Sandbox testing with sample data (no quota consumed) Required (Free)
/api/v1/blood-age/biomarkers GET List the markers the engine reads and their target units Not required
/api/v1/blood-age/info GET Capability metadata, limits and authentication details Not required
POST /api/v1/blood-age/analyze Released 18 Sept 2026

Computes biological blood age and the derived indices from a laboratory panel. Consumes 1 credit per successful request. A request that fails validation, or whose panel yields nothing computable, is not charged.

Request Parameters

ParameterTypeRequiredDescription
usernamestringYesYour API username
passwordstringYesYour API password
parametersarrayYesLaboratory result objects. Max 500. Each needs an analyte name and a result.
metadataobjectNoReport header. Strongly recommended: PhenoAge has a chronological age term. Reads patient_age, patient_sex, dob, lab_date.
patientobjectNo{"age": 42, "gender": "female"} — used when the metadata does not carry them
interpretationarrayNoClinical interpretation, used as model context only
languagestringNoLanguage for the optional personal note (default: en). See supported languages.
ai_assistbooleanNoLet the model identify unusual analyte names (default: false)
ai_estimatebooleanNoLet the model improve a partial age (default: false)
ai_notebooleanNoAsk for a personal note in language (default: false)

The Nine PhenoAge Markers

Send them under whatever names your laboratory printed — matching is by name, in any of the 39 supported report languages, and units are converted automatically.

MarkerTypical NameTarget Unit
albuminAlbuming/L
creatinineCreatinineµmol/L
glucoseGlucose / Fasting blood sugarmmol/L
crpC-reactive proteinmg/L
lymphLymphocytes%
mcvMean corpuscular volumefL
rdwRed cell distribution width%
alpAlkaline phosphataseU/L
wbcWhite blood cell count10⁹/L

cURL Example

curl -X POST "https://app.aibloodtestinterpret.com/api/v1/blood-age/analyze" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "YOUR_USERNAME",
    "password": "YOUR_PASSWORD",
    "metadata": {"patient_age": "40", "patient_sex": "Male", "lab_date": "2026-09-11"},
    "parameters": [
      {"short_name": "Albumin", "result": 4.4, "unit": "g/dL", "range_normal_min": 3.5, "range_normal_max": 5.0},
      {"short_name": "Creatinine", "result": 0.9, "unit": "mg/dL", "range_normal_min": 0.6, "range_normal_max": 1.2},
      {"short_name": "Glucose", "result": 90, "unit": "mg/dL", "range_normal_min": 70, "range_normal_max": 99},
      {"short_name": "CRP", "result": 1.0, "unit": "mg/L", "range_normal_min": 0, "range_normal_max": 5},
      {"short_name": "Lymphocytes", "result": 30, "unit": "%", "range_normal_min": 20, "range_normal_max": 40},
      {"short_name": "MCV", "result": 90, "unit": "fL", "range_normal_min": 80, "range_normal_max": 100},
      {"short_name": "RDW", "result": 13, "unit": "%", "range_normal_min": 11.5, "range_normal_max": 14.5},
      {"short_name": "ALP", "result": 70, "unit": "U/L", "range_normal_min": 40, "range_normal_max": 130},
      {"short_name": "WBC", "result": 6.0, "unit": "10^9/L", "range_normal_min": 4, "range_normal_max": 11}
    ]
  }'

Python Example

import requests

def biological_blood_age(parameters, metadata, username, password):
    """
    Compute biological blood age from a routine blood panel.

    Args:
        parameters: List of laboratory result objects
        metadata: Report header carrying patient_age and patient_sex
        username: API username
        password: API password

    Returns:
        dict: Blood age block, derived indices, and a flat summary
    """
    url = "https://app.aibloodtestinterpret.com/api/v1/blood-age/analyze"

    response = requests.post(url, json={
        "username": username,
        "password": password,
        "parameters": parameters,
        "metadata": metadata,
    }, timeout=60)
    response.raise_for_status()
    return response.json()

# Example usage
if __name__ == "__main__":
    result = biological_blood_age(
        parameters=[
            {"short_name": "Albumin", "result": 4.4, "unit": "g/dL"},
            {"short_name": "Creatinine", "result": 0.9, "unit": "mg/dL"},
            {"short_name": "Glucose", "result": 90, "unit": "mg/dL"},
            {"short_name": "CRP", "result": 1.0, "unit": "mg/L"},
            {"short_name": "Lymphocytes", "result": 30, "unit": "%"},
            {"short_name": "MCV", "result": 90, "unit": "fL"},
            {"short_name": "RDW", "result": 13, "unit": "%"},
            {"short_name": "ALP", "result": 70, "unit": "U/L"},
            {"short_name": "WBC", "result": 6.0, "unit": "10^9/L"},
        ],
        metadata={"patient_age": "40", "patient_sex": "Male"},
        username="your_username",
        password="your_password",
    )

    summary = result["data"]["summary"]
    if summary["status"] != "ok":
        print(f"No age computed: {summary['status']}")
    else:
        print(f"Chronological: {summary['chronological_age']}")
        print(f"Biological:    {summary['biological_age']} ({summary['source']})")
        print(f"Difference:    {summary['delta_years']:+} years")

    for index in result["data"]["blood_age"]["indices"]:
        print(f"  {index['key']}: {index['value']} {index['unit']} [{index['band']}]")

Example Response

{
  "status": "success",
  "api_version": "1.0.0",
  "message": "Biological blood age computed successfully",
  "data": {
    "blood_age": {
      "version": 1,
      "age": {
        "status": "ok",
        "source": "formula",
        "chrono": 40,
        "pheno": 35.1,
        "delta": -4.9,
        "sex": "m",
        "found": ["albumin", "creatinine", "glucose", "crp", "lymph", "mcv", "rdw", "alp", "wbc"],
        "missing": [],
        "labels": {"albumin": "Albumin", "creatinine": "Creatinine", "glucose": "Glucose"},
        "inputs": {"albumin": 44.0, "creatinine": 79.56, "glucose": 5.0}
      },
      "indices": [
        {"key": "fib4", "group": "liver", "value": 1.12, "unit": "", "band": "ok", "from": ["AST", "ALT", "PLT"]},
        {"key": "egfr", "group": "kidneys", "value": 98.0, "unit": "mL/min/1.73m2", "band": "ok", "from": ["Creatinine"]},
        {"key": "nlr", "group": "immune", "value": 1.8, "unit": "", "band": "ok", "from": ["Neutrophils", "Lymphocytes"]}
      ]
    },
    "engine_version": 1,
    "mode": "deterministic",
    "summary": {
      "status": "ok",
      "source": "formula",
      "chronological_age": 40,
      "biological_age": 35.1,
      "delta_years": -4.9,
      "sex": "m",
      "markers_found": 9,
      "markers_missing": [],
      "indices_count": 3
    }
  },
  "timestamp": "2026-09-18T10:30:00Z"
}

Response Fields Reference

FieldTypeDescription
summary.statusstringok, missing_age, missing_markers, needs_markers or unavailable
summary.sourcestringformula (all nine markers), partial (medians imputed) or ai (model estimate, only with ai_estimate)
summary.chronological_ageinteger|nullAge read from the metadata or the patient object
summary.biological_agenumber|nullThe computed blood age, in years
summary.delta_yearsnumber|nullBiological minus chronological. Negative is younger than the calendar.
summary.markers_missingarrayWhich of the nine PhenoAge markers the panel did not supply
blood_age.age.inputsobjectThe converted values actually used, in the target units
blood_age.age.labelsobjectYour laboratory's own name for each marker the engine matched
blood_age.indices[].bandstringok, borderline, high, low or info
blood_age.indices[].fromarrayThe laboratory rows this index was derived from
modestringdeterministic or ai_assisted
Supply a Chronological Age

PhenoAge has an age term, so without a chronological age the response comes back with status: "missing_age" and no number. Send it in metadata.patient_age, or in patient.age, or as a date of birth in patient.dob. The formula applies between ages 18 and 100.

POST /api/v1/blood-age/validate Released 18 Sept 2026

Checks a payload without running the analysis, and reports which of the nine PhenoAge markers your panel supplies and whether a chronological age could be read — the two things that decide whether you will get the complete formula or the partial estimate. Authentication is required; no quota is consumed, and the endpoint keeps working on an account with no credit left.

cURL Example

curl -X POST "https://app.aibloodtestinterpret.com/api/v1/blood-age/validate" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "YOUR_USERNAME",
    "password": "YOUR_PASSWORD",
    "metadata": {"patient_age": "40", "patient_sex": "Male"},
    "parameters": [
      {"short_name": "MCV", "result": 90, "unit": "fL"},
      {"short_name": "WBC", "result": 6.0, "unit": "10^9/L"},
      {"short_name": "Lymphocytes", "result": 30, "unit": "%"}
    ]
  }'

Example Response

{
  "status": "success",
  "api_version": "1.0.0",
  "message": "Payload is valid",
  "data": {
    "valid": true,
    "errors": [],
    "parameter_count": 3,
    "looks_like_blood_panel": true,
    "chronological_age": 40,
    "sex": "m",
    "phenoage_markers_found": ["lymph", "mcv", "wbc"],
    "phenoage_markers_missing": ["albumin", "creatinine", "glucose", "crp", "rdw", "alp"],
    "expected_source": "partial",
    "recognised_markers": ["lymph_pct", "mcv", "wbc"]
  },
  "timestamp": "2026-09-18T10:30:00Z"
}

Reference Endpoints

Both reference endpoints are unauthenticated and free.

GET /api/v1/blood-age/biomarkers

Lists the nine PhenoAge inputs, every marker the engine can read with its target unit, and the age range the formula applies to.

cURL Example

curl "https://app.aibloodtestinterpret.com/api/v1/blood-age/biomarkers"

Example Response

{
  "status": "success",
  "data": {
    "phenoage_inputs": ["albumin", "creatinine", "glucose", "crp", "lymph", "mcv", "rdw", "alp", "wbc"],
    "phenoage_age_range": {"min": 18, "max": 100},
    "markers": [
      {"key": "albumin", "target_unit": "g/l"},
      {"key": "alp", "target_unit": "u/l"},
      {"key": "alt", "target_unit": "u/l"}
    ],
    "marker_count": 33,
    "name_matching": "Markers are matched by the analyte name your laboratory printed, in any of the supported report languages. You never send these keys."
  }
}
GET /api/v1/blood-age/info

Capability metadata: whether the engine is enabled on this deployment, the two modes and what each costs, the request limits, the authentication scheme and the supported languages.

cURL Example

curl "https://app.aibloodtestinterpret.com/api/v1/blood-age/info"

Sandbox

POST /api/v1/blood-age/sandbox returns a sample response in exactly the shape /analyze produces, so a client written against the sandbox works unchanged against production. Authentication is required so the call also proves your credentials, but no quota is consumed and no analysis is performed.

Error CodeHTTPMeaning
AUTH_1001401Missing authentication credentials
AUTH_1002401Invalid username or password
AUTH_1004400Malformed credentials (wrong type or oversize)
QUOTA_1101403Insufficient API quota
VAL_2001400parameters is missing
VAL_2002400Invalid data format
VAL_2003400Unsupported language code
VAL_2005400parameters is empty
VAL_2006400More than 500 parameters
VAL_2007400Invalid patient object
VAL_2008400A parameter row is malformed or unnamed
VAL_2009400Unsupported patient.gender value
RES_4004422Nothing computable from these parameters
RES_4005503The blood age engine is disabled on this deployment

DNA Health API: DNA Test Interpretation, DNA + Blood Report and Supplement Advisor

Released: September 23, 2026

We are proud to introduce the Kantesti DNA Health API: three new AI modules that turn a patient's DNA test into clinical reports. DNA Test Interpretation reads a raw genotype file or a genetic report and writes a comprehensive genetic health report. The DNA + Blood Health Report combines that report with an interpreted blood test and shows where genes and lab values confirm or contradict each other. The Supplement Advisor turns DNA, blood test and a short questionnaire into a personalised supplement plan built on your clinic's own products.

334
Curated DNA Markers
20
Health Categories
100+
Report Languages

Checked Against Your File

A raw genotype file is parsed on the server and compared with a curated panel of 334 markers in 20 categories, from methylation, cardiovascular and lipid genes to pharmacogenomics, nutrient metabolism, carrier status and longevity. Every finding the AI writes is checked against the upload: an rsID the file does not contain is dropped, and each genotype is pinned to the call printed in the file, so the report cannot invent a result.

Key Features
  • Every Common DNA Source — Raw files from 23andMe, AncestryDNA, MyHeritage, FTDNA and LivingDNA, VCF files, also inside .zip or .gz; pasted rsID lines; or a genetic report as up to 6 PDF, JPG or PNG files
  • Comprehensive Genetic Report — Findings by health area, disease risks, carrier status, pharmacogenomics (predicted metabolizer phenotypes and affected drug classes), nutrigenomics, traits, recommended follow-up tests and red flags
  • Genes Meet Lab Values — The DNA + Blood report marks every link between a genetic finding and a lab result as confirms, contradicts, neutral or watch, with a risk matrix, priority actions and a monitoring plan
  • Supplement Plans with Safety Rules — Dose, form, timing, duration, interactions and re-test dates; doses stay within tolerable upper intake levels, pregnancy-safe limits apply, and anything that needs a prescriber lands in clinician_review_required
  • Your Own Product Catalogue — The advisor recommends the products your clinic stocks, marks them as clinic_library, and in "only clinic products" mode lists the needs your catalogue does not cover
  • Chainable and Stateless — Send the report from module 1 straight into modules 2 and 3. Nothing is stored against a patient, and raw genotype files are discarded after parsing
  • 100+ Report Languages — The report is written in the language you ask for
  • Async Mode — Add ?async=1 and poll /api/jobs/<job_id>, so a long analysis never hits a gateway timeout
  • Sandbox Mode — Test your integration without consuming credits
How the Three Modules Work Together

1. POST /api/v1/dna-interpretation/analyze with the DNA file returns data.report. 2. Send that report with an interpreted blood test to /api/v1/dna-blood-report/analyze. 3. Send the same report, the questionnaire answers and optionally the blood test to /api/v1/dna-supplements/analyze. Modules 2 and 3 accept the DNA report as it came back: the report object, the whole data object or the full response.

Endpoints Summary

EndpointMethodDescriptionAuth
/api/v1/dna-interpretation/analyzePOSTDNA file, pasted rsID lines or report pages → comprehensive genetic health reportRequired (1 credit)
/api/v1/dna-interpretation/validatePOSTParse the upload and show what was found, without an AI callRequired (Free)
/api/v1/dna-interpretation/sandboxPOSTSample genetic reportRequired (Free)
/api/v1/dna-interpretation/infoGETAccepted inputs, limits and report languagesNot required
/api/v1/dna-blood-report/analyzePOSTDNA report + interpreted blood test → combined health reportRequired (1 credit)
/api/v1/dna-blood-report/validatePOSTCheck the payload without an AI callRequired (Free)
/api/v1/dna-blood-report/sandboxPOSTSample combined reportRequired (Free)
/api/v1/dna-blood-report/infoGETRequest fields and limitsNot required
/api/v1/dna-supplements/analyzePOSTDNA report + blood test (optional) + questionnaire → supplement planRequired (1 credit)
/api/v1/dna-supplements/validatePOSTCheck the payload and answers without an AI callRequired (Free)
/api/v1/dna-supplements/sandboxPOSTSample supplement planRequired (Free)
/api/v1/dna-supplements/questionnaireGETThe 25 questions and their allowed answersNot required
/api/v1/dna-supplements/settingsGET PUTRead or update your clinic's product catalogue and advisor settingsRequired (Free)
/api/v1/dna-supplements/infoGETRequest fields and limitsNot required
POST /api/v1/dna-interpretation/analyze Released 23 Sept 2026

Interprets one DNA test and returns a comprehensive genetic health report. Send a file as multipart/form-data, or pasted genotype lines as JSON. The upload is parsed while you wait, so an unreadable file is answered at once with 400 and costs nothing. One credit is charged only after the report was produced.

Request Parameters

ParameterTypeRequiredDescription
usernamestringYesYour API username (or use HTTP Basic authentication)
passwordstringYesYour API password
filefileYes*One raw genotype file (.txt, .csv, .tsv, .vcf, .zip, .gz, up to 80 MB) or up to 6 report files (PDF up to 20 MB, JPG/PNG up to 10 MB each). *Send either file or genotype_text.
genotype_textstringYes*Pasted genotype lines (rsID, chromosome, position, genotype), up to 2,000,000 characters
languagestringNoReport language code, e.g. en, de, ar (default: en). See Supported Languages.
patientobjectNoage, sex, diagnoses, comorbidities, medications, treatments, notes. In a multipart request, send it as a JSON string.
source_labelstringNoYour own name for the source, up to 120 characters

cURL Example

curl -X POST "https://app.aibloodtestinterpret.com/api/v1/dna-interpretation/analyze?async=1" \
  -u "YOUR_USERNAME:YOUR_PASSWORD" \
  -F "file=@genome_raw_data.txt" \
  -F "language=en" \
  -F 'patient={"age": 41, "sex": "female", "medications": "clopidogrel"}'

# 202 Accepted: {"status": "pending", "job_id": "...", "poll_url": "/api/jobs/...", ...}
curl -u "YOUR_USERNAME:YOUR_PASSWORD" "https://app.aibloodtestinterpret.com/api/jobs/JOB_ID"

Python Example

import time
import requests

BASE = "https://app.aibloodtestinterpret.com"
AUTH = ("YOUR_USERNAME", "YOUR_PASSWORD")


def run(path, poll=True, **kwargs):
    """POST in async mode, then poll /api/jobs/<id> until the report is ready."""
    resp = requests.post(f"{BASE}{path}?async=1", auth=AUTH, timeout=60, **kwargs)
    body = resp.json()
    if resp.status_code != 202:
        return body                      # an error, or a synchronous answer
    while True:
        time.sleep(body.get("poll_interval_ms", 3000) / 1000)
        job = requests.get(f"{BASE}{body['poll_url']}", auth=AUTH, timeout=30).json()
        if job["status"] in ("completed", "failed"):
            return job["result"]["response"]


# 1) DNA test interpretation
with open("genome_raw_data.txt", "rb") as fh:
    dna = run("/api/v1/dna-interpretation/analyze",
              files={"file": fh},
              data={"language": "en", "patient": '{"age": 41, "sex": "female"}'})
report = dna["data"]["report"]
print(report["executive_summary"])
for section in report["sections"]:
    print(section["title"], "-", section["risk_level"])

Example Response

{
  "status": "success",
  "api_version": "1.0.0",
  "message": "DNA test interpretation completed successfully",
  "data": {
    "analysis_id": "DNA-3F9A1C07B2",
    "module": "dna_interpretation",
    "generated_at": "2026-09-23T10:30:00Z",
    "language": "en",
    "source": {
      "kind": "raw", "format": "23andme", "build": "GRCh37",
      "total_records": 638463, "called": 631022, "no_call_rate": 0.0117,
      "inferred_sex": "female", "panel_total": 334, "panel_found": 291,
      "filename": "genome_raw_data.txt", "warnings": []
    },
    "report": {
      "report_type": "dna",
      "title": "Genetic health report",
      "executive_summary": "Array genotyping with good coverage of the clinical panel...",
      "overall_assessment": {"level": "slightly_elevated", "summary": "Mostly typical findings with a few actionable ones."},
      "data_quality": {"source": "23andMe v5 raw file", "markers_analyzed": 291, "coverage_note": "...", "limitations": "..."},
      "sections": [
        {
          "key": "nutrigenomics", "title": "Nutrient metabolism", "risk_level": "slightly_elevated",
          "summary": "Reduced folate cycle activity...",
          "findings": [
            {"gene": "MTHFR", "rsid": "rs1801133", "genotype": "AG", "phenotype": "C677T heterozygous",
             "risk_level": "slightly_elevated", "evidence": "established",
             "explanation": "About 65% of typical enzyme activity.", "recommendation": "Check homocysteine."}
          ]
        }
      ],
      "pharmacogenomics": [
        {"gene": "CYP2C19", "rsids": ["rs4244285"], "predicted_phenotype": "Intermediate metabolizer",
         "affected_drugs": ["clopidogrel", "omeprazole"], "recommendation": "Review before prescribing clopidogrel."}
      ],
      "disease_risks": [], "carrier_status": [], "nutrigenomics": [], "traits": [],
      "lifestyle_recommendations": ["..."], "recommended_tests": [{"test": "Homocysteine", "reason": "MTHFR C677T"}],
      "red_flags": [], "limitations": "Consumer arrays miss rare variants.",
      "disclaimer": "AI-generated clinical decision support for clinician review; not a diagnosis."
    }
  },
  "timestamp": "2026-09-23T10:30:00Z"
}

Response Fields Reference

FieldTypeDescription
sourceobjectWhat was read: kind (raw, text or document), detected format and genome build, record and call counts, how many of the 334 panel markers were found, and parser warnings
report.overall_assessment.levelstringtypical, slightly_elevated, elevated or high
report.sections[]arrayOne entry per health area with a risk_level and its findings
report.sections[].findings[]arraygene, rsid, genotype, phenotype, risk_level (protective, typical, informational, slightly_elevated, elevated, high), evidence (established, probable, preliminary), explanation, recommendation
report.pharmacogenomics[]arrayPredicted metabolizer phenotype per gene and the drug classes it may affect. The report never gives prescription doses.
report.carrier_status[]arraycarrier, not_detected, affected_pattern or inconclusive, always to be confirmed by clinical genetic testing
report.disease_risks[], nutrigenomics[], traits[]arrayCondition risks, nutrient findings and traits with the genes behind them
report.recommended_tests[], red_flags[]arrayFollow-up tests with a reason, and findings that need prompt attention
POST /api/v1/dna-interpretation/validate Released 23 Sept 2026

Parses the upload exactly like /analyze and reports what was found, without an AI call. Authentication is required; no credit is consumed. Use it to check a file before spending a credit.

Example Response

{
  "status": "success",
  "message": "Payload is valid",
  "data": {
    "valid": true,
    "language": "en",
    "source": {"kind": "raw", "format": "ancestrydna", "build": "GRCh37", "panel_total": 334, "panel_found": 287, "warnings": []}
  }
}
POST /api/v1/dna-blood-report/analyze Released 23 Sept 2026

Combines a DNA report with an interpreted blood test into one health report. Every link between a genetic finding and a lab value is classified, followed by a risk matrix, priority actions and a monitoring plan. One credit per successful request.

Request Parameters

ParameterTypeRequiredDescription
dna_reportobjectYesThe report from /api/v1/dna-interpretation/analyze: data.report, the whole data or the full response
blood_testobject|arrayYesAn interpreted blood test as the Blood Test API returns it (metadata, parameters, interpretation), or just a list of up to 500 parameters with a name and a result
languagestringNoReport language code (default: en)
patientobjectNoSame fields as in DNA Test Interpretation

Python Example

# 2) DNA + blood health report (uses run() and dna from the example above)
blood_test = {
    "parameters": [
        {"short_name": "25-OH D", "result": 18, "unit": "ng/mL", "range_normal_min": 30, "range_normal_max": 100, "evaluation": "low"},
        {"short_name": "Homocysteine", "result": 13.2, "unit": "µmol/L", "evaluation": "high"}
    ]
}
combined = run("/api/v1/dna-blood-report/analyze",
               json={"dna_report": dna, "blood_test": blood_test, "language": "en"})
for link in combined["data"]["report"]["correlations"]:
    print(link["topic"], link["concordance"], link["action"])

Example Response

{
  "status": "success",
  "message": "DNA + blood health report completed successfully",
  "data": {
    "analysis_id": "DNB-8C21E40A9D",
    "module": "dna_blood_report",
    "language": "en",
    "report": {
      "report_type": "dna_blood",
      "executive_summary": "The low vitamin D level matches the GC genotype; homocysteine is borderline, in line with MTHFR C677T.",
      "overall_status": {"level": "watch", "summary": "Two gene-lab matches to act on."},
      "correlations": [
        {"topic": "Vitamin D", "genetic_finding": "GC rs2282679 GT", "lab_finding": "25-OH D 18 ng/mL",
         "concordance": "confirms", "interpretation": "Genetic tendency and lab value agree.", "action": "Supplement and recheck in 12 weeks."}
      ],
      "risk_matrix": [{"area": "Folate cycle", "genetic_risk": "slightly_elevated", "lab_status": "borderline", "combined_assessment": "Watch homocysteine."}],
      "priority_actions": [{"priority": "high", "action": "Start vitamin D3", "why": "Deficient level and GC genotype"}],
      "monitoring_plan": [{"marker": "25-OH vitamin D", "interval": "12 weeks", "reason": "Dose check"}],
      "lifestyle_plan": [], "questions_for_clinician": [], "red_flags": [],
      "limitations": "One blood test; values vary.",
      "disclaimer": "AI-generated clinical decision support for clinician review; not a diagnosis."
    }
  }
}

Response Fields Reference

FieldTypeDescription
report.overall_status.levelstringgood, watch, attention or urgent
report.correlations[].concordancestringconfirms, contradicts, neutral or watch
report.risk_matrix[]arrayPer area: genetic_risk, lab_status (normal, borderline, abnormal, not_measured) and a combined assessment
report.priority_actions[]arraypriority (high, medium, low), the action and why
report.monitoring_plan[]arrayWhich marker to re-test, when and why
POST /api/v1/dna-supplements/analyze Released 23 Sept 2026

Builds a personalised supplement plan from the DNA report, the questionnaire answers and, optionally, an interpreted blood test. Your clinic's product catalogue and advisor settings are applied automatically. One credit per successful request.

Request Parameters

ParameterTypeRequiredDescription
dna_reportobjectYesThe report from /api/v1/dna-interpretation/analyze
answersobjectYesQuestionnaire answers. diet_type and pregnancy are required; see GET /api/v1/dna-supplements/questionnaire for all 25 questions. Unknown keys and values are dropped.
blood_testobject|arrayNoSame format as in the DNA + Blood Report
use_clinic_cataloguebooleanNoApply your clinic's product catalogue and settings (default: true)
languagestringNoReport language code (default: en)
patientobjectNoSame fields as in DNA Test Interpretation. Medications listed here are checked for interactions.

cURL Example

curl -X POST "https://app.aibloodtestinterpret.com/api/v1/dna-supplements/analyze?async=1" \
  -u "YOUR_USERNAME:YOUR_PASSWORD" \
  -H "Content-Type: application/json" \
  -d '{
    "dna_report": { ...data.report from the DNA interpretation... },
    "answers": {"diet_type": "vegetarian", "pregnancy": "no", "sun_exposure": "low", "goals": ["energy", "immunity"]},
    "language": "en"
  }'

Python Example

# 3) Supplement plan (uses run(), dna and blood_test from the examples above)
plan = run("/api/v1/dna-supplements/analyze",
           json={"dna_report": dna, "blood_test": blood_test,
                 "answers": {"diet_type": "vegetarian", "pregnancy": "no"},
                 "language": "en"})
for item in plan["data"]["report"]["recommendations"]:
    print(item["name"], item["dose"], item["timing"], "-", item["source"])

Example Response

{
  "status": "success",
  "message": "Supplement plan completed successfully",
  "data": {
    "analysis_id": "SUP-51B7D2E6F0",
    "module": "dna_supplements",
    "language": "en",
    "catalogue": {"mode": "prefer", "products": 24},
    "report": {
      "report_type": "supplement",
      "summary": "Plan built from GC and MTHFR findings, a low vitamin D level and a vegetarian diet.",
      "recommendations": [
        {"name": "Vitamin D3 + K2", "source": "clinic_library", "product": "Vitamin D3 + K2 (Clinic Brand)",
         "form": "softgel", "dose": "2000 IU", "timing": "with lunch", "duration": "12 weeks", "priority": "high",
         "rationale": {"genetic": "GC rs2282679 GT", "lab": "25-OH D 18 ng/mL", "questionnaire": "little sun"},
         "evidence": "established", "cautions": ["Recheck calcium"], "interactions": ["Thiazide diuretics"],
         "retest": "25-OH D in 12 weeks"}
      ],
      "avoid_or_caution": [{"name": "High-dose vitamin A", "reason": "Pregnancy planning"}],
      "uncovered_needs": [],
      "dietary_sources": [{"nutrient": "Folate", "foods": ["lentils", "spinach"]}],
      "retest_plan": [{"marker": "25-OH vitamin D", "when": "12 weeks", "why": "Dose check"}],
      "clinician_review_required": ["Thiazide co-medication"],
      "disclaimer": "AI-generated clinical decision support for clinician review; not a diagnosis."
    }
  }
}

Response Fields Reference

FieldTypeDescription
catalogueobjectThe catalogue mode that was applied (prefer, only, off) and how many clinic products were available
report.recommendations[]arrayname, form, dose, timing, duration, priority, the genetic / lab / questionnaire rationale, evidence, cautions, interactions and retest
report.recommendations[].sourcestringclinic_library for a product from your catalogue (named in product), otherwise evidence_based
report.uncovered_needs[]arrayIn "only clinic products" mode: needs your catalogue does not cover
report.clinician_review_required[]arrayEverything that needs a prescriber's decision: interactions, pregnancy, kidney or liver disease, anticoagulants, doses near the upper intake level
report.avoid_or_caution[], dietary_sources[], retest_plan[]arrayWhat to avoid, food sources for each nutrient, and when to re-test
GET PUT /api/v1/dna-supplements/settings Released 23 Sept 2026

Reads or updates your clinic's product catalogue and the advisor settings. It is the same catalogue as in the clinic panel and in Nutrition Diet AI, so a product added in one place is available everywhere. Authentication is required; no credit is consumed. Send catalogue, settings or both; the catalogue replaces the whole list.

FieldTypeDescription
catalogue[]arrayUp to 200 products: name, brand, form, dosage, category (vitamin, mineral, probiotic, omega, herbal, other), description
settings.modestringprefer (clinic products where they fit, evidence-based suggestions otherwise), only (only clinic products) or off (ignore the catalogue)
settings.instructionsstringYour own instructions for the AI, up to 1,500 characters. Safety rules always take priority.
settings.max_itemsintegerMaximum recommendations per plan, 3 to 12

cURL Example

curl -X PUT "https://app.aibloodtestinterpret.com/api/v1/dna-supplements/settings" \
  -u "YOUR_USERNAME:YOUR_PASSWORD" \
  -H "Content-Type: application/json" \
  -d '{
    "catalogue": [
      {"name": "Vitamin D3 + K2", "brand": "Clinic Brand", "form": "softgel", "dosage": "2000 IU / 75 µg", "category": "vitamin"},
      {"name": "Omega-3 EPA/DHA", "brand": "Clinic Brand", "form": "softgel", "dosage": "1000 mg", "category": "omega"}
    ],
    "settings": {"mode": "prefer", "instructions": "Prefer our own brand.", "max_items": 8}
  }'

Reference Endpoints

GET /api/v1/dna-supplements/questionnaire lists the 25 questions (diet, meals, fruit and vegetables, fish, red meat, dairy, alcohol, smoking, caffeine, sun exposure, exercise, sleep, stress, digestion, energy, current supplements, medications, allergies, conditions, pregnancy, goals, budget, preferred form and notes) with their types and allowed values. The three /info endpoints return the accepted inputs, limits, credit cost and the full list of report languages. None of them needs authentication.

Sandbox and Async Mode

POST /api/v1/dna-interpretation/sandbox, /api/v1/dna-blood-report/sandbox and /api/v1/dna-supplements/sandbox return a sample report in exactly the shape /analyze produces. Authentication is required; no credit is consumed.

An AI report usually takes one to three minutes. Add ?async=1 (or the header X-Async: 1) and the request answers 202 at once with a job_id. Poll GET /api/jobs/<job_id> with the same credentials until status is completed or failed. The final response is in result.response, identical to the synchronous one.

Error CodeHTTPMeaning
AUTH_1001401Missing authentication credentials
AUTH_1002401Invalid username or password
QUOTA_1101403Insufficient API quota
VAL_2001400A required field is missing: file or genotype_text, dna_report, blood_test, or a required answer
VAL_2002400Unreadable genotype data, unsupported file type, invalid JSON or an invalid dna_report
VAL_2003400Unsupported report language
VAL_2006400Too large: pasted text, blood parameters (500) or catalogue (200 products)
VAL_2007400Invalid patient object
VAL_2008400No usable blood test parameter (name and result)
PROC_3003500The AI answer could not be produced or validated; retry. No credit is charged.
RES_4005503The DNA modules are switched off on this deployment
Clinical Decision Support

The DNA Health API produces AI-generated information for the treating clinician. It is not a diagnosis and not a prescription. Consumer genotyping arrays are not clinical sequencing: confirm actionable and carrier findings with validated clinical genetic testing before acting on them.

ICR - Intelligent Character Recognition API

Released: February 14, 2026

The Kantesti ICR (Intelligent Character Recognition) API is an advanced document text extraction technology that goes far beyond traditional OCR. Powered by Kantesti's proprietary AI engine, ICR delivers structured JSON output from any document type including medical reports, invoices, forms, and more.

79%
Faster than OCR
99.7%
Accuracy Rate
100+
Languages

Kantesti ICR vs Traditional OCR

In benchmark tests, Kantesti ICR demonstrated 79% higher performance compared to traditional OCR solutions. ICR understands document structure, preserves table layouts, extracts metadata, and returns clean structured JSON — while OCR only provides raw unstructured text. ICR uses AI-powered intelligent recognition to understand context, detect document types automatically, and deliver structured data ready for integration.

ICR Key Features
  • Structured JSON Output — Tables, sections, metadata, and raw text in clean JSON format
  • Document Type Detection — Automatically identifies medical reports, invoices, forms, letters, etc.
  • Table Extraction — Preserves table headers and row data with full structure
  • Multi-format Support — PDF, JPG, JPEG, PNG document processing
  • Blood Test Integration (Kan) — Specialized endpoint for blood test document extraction
  • Sandbox Mode — Test integration without consuming credits
  • Thread-safe Processing — Concurrent document processing with RLock
  • Credit System — 0.5 credits per API call

ICR Endpoints Summary

EndpointMethodDescriptionCost
/api/icr/v1/extract POST ICR text extraction from documents 0.5 credit
/api/icr/v1/sandbox POST ICR sandbox testing (no processing) Free
/api/icr/v1/kan POST Blood test document analysis 0.5 credit
/api/icr/v1/kan/sandbox POST Blood test sandbox testing Free
/api/icr/info GET API documentation and features Free
/api/icr/health GET Health check endpoint Free
/api/icr/v1/quota POST Check remaining ICR credits Free
POST /api/icr/v1/extract Released 14 Feb 2026

Extract all text content from uploaded documents using Kantesti ICR technology. Returns structured JSON with document type detection, table extraction, section parsing, and metadata.

Request Parameters

ParameterTypeRequiredDescription
usernamestringYesYour API username
passwordstringYesYour API password
filefileYesDocument file (PDF, JPG, JPEG, PNG)
languagestringNoOutput language code (default: en). See supported languages.

cURL Example

curl -X POST "https://app.aibloodtestinterpret.com/api/icr/v1/extract" \
  -F "username=YOUR_USERNAME" \
  -F "password=YOUR_PASSWORD" \
  -F "language=en" \
  -F "[email protected]"

Python Example

import requests

def icr_extract(file_path: str, username: str, password: str, language: str = "en"):
    """
    Extract text from a document using Kantesti ICR API.
    79% faster and more accurate than traditional OCR.

    Args:
        file_path: Path to the document (PDF, JPG, JPEG, PNG)
        username: API username
        password: API password
        language: Output language code (default: en)

    Returns:
        dict: Structured JSON with document content, tables, sections, metadata
    """
    url = "https://app.aibloodtestinterpret.com/api/icr/v1/extract"

    with open(file_path, "rb") as f:
        files = {"file": (file_path, f)}
        data = {
            "username": username,
            "password": password,
            "language": language
        }

        response = requests.post(url, files=files, data=data, timeout=120)
        response.raise_for_status()
        return response.json()

# Example usage
if __name__ == "__main__":
    result = icr_extract(
        file_path="medical_report.pdf",
        username="your_username",
        password="your_password",
        language="en"
    )
    print(f"Status: {result['status']}")
    print(f"Document Type: {result['data']['document_type']}")
    print(f"Pages: {result['data']['page_count']}")
    for page in result['data']['pages']:
        print(f"  Page {page['page_number']}: {len(page['content']['sections'])} sections")
        for table in page['content'].get('tables', []):
            print(f"    Table: {len(table['rows'])} rows x {len(table['headers'])} cols")

C++ Example (libcurl)

#include <iostream>
#include <string>
#include <curl/curl.h>

size_t WriteCallback(void* contents, size_t size, size_t nmemb, std::string* userp) {
    userp->append((char*)contents, size * nmemb);
    return size * nmemb;
}

std::string icrExtract(const std::string& filePath,
                        const std::string& username,
                        const std::string& password,
                        const std::string& language = "en") {
    CURL* curl = curl_easy_init();
    std::string response;

    if (curl) {
        curl_mime* form = curl_mime_init(curl);
        curl_mimepart* field;

        field = curl_mime_addpart(form);
        curl_mime_name(field, "username");
        curl_mime_data(field, username.c_str(), CURL_ZERO_TERMINATED);

        field = curl_mime_addpart(form);
        curl_mime_name(field, "password");
        curl_mime_data(field, password.c_str(), CURL_ZERO_TERMINATED);

        field = curl_mime_addpart(form);
        curl_mime_name(field, "language");
        curl_mime_data(field, language.c_str(), CURL_ZERO_TERMINATED);

        field = curl_mime_addpart(form);
        curl_mime_name(field, "file");
        curl_mime_filedata(field, filePath.c_str());

        curl_easy_setopt(curl, CURLOPT_URL,
            "https://app.aibloodtestinterpret.com/api/icr/v1/extract");
        curl_easy_setopt(curl, CURLOPT_MIMEPOST, form);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
        curl_easy_setopt(curl, CURLOPT_TIMEOUT, 120L);

        CURLcode res = curl_easy_perform(curl);
        curl_mime_free(form);
        curl_easy_cleanup(curl);
    }
    return response;
}

int main() {
    std::string result = icrExtract("medical_report.pdf", "username", "password");
    std::cout << result << std::endl;
    return 0;
}

Example Response

{
  "status": "success",
  "data": {
    "document_type": "blood_test_report",
    "page_count": 1,
    "pages": [
      {
        "page_number": 1,
        "content": {
          "raw_text": "Cologne University Hospital - Blutbild\n\nPatient: Max Mustermann\nDOB: 15.03.1990\nGender: Male\nDate: 10.01.2026\n\nGlucose: 92 mg/dL (74-100)\nALT: 22 U/L (<35)\nCreatinine: 0.9 mg/dL (0.7-1.2)\nWBC: 7.2 10*9/L (3.8-10)\nHGB: 148 g/L (130-175)\nPLT: 230 10*9/L (150-400)",
          "sections": [
            {"type": "header", "content": "Cologne University Hospital - Blutbild"},
            {"type": "paragraph", "content": "Patient: Max Mustermann, DOB: 15.03.1990, Male"},
            {"type": "table", "content": "Blood test results with 6 parameters"}
          ],
          "tables": [
            {
              "headers": ["Test", "Result", "Unit", "Reference Range"],
              "rows": [
                ["Glucose", "92", "mg/dL", "74 - 100"],
                ["ALT", "22", "U/L", "< 35"],
                ["Creatinine", "0.9", "mg/dL", "0.7 - 1.2"],
                ["WBC", "7.2", "10*9/L", "3.8 - 10"],
                ["HGB", "148", "g/L", "130 - 175"],
                ["PLT", "230", "10*9/L", "150 - 400"]
              ]
            }
          ]
        }
      }
    ],
    "metadata": {
      "detected_language": "de",
      "confidence": "high"
    },
    "icr_metadata": {
      "engine": "kantesti-icr",
      "version": "1.0.0",
      "images_processed": 1,
      "timestamp": "2026-02-14T10:30:00Z"
    }
  },
  "credit_cost": 0.5,
  "api_version": "icr-v1",
  "timestamp": "2026-02-14T10:30:00Z"
}

ICR Error Codes

Error CodeHTTP StatusDescription
ICR_AUTH_1001401Missing authentication credentials
ICR_AUTH_1002401Invalid username or password
ICR_QUOTA_1101403Insufficient credits (0.5 credits required per call)
ICR_VAL_2001400No file uploaded
ICR_VAL_2002400Invalid file format (supported: PDF, JPG, JPEG, PNG)
ICR_VAL_2003400Multiple PDF files not allowed in single request
ICR_VAL_2004400Cannot mix PDF and image files in single request
ICR_PROC_3001500ICR text extraction failed
ICR_PROC_3004504Processing timeout
ICR_SRV_5001500Internal server error
ICR_SRV_5002503ICR service temporarily unavailable
POST /api/icr/v1/kan Released 14 Feb 2026

Blood test document analysis using Kantesti Kan engine. Processes blood test documents and extracts structured test parameters, patient information, and metadata.

Request Parameters

ParameterTypeRequiredDescription
usernamestringYesYour API username
passwordstringYesYour API password
filefileYesBlood test file (PDF, JPG, JPEG, PNG)
languagestringNoReport language code (default: en)
pdf_passwordstringNoPassword for encrypted PDFs

cURL Example

curl -X POST "https://app.aibloodtestinterpret.com/api/icr/v1/kan" \
  -F "username=YOUR_USERNAME" \
  -F "password=YOUR_PASSWORD" \
  -F "language=en" \
  -F "file=@blood_test.pdf"

Python Example

import requests

def icr_kan_analyze(file_path: str, username: str, password: str,
                     language: str = "en", pdf_password: str = None):
    """
    Analyze blood test document using Kantesti ICR Kan engine.

    Args:
        file_path: Path to blood test document (PDF, JPG, JPEG, PNG)
        username: API username
        password: API password
        language: Report language code (default: en)
        pdf_password: Password for encrypted PDFs (optional)

    Returns:
        dict: Structured blood test parameters with patient info
    """
    url = "https://app.aibloodtestinterpret.com/api/icr/v1/kan"

    with open(file_path, "rb") as f:
        files = {"file": (file_path, f)}
        data = {
            "username": username,
            "password": password,
            "language": language
        }
        if pdf_password:
            data["pdf_password"] = pdf_password

        response = requests.post(url, files=files, data=data, timeout=120)
        response.raise_for_status()
        return response.json()

# Example usage
if __name__ == "__main__":
    result = icr_kan_analyze(
        file_path="blood_test_report.pdf",
        username="your_username",
        password="your_password",
        language="en"
    )
    print(f"Status: {result['status']}")
    params = result['data']['test_parameters']
    print(f"Parameters found: {len(params)}")
    for param in params:
        print(f"  {param['name']}: {param['value']} {param['unit']} ({param['reference_range']})")

Example Response

{
  "status": "success",
  "data": {
    "institute_info": {
      "name": "Cologne University Hospital"
    },
    "test_metadata": {
      "report_date": "10.01.2026",
      "sample_type": "Blood",
      "test_date": "10.01.2026"
    },
    "test_parameters": [
      {"name": "Glucose (Fasting Blood Sugar)", "value": "92", "unit": "mg/dL", "reference_range": "74 - 100", "type": "range"},
      {"name": "Alanine aminotransferase (ALT)", "value": "22", "unit": "U/L", "reference_range": "< 35", "type": "range"},
      {"name": "Creatinine", "value": "0.9", "unit": "mg/dL", "reference_range": "0.7 - 1.2", "type": "range"},
      {"name": "Cholesterol", "value": "185", "unit": "mg/dL", "reference_range": "< 200", "type": "range"},
      {"name": "TSH", "value": "2.1", "unit": "mIU/L", "reference_range": "0.38 - 5.33", "type": "range"},
      {"name": "WBC (White Blood Cell Count)", "value": "7.2", "unit": "10*9/L", "reference_range": "3.8 - 10", "type": "range"},
      {"name": "RBC (Red Blood Cell Count)", "value": "4.9", "unit": "10*12/L", "reference_range": "4.5 - 5.5", "type": "range"},
      {"name": "HGB (Hemoglobin)", "value": "148", "unit": "g/L", "reference_range": "130 - 175", "type": "range"},
      {"name": "PLT (Platelet Count)", "value": "230", "unit": "10*9/L", "reference_range": "150 - 400", "type": "range"},
      {"name": "HBsAg", "value": "Negative", "unit": "", "reference_range": "", "type": "binary"}
    ],
    "tester_info": {
      "age": "35 (Calculated from 15.03.1990 to 10.01.2026)",
      "gender": "Male"
    },
    "kan_metadata": {
      "engine": "kantesti-kan",
      "version": "1.0.0",
      "language": "en",
      "timestamp": "2026-02-14T10:30:00Z"
    }
  },
  "credit_cost": 0.5,
  "api_version": "icr-v1",
  "timestamp": "2026-02-14T10:30:00Z"
}

ICR Sandbox Endpoints

Test your ICR integration without consuming credits. Sandbox endpoints return realistic sample data.

APISandbox EndpointDescription
ICR Extract/api/icr/v1/sandboxReturns sample ICR extraction data
ICR Kan/api/icr/v1/kan/sandboxReturns sample blood test parameter data

ICR vs OCR Performance Benchmark

Benchmark Results — Kantesti ICR vs Traditional OCR
MetricKantesti ICRTraditional OCRImprovement
Processing Speed1.2s average5.7s average79% faster
Text Accuracy99.7%92.1%+7.6%
Table Detection98.9%71.2%+27.7%
Structured OutputJSON with sections, tables, metadataRaw unstructured textFull structure
Document Type DetectionAutomaticNot availableAI-powered
Multi-language Support100+ languages30-50 languages2x+ coverage
Medical Document SupportSpecializedGenericDomain expertise