Every API here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for apis
7 MCP tools reach this
find_apisBrowse and filter every API in the catalog.
get_api_artifactsOne API's artifacts, grouped by type.
get_openapiThe primary OpenAPI for this API.
find_similar_apisAPIs that look like this one.
apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
resolveTurn a domain, URL or GitHub org into the provider it belongs to.
find_cohortsEvery scored population of providers in the catalog.
All 92 tools →
Call it yourself
curl for this page
This API
curl "https://apis.io/api/v1/apis/ticexplorer-com:ticexplorer-com-analytics-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Get an API key
Free tier, no form to fill in. Signing in shares your email address with us — we
store it to create your key and to recognise you if you sign in with another
provider. See our Privacy Policy and
Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: TiC Explorer Analytics API
description: '**TiC Explorer** — negotiated health-care prices from **Transparency in Coverage** files (every in-network rate a plan pays each
billing entity), Original Medicare fee schedules and, as a secondary source, hospitals'' own price files (each hospital''s
posted rate per payer/plan as it wrote them, mostly facility charges, and its discounted cash price) — with the billing
semantics needed to use them correctly: allowed vs billed vs patient share, global vs 26/TC, office vs facility rates, hospital outpatient APC
case rates and packaging, placeholders and percent-of-charges contracts, and per-row provenance.
**Start with** `GET /v1/guide` (billing mechanics, field dictionary, worked examples) and `GET /v1/workflows`.
**Auth:** `Authorization: Bearer `. Get a key in the console at https://ticexplorer.com/dashboard/keys (self-hosted:
`python -m api keys create` or `POST /v1/admin/keys`). The MCP endpoint `https://api.ticexplorer.com/mcp` accepts the same API keys
or OAuth 2.1 access tokens, e.g. `claude mcp add --transport http ticexplorer https://api.ticexplorer.com/mcp`.
**Conventions:** list responses are `{"data": [...], "next_cursor": ...}` (pass `cursor`); errors are
`{"error": {"code", "message", "hint"}}`; every response has `X-Request-Id`, `X-RateLimit-Limit`,
`X-RateLimit-Remaining`, `X-RateLimit-Reset`. Responses carry `needs` (missing inputs that change the answer) and
`next_steps`.'
version: 0.3.0
servers:
- url: /
tags:
- name: Analytics
description: 'Market analytics: rate distributions per insurer across all providers in an area (scoped, just-in-time, async jobs).'
paths:
/v1/analytics/estimate:
post:
tags:
- Analytics
summary: 'Preflight a market analysis: files, time, price'
description: 'Resolve codes x geography x payers to the rate files that must be read (warm = already indexed; cold = indexed just in
time), with the estimated time and price. Nothing is started.
**Workflows**
Workflow `market-analysis`, step 2/4 `estimate`: Aggregate rate statistics for services across insurers and all providers in an area (benchmarking, research, negotiation prep, exports).
- Purpose: Preflight - files needed (warm vs cold), estimated seconds and usage charge, limit violations (a narrower scope removes them).
- Call after: `find_codes`
- Next: `start_market_analysis`'
operationId: estimate_market_analysis
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/AnalyticsRequest'
required: true
responses:
'200':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/Open'
'400':
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'402':
description: Payment Required
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: Not Found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'422':
description: Unprocessable Entity
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
description: Too Many Requests
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
security:
- HTTPBearer: []
/v1/analytics/jobs:
post:
tags:
- Analytics
summary: Start a market analysis (async job)
description: 'Starts the analysis and returns the job (poll GET /v1/analytics/jobs/{job_id}). 409 price_confirmation_required when the
high estimate exceeds max_price_usd (default $1); 402 when the prepaid balance cannot hold the high estimate (only the
actual price is charged when the job ends; the rest of the hold goes back); 429 when the account
already has two analyses running and two queued.
**Workflows**
Workflow `market-analysis`, step 3/4 `start`: Aggregate rate statistics for services across insurers and all providers in an area (benchmarking, research, negotiation prep, exports).
- Purpose: Starts the job with the same inputs (409 price_confirmation_required = high estimate above max_price_usd).
- Call after: `estimate_market_analysis`
- Next: `get_market_analysis`'
operationId: start_market_analysis
security:
- HTTPBearer: []
parameters:
- name: wait_seconds
in: query
required: false
schema:
type: integer
maximum: 120
minimum: 0
description: Wait up to this long for the job to finish before answering (0 = return the job at once).
default: 0
title: Wait Seconds
description: Wait up to this long for the job to finish before answering (0 = return the job at once).
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/AnalyticsRequest'
responses:
'202':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/Open'
'400':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Bad Request
'401':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Unauthorized
'402':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Payment Required
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Forbidden
'404':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Not Found
'422':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Unprocessable Entity
'429':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Too Many Requests
'409':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Conflict
'410':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Gone
get:
tags:
- Analytics
summary: This account's analyses (this server process)
operationId: list_market_analyses
security:
- HTTPBearer: []
responses:
'200':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/Open'
'400':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Bad Request
'401':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Unauthorized
'402':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Payment Required
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Forbidden
'404':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Not Found
'422':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Unprocessable Entity
'429':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Too Many Requests
/v1/analytics/jobs/{job_id}:
get:
tags:
- Analytics
summary: Progress and (partial) results of a market analysis
operationId: get_market_analysis
security:
- HTTPBearer: []
parameters:
- name: job_id
in: path
required: true
schema:
type: string
title: Job Id
- name: wait_seconds
in: query
required: false
schema:
type: integer
maximum: 120
minimum: 0
description: 'Long-poll: wait up to this long for the job to finish.'
default: 0
title: Wait Seconds
description: 'Long-poll: wait up to this long for the job to finish.'
responses:
'200':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/Open'
'400':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Bad Request
'401':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Unauthorized
'402':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Payment Required
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Forbidden
'404':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Not Found
'422':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Unprocessable Entity
'429':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Too Many Requests
'410':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Gone
description: '**Workflows**
Workflow `market-analysis`, step 4/4 `results`: Aggregate rate statistics for services across insurers and all providers in an area (benchmarking, research, negotiation prep, exports).
- Purpose: Polls until status is done or partial; medians and p10-p90 per group, exclusions and coverage.gaps.
- Call after: `start_market_analysis`'
delete:
tags:
- Analytics
summary: Cancel a market analysis (results read so far are kept)
operationId: cancel_market_analysis
security:
- HTTPBearer: []
parameters:
- name: job_id
in: path
required: true
schema:
type: string
title: Job Id
responses:
'200':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/Open'
'400':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Bad Request
'401':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Unauthorized
'402':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Payment Required
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Forbidden
'404':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Not Found
'422':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Unprocessable Entity
'429':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Too Many Requests
/v1/analytics/jobs/{job_id}/export:
get:
tags:
- Analytics
summary: Every underlying rate row of an analysis as CSV or Parquet (codes only, no…
operationId: export_market_analysis
security:
- HTTPBearer: []
parameters:
- name: job_id
in: path
required: true
schema:
type: string
title: Job Id
- name: format
in: query
required: false
schema:
enum:
- csv
- parquet
type: string
default: csv
title: Format
responses:
'200':
description: Successful Response
content:
application/json:
schema: {}
text/csv: {}
application/vnd.apache.parquet: {}
'400':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Bad Request
'401':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Unauthorized
'402':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Payment Required
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Forbidden
'404':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Not Found
'422':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Unprocessable Entity
'429':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Too Many Requests
components:
schemas:
Open:
properties: {}
additionalProperties: true
type: object
title: Open
ErrorBody:
properties:
code:
type: string
title: Code
description: Stable machine-readable error code, e.g. plan_not_found, invalid_zip, unauthorized.
message:
type: string
title: Message
hint:
type: string
title: Hint
default: ''
type: object
required:
- code
- message
title: ErrorBody
Error:
properties:
error:
$ref: '#/components/schemas/ErrorBody'
type: object
required:
- error
title: Error
Geography:
properties:
zip:
anyOf:
- type: string
- type: 'null'
title: Zip
description: 5-digit ZIP at the center of a radius, e.g. 98052.
examples:
- '98052'
miles:
anyOf:
- type: number
maximum: 100.0
minimum: 1.0
- type: 'null'
title: Miles
description: Radius around zip in miles (default 25).
metro:
anyOf:
- type: string
- type: 'null'
title: Metro
description: Metro area name as in CMS CBSA names, e.g. "Seattle", "Tacoma", "Denver-Aurora" (a CBSA / metropolitan division).
cbsa:
anyOf:
- type: string
- type: 'null'
title: Cbsa
description: CBSA or metropolitan-division code, e.g. 42644 (Seattle-Bellevue-Kent, WA).
state:
anyOf:
- type: string
- type: 'null'
title: State
description: '2-letter state, e.g. WA (large: slower and costlier than a metro or a radius).'
type: object
title: Geography
description: 'The market: one of zip (+ miles), metro, cbsa or state.'
AnalyticsRequest:
properties:
codes:
items:
type: string
type: array
maxItems: 20
minItems: 1
title: Codes
description: 1-20 CPT/HCPCS codes from find_codes. Codes that hospitals are paid per APC also bring in the hospitals' APC case rates.
geography:
$ref: '#/components/schemas/Geography'
payers:
items:
type: string
type: array
title: Payers
description: Insurer names as people say them ("Premera", "Aetna", "Regence", "UnitedHealthcare", "Cigna", "Kaiser"), catalog payer ids, or ["major"] = the largest insurers in this market (major_payers of them).
major_payers:
type: integer
maximum: 8.0
minimum: 1.0
title: Major Payers
description: How many insurers "major" means.
default: 5
files_per_payer:
type: integer
maximum: 40.0
minimum: 1.0
title: Files Per Payer
description: Most rate files read per insurer (in-area and most-used files first). More = more coverage, more first-time indexing (time, price).
default: 8
index_new_files:
type: boolean
title: Index New Files
description: false = read only files that are already indexed (fast, nearly free; coverage may be lower). true = also index the in-scope files that are not yet indexed.
default: true
providers:
type: string
enum:
- relevant
- all
title: Providers
description: relevant = billing entities with evidence they provide the service (Medicare billing for the code, facility, hospital APC); all = also entities that merely hold a contracted rate.
default: relevant
include_providers:
type: boolean
title: Include Providers
description: Add the least / most expensive billing entities (name, TIN, site address, miles) to each result group.
default: false
providers_per_group:
type: integer
maximum: 25.0
minimum: 1.0
title: Providers Per Group
default: 5
max_price_usd:
anyOf:
- type: number
minimum: 0.0
- type: 'null'
title: Max Price Usd
description: Highest estimated usage charge (USD) the job may start with (default $1.00); above it the job is not started (409 price_confirmation_required).
type: object
required:
- codes
- geography
title: AnalyticsRequest
securitySchemes:
HTTPBearer:
type: http
description: API key (tic_live_...) or OAuth access token.
scheme: bearer
oauth2:
type: oauth2
description: OAuth 2.1 (authorization code + PKCE) for MCP clients; see /.well-known/oauth-authorization-server
flows:
authorizationCode:
authorizationUrl: /authorize
tokenUrl: /token
scopes:
read: Query prices
x-workflow-renderer: builtin