API Documentation
API documentation in one paragraph
These docs cover authentication, rate limits, all six endpoints, and response shapes for the ProcedureRadar B2B API. Every endpoint returns normalized, quality-scored procedure-pricing data across the top 100 US metros, from two federally mandated sources: hospital machine-readable files under 45 CFR Part 180, and payer-published Transparency in Coverage rates at Scale and above, some from one employer group's file.
These docs are written by us and reviewed every release, so what you read here is what the API actually does. We cover authentication, every endpoint, every parameter, and real response examples. Most teams have a working integration in under a day, which is the bar we hold ourselves to on every release.
Authentication
The ProcedureRadar API authenticates with an API key passed in the X-API-Key header on every request.
curl -H "X-API-Key: YOUR_API_KEY" \ "https://procedureradar.com/api/v1/procedures"
Replace YOUR_API_KEY with your live key (it looks like pr_live_...). Apply for a key from the developer portal. Keep it secret; never commit it or expose it in client-side code.
Base URL
All 6 endpoints are relative to this base URL. Every successful response is a JSON envelope: list endpoints return { success, data, pagination, meta } and single-object endpoints return { success, data, meta }.
Procedures
GET /proceduresList procedures with typical price ranges. Starter and Growth keys see shoppable procedures only;shoppable_only=false requires Scale tier or higher.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| page | integer | Page number (default: 1) |
| limit | integer | Results per page (default: 50, max: 200) |
| search | string | Match on procedure name (max 100 chars) |
| category | string | imaging, surgery, obstetric, diagnostic, preventive, emergency, lab, other |
| shoppable_only | boolean | Default true. false requires Scale tier or higher |
Example Request
curl -H "X-API-Key: YOUR_API_KEY" \ "https://procedureradar.com/api/v1/procedures?limit=10&search=knee"
Example Response
{
"success": true,
"data": [
{
"id": "a1b2c3d4-0000-4000-8000-000000000000",
"slug": "knee-replacement",
"display_name": "Knee Replacement (Total)",
"category": "surgery",
"description": "Total knee arthroplasty",
"is_shoppable": true,
"hcpcs_code": "27447",
"drg_code": "470",
"typical_price_range": {
"p25": "24850.00",
"p50": "31200.00",
"p75": "39600.00",
"sample_size": 142
},
"last_updated": "2026-05-01"
}
],
"pagination": { "page": 1, "limit": 10, "total": 108, "pages": 11, "has_next": true, "has_previous": false },
"meta": { "timestamp": "2026-06-13T00:00:00.000Z", "version": "1.0.0" }
}Pricing
GET /pricingUnderwriting-grade pricing rows for one procedure, scoped to a metro or a single hospital. Base fields are returned on every tier. Cohort-derived severity statistics (percentiles 25 to 99, mean, standard deviation) are available from Starter when the cohort supports them, and confidence intervals are available from Growth (the mean-price bounds plus per-percentile BCa bounds for p25, p75, p95, and p99). The base price field is the hospital's own posted price. It is populated only on rows whose quality_flag is low_sample, and it is null on cohort rows. Every row on every tier also carries three provenance fields: data_source, setting, and billing_class. Served rows are hospital MRF data (data_source is hospital_mrf) or payer-published negotiated rates (data_source is payer_tic), served at Scale, Enterprise, and Custom tiers, where scope varies by payer: some payer rates come from network-wide files and some from a single large employer group's rate file, as the methodology page documents per payer. setting and billing_class are null where the source file does not state them. Scale and above also carry five variant span fields: variant_price_low and variant_price_high (the range across the billing codes that make up the cell), variant_count (how many codes), variant_flag (the write-time trust verdict), and variant_basis (whether the codes were told apart by catalog code or by matched description). The three price fields are null when variant_flag is not ok. When variant_count is 2 or more, read median_price carefully: it is the median across those constituent billing codes, not a utilization-weighted expected cost. Utilization weighting needs encounter frequency, which is the frequency_estimate_per_1k field that is not yet populated. Use variant_price_low and variant_price_high to see the spread that median collapses. The higher-tier fields (time-series at Scale, covered-event and frequency at Enterprise) are on the roadmap and are documented but not yet populated; they return null (an empty array for covered_event_codes) on every row until the backing data ships. The example below shows a Growth-tier cohort row.
Field availability. Rows do not all carry cohort statistics. When quality_flag is low_sample, the row carries the hospital's posted price and all cohort-derived statistics are null. On cohort rows, price is null, and the derived fields populate only when enough hospitals reported at the procedure, metro, payer, charge type, and setting grain. sample_size is the count of reporting hospitals at that grain and may also be null. sample_regime tells you which of the three states a row is in, so you never have to guess why a field is null. full means 30 or more reporting hospitals: the percentile ladder is empirical and the BCa confidence intervals are served. small_sample means 10 to 29: you get median_price, sample_size, mean_price, stdev_price and the mean confidence interval, and the percentile ladder is withheld because below 30 observations those percentiles would be extrapolated from the mean and standard deviation rather than measured, and on skewed price data an extrapolated quartile can land on the wrong side of the measured median. suppressed means fewer than 10: no cohort statistic is computable and you get the hospital's own posted price instead. On payer_tic rows sample_regime is null, because sample_size there reports an allowed-amount count rather than a severity cohort. See the methodology white-paper for the sample-size thresholds and known limitations. This is different from the roadmap fields above (time_series_normalized, covered_event_codes, frequency_estimate_per_1k), which return null (an empty array for covered_event_codes) on every row regardless of cohort size because the backing data has not shipped yet, not because the cohort is thin.
Query Parameters
| Parameter | Type | Required |
|---|---|---|
| procedure | string (slug) | Yes |
| metro | string (slug) | metro or hospital_id |
| hospital_id | string (uuid) | metro or hospital_id |
| payer_type | string | No |
| page / limit | integer | No |
Example Request
curl -H "X-API-Key: YOUR_API_KEY" \ "https://procedureradar.com/api/v1/pricing?procedure=ct-scan-abdomen&metro=dallas-fort-worth"
Example Response (Growth tier)
{
"success": true,
"data": [
{
"tier": "growth",
"hospital_name": "UT Southwestern Medical Center",
"procedure_slug": "ct-scan-abdomen",
"procedure_display_name": "CT Scan, Abdomen",
"payer_type": "cash",
"charge_type": "cash",
"price": null,
"gross_charge": null,
"cash_pay": null,
"median_price": 1640.00,
"percentile_10": 920.00,
"percentile_25": 1180.00,
"percentile_75": 2240.00,
"percentile_90": 2870.00,
"percentile_95": 3050.00,
"percentile_99": 3300.00,
"mean_price": 1710.00,
"stdev_price": 612.00,
"ci_lower_bound": 1520.00,
"ci_upper_bound": 1760.00,
"confidence_lower_p25": 1090.00,
"confidence_upper_p25": 1270.00,
"confidence_lower_p75": 2080.00,
"confidence_upper_p75": 2400.00,
"confidence_lower_p95": 2850.00,
"confidence_upper_p95": 3250.00,
"confidence_lower_p99": 3050.00,
"confidence_upper_p99": 3550.00,
"sample_size": 38,
"quality_flag": "verified",
"sample_regime": "full",
"last_updated": "2026-05-01",
"source_mrf_url": "https://www.utsouthwestern.edu/.../standardcharges.json",
"source_publication_date": "2026-04-15",
"data_source": "hospital_mrf",
"setting": null,
"billing_class": null,
"methodology_url": "https://procedureradar.com/methodology"
}
],
"pagination": { "page": 1, "limit": 50, "total": 22, "pages": 1, "has_next": false, "has_previous": false },
"meta": { "timestamp": "2026-06-13T00:00:00.000Z", "version": "1.0.0", "tier": "growth", "granularity_state": "exact" }
}Hospitals
GET /hospitalsGET /hospitals/{id_or_slug}List hospitals (filter by metro, state, name, has_pricing_data), or fetch one hospital by UUID or slug. The single-hospital response adds a quality score_breakdown (coverage, completeness, freshness, payer_count).
Example Response (single hospital)
{
"success": true,
"data": {
"id": "0000aaaa-0000-4000-8000-000000000000",
"slug": "ut-southwestern-medical-center",
"name": "UT Southwestern Medical Center",
"cms_id": "450656",
"metro": "dallas-fort-worth",
"city": "Dallas",
"state": "TX",
"zip": "75390",
"hospital_type": "Acute Care",
"beds": 741,
"transparency_score": 0.86,
"score_breakdown": { "coverage": 0.91, "completeness": 0.83, "freshness": 0.78, "payer_count": 14 },
"procedures_available": 96,
"latest_mrf_published_at": "2026-04-15",
"source_mrf_url": null,
"last_updated": "2026-05-01"
},
"meta": { "timestamp": "2026-06-13T00:00:00.000Z", "version": "1.0.0" }
}Compare
GET /compareSide-by-side price comparison for one procedure across 2 to 5 hospitals. Required: hospitals (comma-separated slugs or UUIDs) and procedure (slug). Optional payer_type is one of cash, commercial, medicare, medicaid (default cash).
Example Request
curl -H "X-API-Key: YOUR_API_KEY" \ "https://procedureradar.com/api/v1/compare?procedure=mri-knee&hospitals=hospital-a,hospital-b&payer_type=cash"
Metros
GET /metrosList the metros your subscription covers, each with population, hospital count, and procedure coverage. Takes no parameters; results are scoped to your tier.
{
"success": true,
"data": [
{ "slug": "dallas-fort-worth", "display_name": "Dallas-Fort Worth", "state": "TX", "population": 7637387, "hospitals_available": 41, "procedures_covered": 96 }
],
"meta": { "timestamp": "2026-06-13T00:00:00.000Z", "version": "1.0.0", "total_metros_available": 100 }
}Error Handling
Errors return a standard HTTP status and a JSON body of the form { "error": { "message", "code" }, "timestamp", "version" }.
Rate Limiting
Requests are rate limited by tier. Every response carries the current usage in headers.
Rate Limit Headers
X-RateLimit-Limit: 300X-RateLimit-Remaining: 299X-RateLimit-Reset: 1616000000Frequently Asked Questions
How do I authenticate with the ProcedureRadar API?
Pass your API key in the X-API-Key header on every request. Keys are issued when you subscribe to any tier starting at $999 per month.
What is the base URL for the ProcedureRadar API?
The production base URL is https://procedureradar.com/api/v1. Every endpoint lives under it.
What rate limits apply?
Rate limits depend on your tier. Starter is 60 requests per minute, Growth is 300, Scale is 1,200, and Enterprise is 3,000. Monthly request quotas also apply per tier. Every response carries X-RateLimit-* headers reflecting current usage.
API documentation reflects the current production specification.
Documentation reviewed:
We're accepting applications for API access.
Apply for API Access