{"openapi":"3.1.0","info":{"title":"ProviderSignal API","description":"Healthcare market intelligence API. Unified provider directory + acquisition signals + license-events feed across all 50 US states, derived from NPI + state dental boards + CMS Medicare + OIG LEIE + state Medicaid + HRSA HPSA designations. All responses ship a citation envelope (`meta.envelope_version`, `meta.source_attribution`, `meta.request`) so agents can verify source freshness without out-of-band validation. Paid `/api/v1/agent/*` endpoints accept two per-call rails on a single 402: x402 (USDC on Base mainnet) and MPP (Stripe card via a Shared Payment Token), plus Bearer-token subscription auth for existing API keys. See [/docs/agent-payments](/docs/agent-payments) for the full flow. See [/docs/fields](/docs/fields) for the field glossary and [/llms.txt](/llms.txt) for the LLM crawler index.","version":"1.0.0","contact":{"name":"ProviderSignal Support","email":"support@providersignal.com","url":"https://providersignal.com/contact"},"license":{"name":"Proprietary — Per-call billing rails available via /pricing","url":"https://providersignal.com/pricing"},"termsOfService":"https://providersignal.com/terms"},"servers":[{"url":"https://providersignal.com","description":"Production"}],"security":[{"apiKey":[]},{"sessionCookie":[]}],"tags":[{"name":"Free Tier","description":"Public no-auth evaluation endpoints — Phase 2 free-tier"},{"name":"Stats","description":"Aggregate counts for dashboard + landing page"},{"name":"Providers","description":"Provider directory + scoring"},{"name":"Reimbursement","description":"CMS + state Medicaid fee schedules"},{"name":"Demographics","description":"ZIP-level Census ACS data"},{"name":"NPDB","description":"National Practitioner Data Bank aggregate stats"},{"name":"Geospatial","description":"Map overlays (CMS billing, HPSA shortage areas)"}],"paths":{"/api/v1/free/lookup":{"get":{"summary":"NPI lookup (free tier, no auth)","description":"Public NPI-keyed lookup returning light data only (name, primary practice address, taxonomy, enumeration date). No authentication required. Rate-limited to 100 requests/day per IP (rolling 24h window) with a 10/min burst cap. Excludes DSO affiliation, license events, license status, HPSA, NPDB, CMS Medicare, and confidence scores — those require a paid plan or per-query billing.","tags":["Free Tier"],"security":[],"parameters":[{"name":"npi","in":"query","required":true,"schema":{"type":"string","pattern":"^\\d{10}$"},"description":"10-digit NPI"}],"responses":{"200":{"description":"Light provider data + citation envelope (billing_method='free')"},"400":{"description":"Missing or malformed npi parameter"},"404":{"description":"NPI not found in the dental cohort"},"429":{"description":"Rate limit exceeded. Headers include `Retry-After` in seconds plus standard `X-RateLimit-*`. Body includes upgrade_paths to /pricing and /docs/agent-payments."}}}},"/api/v1/free/health":{"get":{"summary":"Free-tier health probe","description":"Public no-auth health probe for agents validating connectivity. No rate limit. Returns API version + envelope version + canonical doc URLs. Distinct from /api/health (which probes DB + Redis + Stripe).","tags":["Free Tier"],"security":[],"responses":{"200":{"description":"Service reachable"}}}},"/api/v1/agent/lookup-by-npi":{"get":{"summary":"Agent NPI lookup (paid via x402, $0.50 USDC)","description":"Full provider record by NPI behind an x402 paywall. Per-call price: $0.50 USDC (500,000 atomic). Returns the same envelope shape as /api/v1/free/lookup but with the full Provider record (including DSO affiliation, license events, has_disciplinary_action, has_cms_claims, oig_exclusion record), plus `meta.confidence.provider_record` over the row. Public-internet calls are intercepted by the x402-gateway sidecar Worker which verifies payment via the Coinbase facilitator before forwarding here. See /docs/agent-payments for the full payment flow.","tags":["Agent (Paid)"],"security":[{"x402":[]},{"mpp":[]}],"parameters":[{"name":"npi","in":"query","required":true,"schema":{"type":"string","pattern":"^\\d{10}$"},"description":"10-digit NPI"}],"responses":{"200":{"description":"Full provider data + citation envelope (billing_method='per_query', billed_credits=5)"},"400":{"description":"Missing or malformed npi parameter"},"402":{"description":"Payment required, on two rails. The PAYMENT-REQUIRED header + body carry x402 PaymentRequirements (price, asset, network, payTo) for the USDC rail (retry with X-PAYMENT). The WWW-Authenticate header carries an MPP challenge (method=stripe) for the card rail (retry with `Authorization: Payment <SPT>`)."},"404":{"description":"NPI not found in dental cohort"}}}},"/api/v1/agent/search":{"get":{"summary":"Agent provider search (paid via x402, $0.50 USDC)","description":"Filtered provider list with pagination. Per-call price: $0.50 USDC (500,000 atomic). Filter axes: state(s), city, zip, specialty, is_dso, license_status (comma-separated normalized buckets), has_cms (true/false), excluded (true/false for OIG LEIE). Pagination via page + per_page (max 100). Sort by last_name (default), city, state, enumeration_date, co_located_count, license_expiration_date.","tags":["Agent (Paid)"],"security":[{"x402":[]},{"mpp":[]}],"parameters":[{"name":"state","in":"query","schema":{"type":"string"},"description":"Single state code or comma-separated list (e.g. `TX,FL,CA`)"},{"name":"specialty","in":"query","schema":{"type":"string"},"description":"Exact NUCC taxonomy specialty match"},{"name":"is_dso","in":"query","schema":{"type":"string","enum":["true","false"]}},{"name":"license_status","in":"query","schema":{"type":"string"},"description":"Single value or comma-separated normalized buckets (active/inactive/expired/retired/deceased/disciplined/pending)"},{"name":"has_cms","in":"query","schema":{"type":"string","enum":["true","false"]},"description":"Filter to providers with Medicare Part B claims history"},{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"per_page","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}}],"responses":{"200":{"description":"Paginated provider list with citation envelope (billing_method='per_query')"},"402":{"description":"Payment required"}}}},"/api/v1/agent/dso/affiliation":{"get":{"summary":"Agent DSO affiliation inference (paid via x402, $1.00 USDC)","description":"DSO affiliation context for a single NPI. Per-call price: $1.00 USDC (1,000,000 atomic). Moat-tier — premium over /lookup-by-npi reflects the cluster-level intelligence (sibling sample, dso_cluster_size, parent-org / inferred-practice context).","tags":["Agent (Paid)"],"security":[{"x402":[]},{"mpp":[]}],"parameters":[{"name":"npi","in":"query","required":true,"schema":{"type":"string","pattern":"^\\d{10}$"},"description":"10-digit NPI"}],"responses":{"200":{"description":"DSO affiliation record with cluster size + sibling sample (max 10 records)"},"400":{"description":"Missing or malformed npi parameter"},"402":{"description":"Payment required"},"404":{"description":"NPI not found in dental cohort"}}}},"/api/v1/agent/scoring":{"get":{"summary":"Agent acquisition scoring (paid via x402, $1.00 USDC)","description":"Acquisition-readiness score (0-100) with per-component breakdown for a paginated provider cohort (individuals only). Per-call price: $1.00 USDC (1,000,000 atomic). Score is a persisted column (migration 00138), so min_score filters and sort=score rank DB-side -- paginated output is true score-ranked. Same 6-factor formula as the dashboard (Solo/Independent 25%, Practice Vintage 15%, Retirement Risk 20%, Practice Size 15%, Clean Record 10%, License Freshness 15%).","tags":["Agent (Paid)"],"security":[{"x402":[]},{"mpp":[]}],"parameters":[{"name":"state","in":"query","schema":{"type":"string"}},{"name":"specialty","in":"query","schema":{"type":"string"}},{"name":"is_dso","in":"query","schema":{"type":"string","enum":["true","false"]}},{"name":"sole_prop","in":"query","schema":{"type":"string","enum":["true","false"]}},{"name":"has_cms","in":"query","schema":{"type":"string","enum":["true"]}},{"name":"min_score","in":"query","schema":{"type":"integer","minimum":0,"maximum":100}},{"name":"enriched_only","in":"query","schema":{"type":"string","enum":["true"]},"description":"true to return only providers with a state-board license record"},{"name":"sort","in":"query","schema":{"type":"string","enum":["score","last_name","city","enumeration_date","license_expiration_date","co_located_count"],"default":"last_name"},"description":"Sort column. score defaults to DESC order."},{"name":"order","in":"query","schema":{"type":"string","enum":["asc","desc"]},"description":"Sort direction. Defaults DESC for score, ASC otherwise."},{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"per_page","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}}],"responses":{"200":{"description":"Scored provider list with confidence + score_factors per row"},"402":{"description":"Payment required"}}}},"/api/v1/agent/license/events/historical":{"get":{"summary":"Agent license event history (paid via x402, $1.50 USDC)","description":"Per-NPI license event history: status changes, discipline events, board actions, address changes. Per-call price: $1.50 USDC (1,500,000 atomic). Returns chronologically-sorted events (newest-first) with up to `limit` rows. Each event has event_type, event_date, old_value, new_value, source (which ingest produced it), state.","tags":["Agent (Paid)"],"security":[{"x402":[]},{"mpp":[]}],"parameters":[{"name":"npi","in":"query","required":true,"schema":{"type":"string","pattern":"^\\d{10}$"}},{"name":"event_type","in":"query","schema":{"type":"string"},"description":"Optional filter (e.g. 'STATUS_CHANGE', 'DISCIPLINARY_ACTION')"},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":500,"default":100}}],"responses":{"200":{"description":"Event history for the NPI with total_events count + envelope"},"400":{"description":"Missing or malformed npi parameter"},"402":{"description":"Payment required"},"404":{"description":"NPI not found in dental cohort"}}}},"/api/v1/agent/territory/rollup":{"get":{"summary":"Agent territory rollup (paid via x402, $2.50 USDC)","description":"Aggregate territory analysis: provider counts, DSO/Independent/Group split, signal-driven rollups (CMS billers, disciplinary action, federally-excluded, retirement-risk), license-status distribution, ranked top_specialties + top_dsos, and (single-state requests only) a state-level `positioning` block: a Market Multiple band (Premium/Average/Discount) vs the PUBLIC national practice-sale benchmark (Levin/FOCUS/BizBuySell), shipped with a disclaimer that it is market context, not a transaction comp or practice-specific valuation. Per-call price: $2.50 USDC (2,500,000 atomic). State filter is required — national rollups would be a 270K-row scan and aren't a useful agent query. ~14 parallel count queries + 2 RPC calls per request, ~1 second latency.","tags":["Agent (Paid)"],"security":[{"x402":[]},{"mpp":[]}],"parameters":[{"name":"state","in":"query","required":true,"schema":{"type":"string"},"description":"Single 2-letter code or comma-list (e.g. `TX` or `TX,FL,CA`)"},{"name":"city","in":"query","schema":{"type":"string"},"description":"Optional partial city match (case-insensitive)"},{"name":"zip","in":"query","schema":{"type":"string"},"description":"Optional ZIP prefix match"},{"name":"county","in":"query","schema":{"type":"string"},"description":"Optional exact county match"},{"name":"top_n","in":"query","schema":{"type":"integer","minimum":1,"maximum":25,"default":10},"description":"Cap for top_specialties + top_dsos arrays (default 10, max 25)"}],"responses":{"200":{"description":"Territory rollup with counts plus top_specialties (ranked by provider count, includes share_pct), top_dsos (ranked by provider count, includes practices + states_covered), and a state-level positioning block (band, modifier, benchmark, disclaimer) on single-state requests (null otherwise)."},"400":{"description":"Missing or malformed state parameter"},"402":{"description":"Payment required"}}}},"/api/v1/agent/market/positioning":{"get":{"summary":"Agent market positioning (paid via x402, $0.50 USDC)","description":"Dedicated single-metric Market Multiple Positioning band (Premium/Average/Discount) for a state or ZIP-prefix metro versus the PUBLIC national dental practice-sale benchmark (Levin/FOCUS/BizBuySell), with the four driving factors (DSO competition, demographics, scarcity, retirement supply), a 0-100 confidence score, the public benchmark range for the tier, and the four raw inputs. Cheaper, finer-grained alternative to the positioning block embedded in /api/v1/agent/territory/rollup. Computed LIVE (same deriveMarketInputs + computeMarketPositioning used by the baked /metro and /territory surfaces). Shipped with a disclaimer that it is market context, NOT a transaction comp or practice-specific valuation. Per-call price: $0.50 USDC (500,000 atomic). `state` is required and must be one of the 42 enriched states or DC; `zip` is an optional metro-grain ZIP prefix (truncated to the leading 3 digits). County/city scoping is intentionally not offered.","tags":["Agent (Paid)"],"security":[{"x402":[]},{"mpp":[]}],"parameters":[{"name":"state","in":"query","required":true,"schema":{"type":"string","pattern":"^[A-Za-z]{2}$"},"description":"Single 2-letter enriched-state code (e.g. `TX`). National + multi-state are not supported."},{"name":"zip","in":"query","schema":{"type":"string"},"description":"Optional ZIP prefix for metro-grain scope (3+ digits, truncated to the leading 3, e.g. `770` for Houston). Omit for whole-state."}],"responses":{"200":{"description":"Positioning result: scope (state, zip_prefix, grain), band, score, modifier, confidence, per-factor contributions, public benchmark range, the four raw inputs (dso_pct, median_income, providers_per_10k, retirement_cliff_pct), active_dentists, and the disclaimer. Wrapped in the standard citation envelope."},"400":{"description":"Missing or malformed state parameter"},"402":{"description":"Payment required"},"404":{"description":"State is not enriched (positioning unavailable)"}}}},"/api/v1/agent/medicaid/rates":{"get":{"summary":"Agent Medicaid dental fee schedule (paid via x402, $0.50 USDC)","description":"State Medicaid dental fee schedule for one state: a fixed common-procedure basket (periodic exam, adult + child cleaning, 1-surface filling, stainless-steel crown, simple extraction) with sanity-bounded rates, the state's national rank on that basket (1 = highest of 51), locality structure (adult/pediatric or geographic schedules), latest effective year, and total CDT code count. Optional `code` arg adds the raw published rate(s) for one CDT D-code. Per-call price: $0.50 USDC (500,000 atomic). Public fee-for-service schedule amounts, NOT a coverage/eligibility guarantee and NOT managed-care rates. Covers all 50 states + DC. Same data layer as the public /dental-medicaid-rates surface.","tags":["Agent (Paid)"],"security":[{"x402":[]},{"mpp":[]}],"parameters":[{"name":"state","in":"query","required":true,"schema":{"type":"string","pattern":"^[A-Za-z]{2}$"},"description":"Two-letter state code (e.g. `TX`). All 50 states + DC."},{"name":"code","in":"query","schema":{"type":"string","pattern":"^[Dd]\\d{4}$"},"description":"Optional CDT D-code (e.g. `D2391`) for a specific-procedure raw lookup."}],"responses":{"200":{"description":"Medicaid fee-schedule summary (basket with sanity-bounded rates, national_rank, locality structure, effective_year, total_codes) + citation envelope; `requested_code` present only when `code` is supplied."},"400":{"description":"Missing or malformed state parameter"},"402":{"description":"Payment required"},"404":{"description":"No Medicaid dental rate data for the state"}}}},"/api/stats":{"get":{"summary":"Aggregate provider counts (public)","description":"Headline counts powering the landing page. Returns counts by territory if `states` param provided, or national totals.","tags":["Stats"],"security":[],"parameters":[{"name":"states","in":"query","required":false,"schema":{"type":"string"},"description":"Comma-separated 2-letter state codes (e.g. `TX,FL,CA`). Omit for national totals."}],"responses":{"200":{"description":"Aggregate stats with citation envelope","content":{"application/json":{"schema":{"allOf":[{"type":"object","required":["data","error"],"properties":{"data":{"description":"Endpoint-specific payload. Type varies per route — see individual path responses."},"error":{"type":"null"},"meta":{"$ref":"#/components/schemas/EnvelopeMeta"}}},{"properties":{"data":{"$ref":"#/components/schemas/StatsData"}}}]}}}},"429":{"$ref":"#/components/responses/RateLimit"}}}},"/api/providers":{"get":{"summary":"Provider directory (paginated, filterable)","description":"Paginated provider list with extensive filter support. Each row carries a per-provider `confidence` field (completeness + multi-source + freshness). The full filter catalog is documented in the parameters below.","tags":["Providers"],"parameters":[{"$ref":"#/components/parameters/state"},{"$ref":"#/components/parameters/page"},{"$ref":"#/components/parameters/per_page"},{"name":"q","in":"query","schema":{"type":"string"},"description":"Free-text search across name, NPI, city, ZIP, organization"},{"name":"city","in":"query","schema":{"type":"string"}},{"name":"zip","in":"query","schema":{"type":"string","pattern":"^\\d{5}$"}},{"name":"specialty","in":"query","schema":{"type":"string"}},{"name":"is_dso","in":"query","schema":{"type":"string","enum":["true","false"]}},{"name":"discipline","in":"query","schema":{"type":"string","enum":["true","false"]},"description":"Active OR historical discipline (TN v1.24 bifurcation)"},{"name":"excluded","in":"query","schema":{"type":"string","enum":["true","false"]},"description":"OIG LEIE federal exclusion filter"},{"name":"retirement_risk","in":"query","schema":{"type":"string","enum":["true"]},"description":"State-agnostic retirement-risk via graduation_year, age_range, or license_issue_date"},{"name":"license_status","in":"query","schema":{"type":"string"}},{"name":"exp_months","in":"query","schema":{"type":"integer","minimum":1,"maximum":24}},{"name":"anesthesia_level","in":"query","schema":{"type":"string"}},{"name":"min_practice_size","in":"query","schema":{"type":"integer"}},{"name":"has_cms","in":"query","schema":{"type":"string","enum":["true","false"]}},{"name":"has_email","in":"query","schema":{"type":"string","enum":["true","false"]},"description":"FL provider_email presence"},{"name":"has_fax","in":"query","schema":{"type":"string","enum":["true","false"]},"description":"NPPES practice-fax presence (national). Tenure proxy: true = established offices, false = digital-first"},{"name":"sedation_permit","in":"query","schema":{"type":"string"},"description":"FL sedation_permits filter; pass `__any__` for IS NOT NULL"},{"name":"sole_prop","in":"query","schema":{"type":"string","enum":["true","false"]}},{"name":"independent","in":"query","schema":{"type":"string","enum":["true"]}},{"name":"enriched_only","in":"query","schema":{"type":"string","enum":["true"]}},{"name":"include_suppressed","in":"query","schema":{"type":"string","enum":["true"]},"description":"Include rows users marked as already-acquired (default: excluded)"},{"name":"min_confidence","in":"query","schema":{"type":"integer","minimum":0,"maximum":100}},{"name":"cursor","in":"query","schema":{"type":"string"},"description":"NPI of the last result from the prior page (cursor pagination)"}],"responses":{"200":{"description":"Paginated provider list with citation envelope. `meta` carries both pagination fields (total, page, per_page, total_pages, optional next_cursor) and envelope fields (envelope_version, source_attribution, request)."},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimit"}}}},"/api/providers/{npi}":{"get":{"summary":"Provider record by NPI","description":"Detail record for a single provider keyed by 10-digit NPI. Returns provider fields + co-located providers + practice entities + CMS Medicare summary + OIG LEIE exclusion (when applicable). NOTE: this endpoint currently returns its legacy non-envelope shape; envelope migration pending dashboard-frontend coordination.","tags":["Providers"],"parameters":[{"name":"npi","in":"path","required":true,"schema":{"type":"string","pattern":"^\\d{10}$"},"description":"10-digit National Provider Identifier"}],"responses":{"200":{"description":"Provider detail (legacy shape — envelope migration pending)"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"NPI not found in the dental cohort"}}}},"/api/scoring":{"get":{"summary":"Scored acquisition leads","description":"Provider list with computed acquisition score (0-100), per-row confidence, and CMS Medicare aggregates. Each row carries `confidence: { score, tier, breakdown }` reflecting completeness + multi-source agreement + freshness for that provider.","tags":["Providers"],"parameters":[{"$ref":"#/components/parameters/state"},{"$ref":"#/components/parameters/page"},{"$ref":"#/components/parameters/per_page"},{"name":"sort","in":"query","schema":{"type":"string","enum":["score","last_name","city","enumeration_date","license_expiration_date","co_located_count","inferred_practice_name","cms_paid"]},"description":"Sort column. Default `score`."},{"name":"order","in":"query","schema":{"type":"string","enum":["asc","desc"],"default":"desc"}},{"name":"min_score","in":"query","schema":{"type":"integer","minimum":0,"maximum":100}}],"responses":{"200":{"description":"Paginated scored providers with citation envelope","content":{"application/json":{"schema":{"allOf":[{"type":"object","required":["data","error"],"properties":{"data":{"description":"Endpoint-specific payload. Type varies per route — see individual path responses."},"error":{"type":"null"},"meta":{"$ref":"#/components/schemas/EnvelopeMeta"}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimit"}}}},"/api/npdb":{"get":{"summary":"NPDB aggregate stats","description":"Aggregated National Practitioner Data Bank stats by state + year + report category. NPDB is anonymized so individual disciplinary records come from state boards (see /api/alerts/events).","tags":["NPDB"],"parameters":[{"$ref":"#/components/parameters/state"}],"responses":{"200":{"description":"NPDB aggregate stats with citation envelope"},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/reimbursement":{"get":{"summary":"Fee schedules (CMS + state Medicaid)","description":"CPT/CDT-keyed reimbursement rates from CMS Medicare PFS and state Medicaid programs. Note: CMS dental rates are $0 (Medicare doesn't cover dental); use state Medicaid for actual dental rates.","tags":["Reimbursement"],"parameters":[{"$ref":"#/components/parameters/state"},{"name":"code","in":"query","schema":{"type":"string"},"description":"CPT or CDT code (e.g. `D2150`)"},{"name":"locality","in":"query","schema":{"type":"string"},"description":"State-specific locality identifier"},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":2000,"default":20}}],"responses":{"200":{"description":"Reimbursement rates with citation envelope"},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/demographics":{"get":{"summary":"ZIP-level Census ACS demographics","description":"Census ACS 5-year demographics by ZIP. Supports geo-scoping via ZIP+radius or city centroid.","tags":["Demographics"],"parameters":[{"$ref":"#/components/parameters/state"},{"name":"metric","in":"query","schema":{"type":"string","enum":["total_population","median_household_income","median_age","pct_under_18","pct_65_plus"],"default":"total_population"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":500,"default":200}},{"name":"zip","in":"query","schema":{"type":"string","pattern":"^\\d{5}$"},"description":"5-digit ZIP for radius scoping (use with `radius`)"},{"name":"radius","in":"query","schema":{"type":"number"},"description":"Miles around `zip`. Capped at 200."},{"name":"city","in":"query","schema":{"type":"string"},"description":"City name (use with `state`); 25-mile default radius applied"}],"responses":{"200":{"description":"Demographics with citation envelope (echoes `metric` at root for legacy callers)"},"400":{"description":"Invalid metric"},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/cms/map":{"get":{"summary":"Medicare Part B map overlay (Team+)","description":"Geocoded providers with Medicare Part B billing history, aggregated by NPI. Marker size scales with lifetime payment volume. Pro plan blocked (returns 403); Team plan and higher allowed.","tags":["Geospatial"],"parameters":[{"$ref":"#/components/parameters/state"}],"responses":{"200":{"description":"CMS map entries with citation envelope"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"description":"Pro plan — upgrade to Team for CMS overlay"}}}},"/api/hpsa/map":{"get":{"summary":"HRSA HPSA designations map overlay","description":"Health Professional Shortage Area designations by county. One row per county (highest-score designation when multiple).","tags":["Geospatial"],"parameters":[{"$ref":"#/components/parameters/state"}],"responses":{"200":{"description":"HPSA designations with citation envelope"},"401":{"$ref":"#/components/responses/Unauthorized"}}}}},"components":{"schemas":{"EnvelopeMeta":{"type":"object","required":["envelope_version","source_attribution","request"],"description":"Citation envelope. Every agent-callable response carries this so agents can verify provenance + freshness without out-of-band validation.","properties":{"envelope_version":{"type":"string","const":"1.0","description":"Schema version of the envelope itself. Bumped on breaking shape changes; non-breaking additions don't bump."},"source_attribution":{"type":"array","description":"Every source table that contributed to this response, with its own `last_refresh` from the pipeline status table.","items":{"$ref":"#/components/schemas/SourceAttribution"}},"confidence":{"type":"object","description":"Endpoint-specific confidence breakdowns keyed by inference type. Omitted entirely when no inferred fields are returned. For per-row inferences (e.g. /api/scoring's per-provider confidence), the inference appears on each row instead.","additionalProperties":{"$ref":"#/components/schemas/EndpointConfidence"}},"request":{"$ref":"#/components/schemas/RequestMeta"},"total":{"type":"integer"},"page":{"type":"integer"},"per_page":{"type":"integer"},"total_pages":{"type":"integer"},"next_cursor":{"type":["string","null"]}}},"SourceAttribution":{"type":"object","required":["table","last_refresh","schema_version","license"],"properties":{"table":{"type":"string","description":"Logical source name (e.g. `npi`, `tsbde`, `cms_partb`, `hpsa`)"},"last_refresh":{"type":["string","null"],"format":"date-time","description":"ISO 8601 timestamp of the most recent successful pipeline run, or null if never synced (cold-start state)"},"schema_version":{"type":"string","description":"Stable identifier for the data shape we expose. Bumped only on deliberate breaking changes."},"license":{"type":"string","enum":["public-domain","state-public-records","state-fee-schedule"],"description":"Posture string. `public-domain` for federal sources (NPI, OIG LEIE, CMS, HPSA, Census). `state-public-records` for state board rosters. `state-fee-schedule` for state Medicaid fee tables (often carry use-with-attribution restrictions)."}}},"EndpointConfidence":{"type":"object","required":["score","method"],"properties":{"score":{"type":"number","description":"0-100 (provider record confidence) or 0-1 (probability-style scores like DSO affiliation). Endpoint-specific scale; documented in /docs/fields."},"tier":{"type":"string","enum":["High","Medium","Low"],"description":"Optional human-readable bucket. Only meaningful for 0-100 scores."},"method":{"type":"string","description":"Short identifier for the computation method (e.g. `completeness+multi_source+freshness` or `shared_billing_address+phone_clustering+name_match`). Stable across releases — bumps signal a method change."},"breakdown":{"type":"object","additionalProperties":true,"description":"Optional component-level breakdown for callers who want to surface the 'why'."},"evidence_count":{"type":"integer","description":"Optional supporting-row count for evidence-driven inferences (e.g. number of co-located providers backing a DSO inference)."}}},"RequestMeta":{"type":"object","required":["id","endpoint","billed_credits","billing_method"],"properties":{"id":{"type":"string","description":"Stable request id for log correlation. Mirrored to the `X-Request-Id` response header."},"endpoint":{"type":"string"},"billed_credits":{"type":"integer","description":"Credits billed against the caller's bucket. 0 for subscription / admin / free; positive int for per-query (Phase 3 x402 / MPP)."},"billing_method":{"type":"string","enum":["subscription","per_query","free","admin"]}}},"StatsData":{"type":"object","properties":{"provider_count":{"type":"integer"},"active_providers":{"type":"integer"},"dso_flagged":{"type":"integer"},"solo_practitioners":{"type":"integer"},"retirement_age":{"type":"integer"},"inactive_retired_count":{"type":"integer"},"disciplinary_actions":{"type":"integer"},"enriched_count":{"type":"integer"},"expiring_licenses_12mo":{"type":"integer"},"expiring_licenses_24mo":{"type":"integer"},"open_grants":{"type":"integer"},"hpsa_designations":{"type":"integer"}}}},"parameters":{"state":{"name":"state","in":"query","schema":{"type":"string","pattern":"^[A-Z]{2}$"},"description":"2-letter US state code (uppercased automatically)"},"page":{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},"per_page":{"name":"per_page","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}}},"responses":{"Unauthorized":{"description":"Missing or invalid auth (no API key, expired session, wrong scope on key)","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"null"},"error":{"type":"string"}}}}}},"RateLimit":{"description":"Rate limit exceeded. Headers: `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"schema":{"type":"integer"}}}}},"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","description":"API key auth. Format: `Authorization: Bearer ps_live_<key>`. Provisioned per plan — see /pricing."},"sessionCookie":{"type":"apiKey","in":"cookie","name":"sb-access-token","description":"Supabase session cookie (dashboard auth). Not used by external API consumers."},"x402":{"type":"apiKey","in":"header","name":"X-PAYMENT","description":"x402 (USDC) payment authorization header. Signed PaymentPayload, base64url-encoded. On a 402 response the body + PAYMENT-REQUIRED header contain the PaymentRequirements (price + asset + network + payTo); the agent constructs the X-PAYMENT header by signing those requirements with its USDC wallet. The same 402 also offers a card rail (see the `mpp` scheme): agents without a USDC wallet can pay by card instead. See /docs/agent-payments for the full flow and https://x402.org for protocol spec."},"mpp":{"type":"apiKey","in":"header","name":"Authorization","description":"MPP card-rail authorization. Format: `Authorization: Payment <shared-payment-token>`. On a 402 the WWW-Authenticate header carries an MPP challenge (method=stripe, the per-call price); a card agent mints a Stripe Shared Payment Token (for example via @stripe/link-cli) and retries with this header. Every paid endpoint accepts EITHER x402 (USDC) OR MPP (card) on the same 402: pick the rail your wallet supports. See /docs/agent-payments."}}}}