Query real US hospital prices — negotiated insurance rates, cash discounts, and gross charges — from CMS-mandated machine-readable files.
Base URL: https://data.medrates.fyi
All endpoints return JSON. No API key is required for basic use (see Authentication for higher rate limits).
The fastest way to answer "how much does X cost?" is the NLP search:
bash
curl -X POST https://data.medrates.fyi/api/search/nlp/grouped \
-H "Content-Type: application/json" \
-d '{"query": "brain MRI near San Jose with Blue Cross PPO"}'
For exact code lookups with multi-hospital price comparison:
bash
curl "https://data.medrates.fyi/api/price-quote?codes=70551,70552&lat=37.33&lng=-121.89&payer=Blue+Cross&plan_type=PPO"
This data covers US hospitals only — prices published by licensed US hospitals under the Hospital Price Transparency Rule. It does not include prices from:
For outpatient procedures (MRIs, CTs, colonoscopies, minor surgeries), independent freestanding facilities often charge significantly less than hospital outpatient departments. When presenting hospital prices to users, note that non-hospital alternatives may exist at lower cost.
POST /api/search/nlp/grouped#Best for: Answering questions in plain English. Resolves procedure names to codes, geocodes cities, and groups results by billing code.
Request body (JSON):
FieldTypeRequiredDescriptionquerystringyesNatural language, e.g. "knee replacement in Palo Alto with Aetna PPO"latfloatnoPatient latitude (improves geo-sorting)lngfloatnoPatient longituderadius_milesfloatnoGeo cutoff in milespayerstringnoInsurance company name, e.g. "Blue Cross", "Aetna"plan_typestringnoPlan type, e.g. "PPO", "HMO"plan_namestringnoExact plan name for precise matchingsettingstringno"inpatient" or "outpatient"code_typestringno"CPT", "HCPCS", or "MS-DRG"codesstring[]noPre-resolved codes (skips LLM extraction — faster)procedurestringnoPre-extracted procedure name (skips LLM extraction)codes_per_pageintnoCode groups per page (default 10, max 50)hospitals_per_codeintnoHospitals per code group (default 5, max 20)pageintnoPage number for pagination (default 1)
Response: Groups of results by billing code, each with a list of hospitals sorted by price. Includes extracted (what the NLP parsed), resolved (codes found), and groups[] with hospital pricing.
Pro tip: If you already know the CPT codes, pass them in codes to skip the LLM extraction step — it's faster and uses less rate limit budget.
GET /api/price-quote#Best for: Precise multi-code cost estimates at nearby hospitals. Returns per-hospital totals.
ParamTypeRequiredDescriptioncodesstringyesComma-separated CPT/HCPCS codes, e.g. "70551,70552,70553"latfloatyesPatient latitudelngfloatyesPatient longituderadius_milesfloatnoSearch radius (default 25)payerstringnoInsurance payer nameplan_categorystringnoPlan category filter: "Commercial", "Medicare", "Medicaid", or "Other"plan_typestringnoPlan type, e.g. "PPO", "HMO", "EPO"plan_namestringnoExact plan namedrg_codesstringnoComma-separated MS-DRG codes for inpatient bundled pricinginclude_bundleboolnoInclude ancillary codes (anesthesia, facility fees) in estimatelimitintnoMax hospitals (default 5)
Response: Hospitals sorted by total_estimate (cheapest first). Each hospital has items[] with per-code prices, total_estimate, distance_miles, and in_network status. Negotiated/estimated-rate items include plan_category (Commercial, Medicare, Medicaid, Other) when a payer is specified; cash/standard-charge-only items will not have this field.
GET /api/search#Best for: Direct code lookups or keyword searches when you already know the CPT/HCPCS code.
ParamTypeRequiredDescriptionqstringyesCode (e.g. "70551") or keyword (e.g. "MRI brain"). Min 2 chars.code_typestringno"CPT", "HCPCS", "MS-DRG"hospital_idintnoFilter to a specific hospitalpayer_namestringnoFilter by payer nameplan_namestringnoFilter by exact plan namesettingstringno"inpatient" or "outpatient"zip_codestringnoUS ZIP code for geo filteringlatfloatnoLatitude for geo-sortinglngfloatnoLongitude for geo-sortingradius_milesfloatnoRadius cutoffpageintnoPage number (default 1)page_sizeintnoResults per page (default 100)
Response: Flat list of charge items with gross_charge, discounted_cash_price, min_negotiated_rate, max_negotiated_rate, hospital info, and optional payer_rate when filtered by payer.
GET /api/hospitals#Returns all hospitals with campus locations and coordinates. Use hospital IDs to filter other endpoints.
GET /api/payers#Returns all insurance payer + plan combinations. Optional ?hospital_id=N to filter by hospital.
GET /api/stats/public#Returns database summary: hospital count, procedure count, plan count, covered states.
When presenting results to users, link to the web UI for visual exploration:
https://data.medrates.fyi/code/{CODE_TYPE}/{CODE} (e.g. /code/CPT/70551)https://data.medrates.fyi/search?q={QUERY}https://data.medrates.fyi/hospitalsUser asks a vague question (e.g. "how much is an MRI?"):
Use POST /api/search/nlp/grouped with their query. Include lat/ lng if you know their location.
User has specific codes (e.g. "price for CPT 27447"):
Use GET /api/price-quote with codes=27447 and their coordinates.
User wants to compare insurance plans:
First call GET /api/payers to find available plans, then use price_quote or search/nlp/grouped with the payer/plan filters.
User asks about a specific hospital:
Call GET /api/hospitals to find the hospital ID, then use GET /api/search with hospital_id.
All endpoints work without authentication. Anonymous rate limits are sufficient for casual use.
TierLimitEndpointsStandard30/min/api/searchExpensive10/min/api/search/nlp, /api/search/nlp/groupedLanding20/min/api/price-quoteUtility15/min/api/hospitals, /api/payers, /api/stats/public
If you hit rate limits, your human should request an API access token by emailing hello@medrates.fyi or visiting medrates.fyi/api-access.
Once you have a JWT token, include it in requests:
text
Authorization: Bearer <token>
Authenticated users get significantly higher rate limits (e.g. 200/min standard, 60/min expensive) based on their plan. The token's rate_limit claim determines the multiplier applied to each tier.
All responses include standard rate limit headers:
X-RateLimit-Limit — requests allowed in the windowX-RateLimit-Remaining — requests leftX-RateLimit-Reset — seconds until the window resetsRetry-After — seconds to wait (only on 429 responses)When you receive a 429 Too Many Requests response, wait for the Retry-After period. If you're consistently rate-limited, ask your human to request API access.
gross_charge is the hospital's list price (chargemaster)discounted_cash_price is what uninsured patients paymin_negotiated_rate / max_negotiated_rate are the range across all insurerspayer_rate is the specific negotiated rate