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/*
stablePre-rendered JSON files. Cache as long as you like. Refreshed weekly via the GitHub Actions cron and on every NDH release.
/api/v1/stats.jsonstaticSite-wide counters: release date, methodology version, total resources, findings tally.
curl -s https://ainpi.dev/api/v1/stats.json | jqExample 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
}
}/api/v1/findings/<slug>.jsonstaticPer-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 | jqExample 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": [...] }
}/api/v1/states/<state>.jsonstaticState-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/api/v1/states/va-cohort-critical.csvstaticFederally-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/api/v1/manifest.jsonstaticDiscovery 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 | jqLive API — /api/npd/* + /api/provider-search
stable, livePer-request reads against BigQuery (NDH) + NPPES + 4 payer FHIR directories. Median latency ~400ms; tail latency depends on which payers respond. No auth today.
/api/npd/search?npi=<10-digit>stableNDH-only profile lookup by NPI. Returns Practitioner with name, gender, qualifications, addresses.
curl -s "https://ainpi.dev/api/npd/search?npi=1306378096" | jqExample response
{
"type": "provider_profile",
"data": { "practitioner": { "npi": "1306378096", "family_name": "...", "given_name": "...", "qualifications": [...] } },
"source": "cms_npd",
"release_date": "2026-05-08"
}/api/npd/search?family=<name>&state=<XX>stableName-based NDH search across Practitioner + Organization + Location.
curl -s "https://ainpi.dev/api/npd/search?family=smith&state=VA"/api/provider-searchstableCross-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"}' | jqExample response
{
"ok": true,
"summary": { "sourcesQueried": 6, "matched": 2, "totalMs": 2562 },
"results": [
{ "sourceId": "ndh", "category": "directory", "matchCount": 1, "practitioners": [...] },
{ "sourceId": "nppes", "category": "authoritative", ... }
]
}/api/npd/data-quality?view=<summary|states|specialties|endpoints>stablePre-aggregated data quality breakdown sourced from Supabase (synced from BigQuery weekly).
curl -s "https://ainpi.dev/api/npd/data-quality?view=summary" | jq/api/npd/validationstableLive BigQuery vs source-manifest reconciliation. Reports per-resource expected/actual/delta + completeness.
curl -s https://ainpi.dev/api/npd/validation | jqCode 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.jsonand/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.