# dietary-supplement-analysis 0.15.1 > Supplement label lookup (NIH Dietary Supplement Label Database, DSLD) and per-nutrient intake checks against NIH reference values. One call answers "is anything in my supplements too high, why does that matter, and what change would fix it". Information from labels and NIH reference data, not medical advice. All endpoints take and return JSON objects. Errors are 4xx JSON: {"error":{"code","message","retryable","field"}}. Never 5xx. ## The one call most agents need POST /v1/stack/analyze with what the user said, as written: {"age": 62, "sex": "female", "products": [ {"query": "Centrum Silver Women 50+"}, {"query": "Nature Made fish oil 1400"}, {"upc": "031604026974"}, {"dsld_id": 253226, "servings_per_day": 1}, {"name": "Homemade zinc", "ingredients": [{"name": "zinc", "amount": 25, "unit": "mg"}]} ], "medications": ["warfarin", "Synthroid"], "conditions": ["smoker"], "candidates": [{"query": "vitamin d3 5000 iu"}]} - products: 1-15. Each is a product name ({"query"}), a barcode ({"upc"}), a DSLD ID ({"dsld_id"}), or a custom product with explicit ingredients. Pass "servings_per_day" whenever the user said how much they take; otherwise the label's maximum daily servings is assumed (listed in assumptions). - lang (optional): "es" writes agent_summary in Spanish (English kept in agent_summary_en). Medication names may be given in Spanish ("warfarina", "levotiroxina", "Sintrom"). - detail (optional): "summary" for a compact 1-3 KB answer (recommended when the result goes into your context); "full" (default) for every field. - foods (optional, up to 30): what the person eats in a day, e.g. {"query": "spinach cooked", "amount": 1, "unit": "cup"} or {"query": "whole milk", "grams": 488}. Matched offline to USDA SR28 foods and added in nutrient_totals[].with_foods; food-only nutrients are checked in foods.totals. Use foods or diet "typical", not both. - diet (optional): "typical" adds US average food and drink intake for the age and sex (NHANES) and repeats the checks in nutrient_totals[].with_typical_diet. Use it when the user asks whether their total intake is too high or too low. - candidates (optional, up to 5): products the user is thinking of adding. Each is evaluated as an addition in candidate_results[]. - medications (optional, up to 30): generic or brand names as the user said them. Each is matched to a drug class (RxNorm normalizes names the list doesn't know) and checked against the medication interactions in the NIH ODS fact sheets and, for herbs in the stack (St. John's wort, ginkgo, kava...), the NIH NCCIH fact sheets, with timing advice where NIH gives it (for example, take levothyroxine 4 hours apart from calcium or iron). Not exhaustive. - conditions (optional): smoker (current or former, or asbestos exposure), kidney_disease, hemochromatosis, lab_test_soon (biotin skews lab tests), cancer_treatment. Each flags the doses NIH warns about for that group. - age and sex together enable upper-limit checks. Add "life_stage": "pregnancy" or "lactation" (female, 14-50) for those reference values. For infants, give age as a fraction of a year (0.25 = 3 months). Read the response in this order: 1. agent_summary: two to five plain sentences you can relay as written. 2. resolutions[]: how each {query}/{upc} was identified, with confidence (high/medium/low) and alternatives. If confidence is low, confirm the product with the user and re-run with its dsld_id. 3. suggestions[]: single-product changes that would bring an above-UL nutrient to or under its UL (reduce servings or leave a product out), with the resulting amount, best first. 4. nutrient_totals[]: per nutrient: daily_total, amount_toward_ul, percent_of_ul, flags (above_ul, near_ul), severity (high: 2x UL or more, moderate: above UL, low: within 10% of UL), coverage (percent of RDA/AI from supplements alone, informational), reference.ul_basis (what the UL protects against), and contributions per product. 5. timing[] (when present): NIH statements on when to take things (calcium in doses of 500 mg or less, calcium carbonate with a meal, calcium and iron apart, vitamin D with some fat, medication spacing). 5b. botanicals[] (when present): herbs and other non-nutrients in the stack with NIH NCCIH/ODS safety signals (liver injury, bleeding, drug interactions, banned ingredients) and dose checks (creatine, EGCG, valerian). 6. interactions (when medications or conditions were given): medications[] shows how each name was matched; findings[] lists every NIH-listed interaction, those involving a nutrient in the stack (in_stack: true) first. 7. data_gaps[]: what could not be counted, plus DATA_SUSPECT entries where the NIH label record looks inconsistent (duplicate row, nested amounts larger than the total, %DV that contradicts the amount, implausible amount). ## Other endpoints - POST /v1/products/search {"query", "brand"?, "ingredient"?, "limit"<=10, "dedupe_versions"=true}: product summaries, one per product (older label versions in other_versions). - POST /v1/products/lookup {"upc"}: the label for a barcode, newest version first. - POST /v1/products/fda {"query"} or {"upc"} or {"dsld_id"} or {"brand", "name"}: FDA recalls matching the product and CAERS adverse event report counts (reports do not show causation). - POST /v1/products/get {"dsld_id"} or {"dsld_ids": [...]}: full normalized labels. - POST /v1/interactions/check {"medications"?, "conditions"?, "nutrients"?}: NIH-listed nutrient interactions for medications or conditions, without a stack. - POST /v1/nutrients/reference {"nutrient", "age", "sex"}: RDA, EAR, AI, UL and UL basis. Offline. - POST /v1/tool {"tool", "arguments"}: one dispatcher for all of the above. "name" works in place of "tool", and {"arguments"} alone runs stack_analyze. - GET /v1/tools: tool definitions with JSON Schema inputs, ready for function calling. - Free trial: the public demo host meters calls per day (25 tool calls per MCP connection, 100 REST calls per IP; see the X-Free-Tier-Remaining header or _meta.free_tier). Relays through Pocket Network are unmetered. - POST /mcp: the same tools as a remote MCP server (Streamable HTTP); stack_analyze defaults to detail "summary" there. - GET /v1/provenance: code version, git commit and data editions behind every answer. - GET /openapi.json: OpenAPI 3.1. ## Rules for relaying results - The totals cover the listed supplements only, not food, drinks or medications. - No flag means nothing to report for that nutrient; it is not a clean bill of health. Do not tell the user a stack is harmless. - Medication interactions are checked only when medications are given, and only those named in the NIH fact sheets. No finding does not mean no interaction; suggest a pharmacist check. Supplement-to-supplement interactions are not assessed. - Every number links to its DSLD label or NIH fact sheet in sources[]. - Everything returned is information from labels and NIH and FDA data, not medical advice. Relay agent_summary in full, including its last sentence, and the disclaimer field where you show results. - For anything flagged, and always for pregnancy, children, serious illness or prescription drugs, point the user to a doctor or pharmacist. For an emergency or suspected overdose, tell them to call emergency services (911 in the US) or Poison Control (1-800-222-1222 in the US) now. - Send no names or other identifying details; the service needs only age, sex and what the person takes. Terms of use: https://github.com/chariot-ventures/dietary-supplement-analysis/blob/main/TERMS.md Docs: https://github.com/chariot-ventures/dietary-supplement-analysis#readme ## Links - Remote MCP server (no key): https://agents.trackmysupplement.com/mcp - How agents connect, pay and relay results: https://agents.trackmysupplement.com/agents.md - Guide plus every tool schema: https://agents.trackmysupplement.com/llms-full.txt - OpenAPI 3.1: https://agents.trackmysupplement.com/openapi.json - Live status, accuracy and data editions: https://agents.trackmysupplement.com/status.json - Pocket Network: service dietary-supplement-analysis, Beta TestNet, relay endpoint https://pokt-beta.trackmysupplement.com - Source and docs: https://github.com/chariot-ventures/dietary-supplement-analysis#readme - Contact: mb@chariot.ventures ## Tool schemas ### stack_analyze (POST /v1/stack/analyze) Check a list of dietary supplements for a person: per-nutrient daily totals against NIH upper limits (UL) and RDA/AI, which products overlap, what each UL protects against, and single-product changes that would bring an above-UL nutrient back under it. Products can be given as names ("Centrum Silver Women 50+"), barcodes, DSLD IDs, or custom ingredient lists; optional candidates are evaluated as additions. Pass the person's medications and conditions (smoker, kidney_disease, hemochromatosis, lab_test_soon, cancer_treatment) to check them against the interactions in the NIH fact sheets. Returns agent_summary (plain sentences to relay), resolutions, suggestions, interactions, nutrient_totals and data_gaps. Label data only; food is included only with diet "typical". ```json { "type": "object", "properties": { "age": { "type": "number", "minimum": 0, "maximum": 120, "description": "Age in years. For infants use a fraction: 0.25 = 3 months; 0-5 and 6-11 month values apply under 1." }, "sex": { "type": "string", "enum": [ "male", "female" ] }, "life_stage": { "type": "string", "enum": [ "pregnancy", "lactation" ], "description": "Pregnancy or lactation (breastfeeding) reference values; requires sex \"female\" and age 14-50" }, "detail": { "default": "full", "description": "\"summary\" returns only what an agent needs to answer (agent_summary, flagged nutrients, suggestions, resolutions, candidate verdicts), about 1-3 KB instead of 20-40 KB", "type": "string", "enum": [ "summary", "full" ] }, "lang": { "default": "en", "description": "\"es\" writes agent_summary in Spanish (the English text is kept in agent_summary_en); other fields stay in English", "type": "string", "enum": [ "en", "es" ] }, "diet": { "default": "none", "description": "\"typical\" adds the US average intake from food and drinks for this age and sex (NHANES) to estimate total intake; see with_typical_diet", "type": "string", "enum": [ "none", "typical" ] }, "products": { "minItems": 1, "maxItems": 15, "type": "array", "items": { "anyOf": [ { "type": "object", "properties": { "dsld_id": { "type": "integer", "exclusiveMinimum": 0, "maximum": 10000000, "description": "DSLD label ID, e.g. from /v1/products/search" }, "servings_per_day": { "type": "number", "exclusiveMinimum": 0, "maximum": 50, "description": "Servings taken per day. Default: the label maximum daily servings, else 1." } }, "required": [ "dsld_id" ], "additionalProperties": false }, { "type": "object", "properties": { "query": { "type": "string", "minLength": 2, "maxLength": 200, "description": "Product as the user named it, e.g. \"Centrum Silver Women 50+\". Resolved to the best-matching DSLD label; see resolutions[]" }, "brand": { "description": "Brand, if known separately", "type": "string", "minLength": 1, "maxLength": 100 }, "servings_per_day": { "type": "number", "exclusiveMinimum": 0, "maximum": 50, "description": "Servings taken per day. Default: the label maximum daily servings, else 1." } }, "required": [ "query" ], "additionalProperties": false }, { "type": "object", "properties": { "upc": { "type": "string", "minLength": 8, "maxLength": 32, "description": "UPC-A or EAN barcode digits as printed on the bottle, e.g. \"031604026974\" (spaces and dashes are ignored)" }, "servings_per_day": { "type": "number", "exclusiveMinimum": 0, "maximum": 50, "description": "Servings taken per day. Default: the label maximum daily servings, else 1." } }, "required": [ "upc" ], "additionalProperties": false }, { "type": "object", "properties": { "name": { "type": "string", "minLength": 1, "maxLength": 200 }, "servings_per_day": { "type": "number", "exclusiveMinimum": 0, "maximum": 50, "description": "Servings taken per day. Default: the label maximum daily servings, else 1." }, "ingredients": { "minItems": 1, "maxItems": 50, "type": "array", "items": { "type": "object", "properties": { "name": { "type": "string", "minLength": 1, "maxLength": 200 }, "amount": { "type": "number", "minimum": 0, "maximum": 10000000 }, "unit": { "type": "string", "minLength": 1, "maxLength": 30, "description": "mg, mcg, g, IU, mcg DFE, mcg RAE, mg NE" }, "form": { "description": "Declared form, e.g. \"folic acid\", \"retinyl palmitate\", \"d-alpha tocopherol\"", "type": "string", "minLength": 1, "maxLength": 200 }, "nutrient_basis": { "description": "For minerals: whether amount is elemental or the whole compound weight", "type": "string", "enum": [ "elemental", "compound" ] } }, "required": [ "name", "amount", "unit" ] } } }, "required": [ "ingredients" ], "additionalProperties": false } ] }, "description": "1-15 products. Each is one of: {\"dsld_id\"}, {\"query\"} (a product name, resolved server-side), {\"upc\"} (barcode), or a custom product {\"name\",\"ingredients\"}. Add \"servings_per_day\" to any of them." }, "medications": { "minItems": 1, "maxItems": 30, "type": "array", "items": { "type": "string", "minLength": 2, "maxLength": 100 }, "description": "Medications the person takes, as generic or brand names (\"warfarin\", \"Synthroid\", \"metformin 500 mg\"). Checked against the medication interactions listed in the NIH ODS fact sheets; not exhaustive. Never logged." }, "conditions": { "minItems": 1, "maxItems": 5, "type": "array", "items": { "type": "string", "enum": [ "smoker", "kidney_disease", "hemochromatosis", "lab_test_soon", "cancer_treatment" ] }, "description": "Conditions that change how NIH reads a dose: smoker (current or former, or asbestos exposure: beta-carotene), kidney_disease (potassium, magnesium, phosphorus), hemochromatosis (iron, vitamin C), lab_test_soon (biotin interferes with lab tests), cancer_treatment (antioxidant doses)" }, "foods": { "description": "Optional, up to 30: what the person eats in a day, e.g. [{\"query\":\"spinach cooked\",\"amount\":1,\"unit\":\"cup\"},{\"query\":\"whole milk\",\"grams\":488}]. Added to the supplement totals in nutrient_totals[].with_foods (USDA SR28, offline). Use instead of diet \"typical\".", "minItems": 1, "maxItems": 30, "type": "array", "items": { "type": "object", "properties": { "query": { "description": "Food as the user named it, e.g. \"spinach cooked\", \"whole milk\"; matched to a USDA SR28 food (see foods.items)", "type": "string", "minLength": 2, "maxLength": 120 }, "ndb_number": { "description": "USDA NDB number (SR Legacy), e.g. \"11458\"", "type": "string", "pattern": "^\\d{4,5}$" }, "grams": { "description": "Amount eaten per day, in grams", "type": "number", "exclusiveMinimum": 0, "maximum": 5000 }, "amount": { "description": "Amount in \"unit\" per day, e.g. 1.5 with unit \"cup\"", "type": "number", "exclusiveMinimum": 0, "maximum": 100 }, "unit": { "description": "cup, tbsp, tsp, slice, large, medium, oz, lb, kg, g, fl oz... must match a USDA portion for the food (or be a weight)", "type": "string", "minLength": 1, "maxLength": 30 } }, "additionalProperties": false } }, "candidates": { "description": "Optional, up to 5: products the user is considering adding. Each is evaluated as an addition to the stack in candidate_results[]; they are not included in nutrient_totals.", "minItems": 1, "maxItems": 5, "type": "array", "items": { "anyOf": [ { "type": "object", "properties": { "dsld_id": { "type": "integer", "exclusiveMinimum": 0, "maximum": 10000000, "description": "DSLD label ID, e.g. from /v1/products/search" }, "servings_per_day": { "type": "number", "exclusiveMinimum": 0, "maximum": 50, "description": "Servings taken per day. Default: the label maximum daily servings, else 1." } }, "required": [ "dsld_id" ], "additionalProperties": false }, { "type": "object", "properties": { "query": { "type": "string", "minLength": 2, "maxLength": 200, "description": "Product as the user named it, e.g. \"Centrum Silver Women 50+\". Resolved to the best-matching DSLD label; see resolutions[]" }, "brand": { "description": "Brand, if known separately", "type": "string", "minLength": 1, "maxLength": 100 }, "servings_per_day": { "type": "number", "exclusiveMinimum": 0, "maximum": 50, "description": "Servings taken per day. Default: the label maximum daily servings, else 1." } }, "required": [ "query" ], "additionalProperties": false }, { "type": "object", "properties": { "upc": { "type": "string", "minLength": 8, "maxLength": 32, "description": "UPC-A or EAN barcode digits as printed on the bottle, e.g. \"031604026974\" (spaces and dashes are ignored)" }, "servings_per_day": { "type": "number", "exclusiveMinimum": 0, "maximum": 50, "description": "Servings taken per day. Default: the label maximum daily servings, else 1." } }, "required": [ "upc" ], "additionalProperties": false }, { "type": "object", "properties": { "name": { "type": "string", "minLength": 1, "maxLength": 200 }, "servings_per_day": { "type": "number", "exclusiveMinimum": 0, "maximum": 50, "description": "Servings taken per day. Default: the label maximum daily servings, else 1." }, "ingredients": { "minItems": 1, "maxItems": 50, "type": "array", "items": { "type": "object", "properties": { "name": { "type": "string", "minLength": 1, "maxLength": 200 }, "amount": { "type": "number", "minimum": 0, "maximum": 10000000 }, "unit": { "type": "string", "minLength": 1, "maxLength": 30, "description": "mg, mcg, g, IU, mcg DFE, mcg RAE, mg NE" }, "form": { "description": "Declared form, e.g. \"folic acid\", \"retinyl palmitate\", \"d-alpha tocopherol\"", "type": "string", "minLength": 1, "maxLength": 200 }, "nutrient_basis": { "description": "For minerals: whether amount is elemental or the whole compound weight", "type": "string", "enum": [ "elemental", "compound" ] } }, "required": [ "name", "amount", "unit" ] } } }, "required": [ "ingredients" ], "additionalProperties": false } ] } } }, "required": [ "products" ] } ``` ### products_search (POST /v1/products/search) Search the NIH Dietary Supplement Label Database by product name, brand or ingredient. Returns up to 10 products (one per product; older label versions listed in other_versions) with DSLD IDs. ```json { "type": "object", "properties": { "query": { "description": "Free-text search, e.g. \"vitamin d3 5000\"", "type": "string", "minLength": 1, "maxLength": 200 }, "brand": { "type": "string", "minLength": 1, "maxLength": 100 }, "ingredient": { "description": "Ingredient name, e.g. \"cholecalciferol\"", "type": "string", "minLength": 1, "maxLength": 100 }, "on_market_only": { "default": true, "type": "boolean" }, "limit": { "default": 5, "type": "integer", "minimum": 1, "maximum": 10 }, "dedupe_versions": { "default": true, "description": "Collapse label versions of the same product (same brand and name) into one result, newest first; older IDs are listed in other_versions", "type": "boolean" } } } ``` ### products_lookup (POST /v1/products/lookup) Look up a supplement by the UPC/EAN barcode printed on the bottle. Returns the newest matching DSLD label, normalized, and any older versions. ```json { "type": "object", "properties": { "upc": { "type": "string", "minLength": 8, "maxLength": 32, "description": "UPC-A or EAN barcode digits as printed on the bottle, e.g. \"031604026974\" (spaces and dashes are ignored)" } }, "required": [ "upc" ], "additionalProperties": false } ``` ### products_get (POST /v1/products/get) Full normalized supplement labels by DSLD ID (up to 10): every ingredient with label amount, converted amount, form and %DV. ```json { "type": "object", "properties": { "dsld_id": { "type": "integer", "exclusiveMinimum": 0, "maximum": 10000000, "description": "DSLD label ID, e.g. from /v1/products/search" }, "dsld_ids": { "minItems": 1, "maxItems": 10, "type": "array", "items": { "type": "integer", "exclusiveMinimum": 0, "maximum": 10000000, "description": "DSLD label ID, e.g. from /v1/products/search" } } } } ``` ### interactions_check (POST /v1/interactions/check) Which vitamins and minerals interact with given medications (generic or brand names, e.g. "warfarin", "Synthroid") or conditions, per the NIH Office of Dietary Supplements fact sheets, with timing advice (e.g. take levothyroxine 4 hours apart from calcium). No product list needed; to check an actual stack, pass medications to stack_analyze instead. Not exhaustive. ```json { "type": "object", "properties": { "medications": { "minItems": 1, "maxItems": 30, "type": "array", "items": { "type": "string", "minLength": 2, "maxLength": 100 }, "description": "Medications the person takes, as generic or brand names (\"warfarin\", \"Synthroid\", \"metformin 500 mg\"). Checked against the medication interactions listed in the NIH ODS fact sheets; not exhaustive. Never logged." }, "conditions": { "minItems": 1, "maxItems": 5, "type": "array", "items": { "type": "string", "enum": [ "smoker", "kidney_disease", "hemochromatosis", "lab_test_soon", "cancer_treatment" ] }, "description": "Conditions that change how NIH reads a dose: smoker (current or former, or asbestos exposure: beta-carotene), kidney_disease (potassium, magnesium, phosphorus), hemochromatosis (iron, vitamin C), lab_test_soon (biotin interferes with lab tests), cancer_treatment (antioxidant doses)" }, "nutrients": { "description": "Optional: only report interactions involving these nutrients or botanicals (IDs or names, e.g. \"vitamin-k\", \"magnesium\", \"St. John's wort\")", "minItems": 1, "maxItems": 40, "type": "array", "items": { "type": "string", "minLength": 1, "maxLength": 100 } } }, "additionalProperties": false } ``` ### products_fda_reports (POST /v1/products/fda) FDA recalls and adverse event reports (CAERS) for one supplement, from openFDA. Give a product name, barcode, DSLD ID, or brand and name. Recalls are listed only when they carry the barcode or the brand and every product-name word; adverse event reports are counted with their most common reactions. Reports do not show that a product caused an event. ```json { "type": "object", "properties": { "dsld_id": { "type": "integer", "exclusiveMinimum": 0, "maximum": 10000000, "description": "DSLD label ID, e.g. from /v1/products/search" }, "upc": { "type": "string", "minLength": 8, "maxLength": 32, "description": "UPC-A or EAN barcode digits as printed on the bottle, e.g. \"031604026974\" (spaces and dashes are ignored)" }, "query": { "description": "Product as the user named it; resolved to a DSLD label", "type": "string", "minLength": 2, "maxLength": 200 }, "brand": { "description": "Brand (with \"name\", or to narrow \"query\")", "type": "string", "minLength": 2, "maxLength": 100 }, "name": { "description": "Product name as printed, used with \"brand\" when the product is not in DSLD", "type": "string", "minLength": 1, "maxLength": 200 } }, "additionalProperties": false } ``` ### nutrients_reference (POST /v1/nutrients/reference) NIH reference values (RDA, EAR, AI, UL) for one vitamin or mineral at a given age and sex, with what the UL protects against. Offline and instant. ```json { "type": "object", "properties": { "nutrient": { "type": "string", "minLength": 1, "maxLength": 100, "description": "Nutrient ID (\"vitamin-d\") or any synonym (\"cholecalciferol\")" }, "age": { "type": "number", "minimum": 0, "maximum": 120, "description": "Age in years. For infants use a fraction: 0.25 = 3 months; 0-5 and 6-11 month values apply under 1." }, "sex": { "type": "string", "enum": [ "male", "female" ] }, "life_stage": { "type": "string", "enum": [ "pregnancy", "lactation" ], "description": "Pregnancy or lactation (breastfeeding) reference values; requires sex \"female\" and age 14-50" } }, "required": [ "nutrient", "age", "sex" ] } ```