Salvio API
OTC product-data infrastructure: full-text product search, brand-to-generic equivalence, ingredient label analysis, and barcode resolution for the U.S. pharmacy aisle. Built for developers and AI agents.
Authentication
Pass your API key as a Bearer token in the Authorization header. Keys are prefixed sk_.
curl https://api.salvio.health/v1/products/search?q=tylenol \ -H "Authorization: Bearer sk_..."
Authorization header are served on an anonymous open tier, so every Try it panel on this page works with no key. Once keys become required, send Authorization: Bearer sk_... and unauthenticated requests will return 401.Rate limits
Keyed requests are metered per calendar month. Responses include X-RateLimit-Limit and X-RateLimit-Remaining headers; exceeding your monthly allowance returns 429.
Endpoints
Every endpoint is under the base URL above. Each is listed below with its parameters, an example response, and a live Try It panel. Prefer to explore visually? Jump to the interactive playground.
Health
Liveness probe. Returns service status, the number of active products loaded, and the API version. Always public.
Product Search
Full-text search across OTC products by brand name, generic name, active ingredient, or labeler. Homeopathic products are excluded by default. Supports filtering and pagination; returns { total, page, per_page, results }.
Product Lookup
Look up a single product by NDC code or UPC barcode. Returns full detail including active ingredients, barcodes, and FDA label data (indications, warnings, dosage, interactions) when available.
label.indications, label.warnings, label.do_not_use, label.dosage_instructions, and label.drug_interactions. These are informational restatements of FDA labeling, not advice.Equivalents
Find all products that share the same active ingredients, strength, and dosage form (for example, store-brand and generic products with the same formulation as a name brand). Store brands are sorted first, and each match carries a confidence score. “Equivalent” means matching active ingredients — not a clinical substitution recommendation.
Confidence levels
Ingredient Analysis
Analyze a list of active-ingredient strings parsed from a product label, OCR scan, or manual input. Returns an ingredient breakdown, matching products, informational safety notes drawn from FDA labeling, and suggestions. Returns { ingredients_parsed, matched_products, safety_notes, suggestions, disclaimer }.
Request body
{
"ingredients": [
"ACETAMINOPHEN 325 MG",
"DEXTROMETHORPHAN HYDROBROMIDE 10 MG",
"GUAIFENESIN 200 MG",
"PHENYLEPHRINE HYDROCHLORIDE 5 MG"
]
}ingredients field above is a convenience for this panel — type ingredient strings separated by commas and Salvio sends them as a JSON array { "ingredients": [...] }.Safety note structure
Every safety note carries recommendation_type: "informational_only". This is FDA label data, not medical advice.
{
"ingredient": "ACETAMINOPHEN",
"label_warning_present": true,
"warning_category": "liver",
"source": "FDA label",
"consumer_summary": "This product contains acetaminophen...",
"recommendation_type": "informational_only"
}Suggestion types
Ingredient Search
Search the catalog of canonical active-ingredient names. Use this to resolve a user-typed name (e.g. “tylenol” or a misspelling) to the canonical ingredient before calling /ingredients/{name}/products. Each match carries its purpose, therapeutic class, RxNorm identifier, and an informational label-safety note where one exists. Returns { total, ingredients }.
{
"total": 1,
"ingredients": [{
"name": "ACETAMINOPHEN",
"purpose": "Pain reliever / fever reducer",
"safety_note": "Liver warning: contains acetaminophen...",
"therapeutic_class": "Analgesic / antipyretic",
"rxcui": "161"
}]
}Products by Ingredient
The core cross-linking primitive: every product whose active ingredients include the named ingredient, with relationship filters for dose, composition (sole active vs. combination), and labeler. The response also returns the distinct doses the ingredient appears at (available_strengths) so you can build a dose picker, plus per-product allergen_flags. Returns { ingredient, query, available_strengths, total, page, per_page, results }.
{
"ingredient": {
"name": "IBUPROFEN",
"purpose": "Pain reliever / fever reducer (NSAID)",
"therapeutic_class": "NSAID",
"rxcui": "5640"
},
"query": {
"resolved_name": "IBUPROFEN",
"strength": "200 mg",
"composition": "single",
"free_of": ["gluten"],
"contains_allergen": []
},
"available_strengths": [
{ "strength": "200 mg", "product_count": 412 },
{ "strength": "400 mg", "product_count": 88 }
],
"total": 412,
"page": 1,
"per_page": 20,
"results": [{
"product_ndc": "0573-0150",
"brand_name": "ADVIL",
"generic_name": "IBUPROFEN",
"labeler_type": "name_brand",
"dosage_form": "TABLET, COATED",
"this_ingredient_strength": "200 mg",
"active_ingredient_count": 1,
"is_combination": false,
"allergen_flags": ["dye"]
}]
}allergen_flags lists allergen codes detected in a product’s FDA-listed inactive ingredients. Coverage is partial — only ~55% of products have inactive-ingredient data on file. When a product has no inactive-ingredient data, allergen_flags is null (status unknown) rather than an empty list, and the free_of filter excludes those products entirely — so “free of” is never falsely asserted. This is informational product data, not a guarantee of safety for any individual.Allergens
The catalog of allergens and sensitivities Salvio tracks, each with the number of products known to contain it. Use the returned code values with the free_of and contains_allergen filters on /ingredients/{name}/products. Returns { total, allergens }.
{
"total": 12,
"allergens": [
{ "code": "dye", "label": "Artificial dyes / colors", "product_count": 5821 },
{ "code": "gluten", "label": "Gluten (wheat)", "product_count": 1043 },
{ "code": "lactose", "label": "Lactose", "product_count": 2310 },
{ "code": "gelatin", "label": "Gelatin (animal-derived)", "product_count": 1487 }
]
}product_count reflects products where the allergen was detected; it is not an exhaustive count. Treat this as informational product data, not medical or dietary advice.Symptoms
The symptom-to-ingredient mapping: for each of 20 common symptom ids, the active ingredients that FDA OTC monographs or FDA-approved OTC labeling list for that indication — with regulatory sources, informational flags, typical label age minimums, and pediatric availability. /symptoms lists the taxonomy and the selectable age ranges; /symptoms/{id} returns one symptom’s ingredients (filter with an age_band= range id — the recommended way — or an exact age= in years); /symptoms/{id}/products joins each qualifying ingredient out to its catalog products (line=primary|all, labeler_type, free_of, per_page per ingredient, max 25).
{
"symptom_id": "fever",
"label": "Fever",
"ingredients": [
{
"canonical_name": "ACETAMINOPHEN",
"display_name": "Acetaminophen",
"therapeutic_class": "Antipyretic",
"line": "primary",
"regulatory_source": "FDA OTC Monograph M013",
"flags": ["APAP_LIVER"],
"age_labeling": { "min_age_years": 2, "under_age_guidance": "ask_doctor" }
}
],
"age_filter_applied": 4,
"excluded_by_age": 2,
"flag_definitions": { "APAP_LIVER": "Acetaminophen liver warning; ..." }
}Barcode Scan
Resolve a product by UPC (12-digit) or EAN (13-digit) barcode. Returns product detail plus a resolution object with the match source and a confidence score.
{
"resolution": {
"source": "openfda",
"confidence_score": 0.95,
"barcode_format": "UPC",
"last_verified_at": "2026-05-18T00:00:00Z"
}
}404. Fall back to /products/search?q=... by product name.Equivalence Groups
Browse precomputed equivalence groups — sets of products sharing the same active ingredients, strength, and dosage form, ordered by member count. Useful for discovering which OTC products have the most generic and store-brand alternatives. Filter with min_members and paginate with page / per_page.
{
"total": 2847,
"results": [{
"equivalence_hash": "a3f7b2c1e8d94f01",
"ingredient_signature": "ACETAMINOPHEN 500 mg [TABLET]",
"member_count": 665,
"confidence_level": "exact",
"store_brand_count": 245,
"name_brand_count": 12,
"generic_count": 408
}]
}Categories
List the OTC product categories Salvio recognizes (for example, pain relief, cough and cold, allergy). Returns { categories }.
Stats
Dataset summary statistics — counts of products, ingredients, equivalence groups, and label coverage across the corpus.
Interactive playground
Explore the ingredient graph without writing any code. Search by ingredient and filter by dose, composition, labeler, and “free of” allergen — or search by product and pivot into its active ingredients. Every interaction is a live call to the same endpoints documented above (/ingredients/{name}/products, /products/search, /allergens).
Authorization: Bearer sk_....DemoResults are limited to 5 — the full explorer (all matches) is for signed-in users.
Informational product data only, from FDA labeling. “Equivalent” = same active ingredients, strength, and dosage form — not a clinical substitution recommendation. Allergen coverage is partial: only ~55% of products have inactive-ingredient data on file. Products without it show “inactive ingredients not on file” and are never reported as “free of” anything.
Agents & MCP
Salvio is built to be consumed by AI agents as well as applications. Three machine-readable surfaces make the API discoverable.
MCP server
The Salvio MCP server (salvio-mcp-server) is a remote, stateless Streamable HTTP endpoint at /api/mcp. Point any MCP-capable client at that URL. All twelve tools are read-only.
{
"mcpServers": {
"salvio": {
"type": "streamable-http",
"url": "https://api.salvio.health/api/mcp"
}
}
}