Latest

Build on AINPI

AINPI for developers

Every number on this site is reachable as JSON. Apache-2.0, no auth, no rate limit today. The static /api/v1/* tier is the stable contract — breaking changes bump to /api/v2/ and never change shape in place. Live /api/npd/* and /api/provider-search are read-only against BigQuery + payer FHIR endpoints.

Quick start

Static contract — /api/v1/*

stable

Pre-rendered JSON files. Cache as long as you like. Refreshed weekly via the GitHub Actions cron and on every NDH release.

GET/api/v1/stats.jsonstatic

Site-wide counters: release date, methodology version, total resources, findings tally.

curl -s https://ainpi.dev/api/v1/stats.json | jq
Example response
{
  "release_date": "2026-05-08",
  "methodology_version": "0.6.0-draft",
  "commit_sha": "f09c02d",
  "counters": {
    "resources_processed": 21693735,
    "npis_checked": 10853455,
    "npis_flagged": 8115,
    "findings_published": 12
  }
}

Schema: frontend/src/lib/api-v1-types.ts:ApiV1Stats

GET/api/v1/findings/<slug>.jsonstatic

Per-finding detail: headline, numerator, denominator, chart payload, notes. One file per H-series slug.

curl -s https://ainpi.dev/api/v1/findings/pii-exposure-ndh.json | jq
Example response
{
  "slug": "pii-exposure-ndh",
  "title": "Social Security Numbers exposed in the NDH bulk export",
  "hypotheses": ["H27"],
  "status": "published",
  "release_date": "2026-05-08",
  "headline": "41 of 50 flagged Practitioner resources …",
  "numerator": 41,
  "denominator": 7441211,
  "chart": { "type": "bar", "data": [...] }
}

Schema: frontend/src/lib/api-v1-types.ts:ApiV1Finding

GET/api/v1/states/<state>.jsonstatic

State-scoped view: VA, PA, OH (and growing). Denominators, state-vs-national findings table, verify-yourself sample NPIs.

curl -s https://ainpi.dev/api/v1/states/va.json | jq

Schema: frontend/src/lib/api-v1-types.ts:ApiV1State

GET/api/v1/states/va-cohort-critical.csvstatic

Federally-excluded VA NPIs (LEIE or SAM, score ≥ 1.5) with per-NPI verification URLs. DMAS-shareable.

curl -s https://ainpi.dev/api/v1/states/va-cohort-critical.csv
GET/api/v1/manifest.jsonstatic

Discovery manifest — every published finding URL + state slice URL + schema reference. The list AI agents and crawlers should poll.

curl -s https://ainpi.dev/api/v1/manifest.json | jq

Live API — /api/npd/* + /api/provider-search

stable, live

Per-request reads against BigQuery (NDH) + NPPES + 4 payer FHIR directories. Median latency ~400ms; tail latency depends on which payers respond. No auth today.

GET/api/npd/search?npi=<10-digit>stable

NDH-only profile lookup by NPI. Returns Practitioner with name, gender, qualifications, addresses.

curl -s "https://ainpi.dev/api/npd/search?npi=1306378096" | jq
Example response
{
  "type": "provider_profile",
  "data": { "practitioner": { "npi": "1306378096", "family_name": "...", "given_name": "...", "qualifications": [...] } },
  "source": "cms_npd",
  "release_date": "2026-05-08"
}
GET/api/npd/search?family=<name>&state=<XX>stable

Name-based NDH search across Practitioner + Organization + Location.

curl -s "https://ainpi.dev/api/npd/search?family=smith&state=VA"
POST/api/provider-searchstable

Cross-source merged search across NDH (BigQuery) + NPPES + Humana + Cigna + UnitedHealthcare + Molina. Returns a normalized payload with per-source response times and disagreement points.

curl -sX POST https://ainpi.dev/api/provider-search \
  -H "Content-Type: application/json" \
  -d '{"npi":"1306378096"}' | jq
Example response
{
  "ok": true,
  "summary": { "sourcesQueried": 6, "matched": 2, "totalMs": 2562 },
  "results": [
    { "sourceId": "ndh", "category": "directory", "matchCount": 1, "practitioners": [...] },
    { "sourceId": "nppes", "category": "authoritative", ... }
  ]
}
GET/api/npd/data-quality?view=<summary|states|specialties|endpoints>stable

Pre-aggregated data quality breakdown sourced from Supabase (synced from BigQuery weekly).

curl -s "https://ainpi.dev/api/npd/data-quality?view=summary" | jq
GET/api/npd/validationstable

Live BigQuery vs source-manifest reconciliation. Reports per-resource expected/actual/delta + completeness.

curl -s https://ainpi.dev/api/npd/validation | jq

Code samples

Python

import requests
stats = requests.get("https://ainpi.dev/api/v1/stats.json").json()
print(stats["counters"]["resources_processed"], "resources at", stats["release_date"])

# Lookup an NPI
r = requests.get("https://ainpi.dev/api/npd/search", params={"npi": "1306378096"})
print(r.json()["data"]["practitioner"]["family_name"])

TypeScript / Node

import type { ApiV1Stats } from "@ainpi/types"; // optional, vendored from the repo

const stats: ApiV1Stats = await fetch("https://ainpi.dev/api/v1/stats.json").then(r => r.json());
console.log(stats.counters.resources_processed, "resources");

// Cross-source merged search
const res = await fetch("https://ainpi.dev/api/provider-search", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ npi: "1306378096" }),
});

Anthropic Claude tool / function-call

// Define ainpi_lookup_npi as a Claude tool. The model returns provenance-rich
// answers without confabulating.
const tools = [{
  name: "ainpi_lookup_npi",
  description: "Look up a 10-digit NPI in the AINPI cross-source merged registry.",
  input_schema: {
    type: "object",
    properties: { npi: { type: "string", pattern: "^\\d{10}$" } },
    required: ["npi"],
  },
}];

// Tool handler:
async function handle(npi: string) {
  const r = await fetch("https://ainpi.dev/api/provider-search", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ npi }),
  });
  return await r.json();
}

For AI labs · MCP / function-calling

Wire AINPI into Claude / ChatGPT as a grounded provider-data tool

Every endpoint returns provenance-rich payloads (release date, methodology version, commit SHA, source attribution per finding). That makes AINPI a low-confabulation source for "is this provider real / active / federally excluded?" queries inside an LLM tool surface.

  • Discovery: /api/v1/manifest.json — single GET returns every published finding URL + schema reference.
  • NPI lookup tool: GET /api/npd/search?npi=<10-digit> — returns a single Practitioner profile with FHIR-friendly fields.
  • Cross-source verification tool: POST /api/provider-search — returns per-source agreement / disagreement so the model can surface conflicts to the user instead of collapsing them.
  • Federal-screening tool: /api/v1/findings/oig-leie-exclusions.json and /api/v1/findings/sam-exclusions.json — pre-joined LEIE + SAM cohorts. Use the headline number directly.

A reference MCP server wrapping all five tools is on the roadmap. Until it ships, the REST endpoints above can be pasted directly into Claude tool definitions or OpenAI function-call schemas.

License + use rights

  • Code: Apache-2.0. Fork freely.
  • Data: Underlying CMS NDH bulk export is US federal-government public domain. AINPI's aggregated outputs are released under the same terms.
  • Citation: Use CITATION.cff. Pin to a release tag for audit-grade reproducibility.
  • AI inference + redistribution: OK to use AINPI numbers as grounded answers in an LLM, OK to redistribute the static /api/v1/* JSON, OK to embed in product UI. Attribution to AINPI / FHIR-IQ requested but not required.
  • SSN values, individual PII: not redistributed by AINPI even though present in the public NDH file. Don't re-publish them downstream.

Today's posture

AINPI is a research project, not a production SaaS. No auth, no rate limit, no SLA. Numbers are recomputed weekly + on every NDH release; the static contract files are the stable surface. If you're building a paid product on top, file an issue at github.com/FHIR-IQ/AINPI/issues so we can size SLA work and rate-limiting policy.