{
  "openapi": "3.1.0",
  "info": {
    "title": "SimpleNPI public API",
    "version": "1.0.0",
    "summary": "Free NPI lookup and verification from the CMS NPPES registry.",
    "description": "Free, keyless, IP rate-limited (30 requests per minute). Data comes from the CMS NPPES NPI Registry, which CMS refreshes daily. Starting an NPI application happens on the hosted form at https://simplenpi.com/start (prefill with query parameters first, last, state, profession, email, mobile); identity details are never accepted through this API. AI assistants can also use the MCP server at https://simplenpi.com/mcp. SimpleNPI is a private filing service, not a government agency. The NPI is issued free of charge by CMS at nppes.cms.hhs.gov.",
    "contact": { "name": "SimpleNPI", "url": "https://simplenpi.com", "email": "info@simplenpi.com" },
    "termsOfService": "https://simplenpi.com/"
  },
  "servers": [{ "url": "https://simplenpi.com/api/v1" }],
  "paths": {
    "/lookup": {
      "post": {
        "operationId": "lookupNpi",
        "summary": "Look up an NPI by provider name or business name",
        "description": "Search the CMS registry. Send first + last (+ optional state) for an individual (Type 1) NPI, or organization (+ optional state) for a business (Type 2) NPI. Organization search also matches DBA names; a trailing * is a prefix match. Returns up to 10 matches.",
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LookupRequest" } } }
        },
        "responses": {
          "200": { "description": "Matches", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LookupResponse" } } } },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/verify/{npi}": {
      "get": {
        "operationId": "verifyNpi",
        "summary": "Verify an NPI number",
        "description": "Full CMS registry record for one NPI: status (active, deactivated, not_found), name, taxonomies with license numbers, practice and mailing address, enumeration date, last update.",
        "parameters": [{ "name": "npi", "in": "path", "required": true, "schema": { "type": "string", "pattern": "^\\d{10}$" }, "description": "The 10-digit NPI." }],
        "responses": {
          "200": { "description": "Registry record", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/VerifyResponse" } } } },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/applications/{id}": {
      "get": {
        "operationId": "getApplicationStatus",
        "summary": "Status of a SimpleNPI application",
        "description": "Takes the id and k (key) from the status link SimpleNPI emailed the applicant: https://simplenpi.com/s/{id}?k={key}.",
        "parameters": [
          { "name": "id", "in": "path", "required": true, "schema": { "type": "string", "pattern": "^a_[a-z2-7]{10}$" } },
          { "name": "k", "in": "query", "required": true, "schema": { "type": "string" }, "description": "The status key from the email link." }
        ],
        "responses": {
          "200": { "description": "Status", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/StatusResponse" } } } },
          "404": { "description": "No application matches that id and key." }
        }
      }
    },
    "/health": {
      "get": { "operationId": "health", "summary": "Health check", "responses": { "200": { "description": "ok", "content": { "application/json": { "schema": { "type": "object", "properties": { "ok": { "type": "boolean" } } } } } } } }
    }
  },
  "components": {
    "responses": {
      "BadRequest": { "description": "Invalid request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "RateLimited": { "description": "Too many requests from this IP. Retry-After header in seconds.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
    },
    "schemas": {
      "LookupRequest": {
        "type": "object",
        "properties": {
          "first": { "type": "string", "description": "First name, 2+ letters; trailing * matches the rest." },
          "last": { "type": "string", "description": "Last name." },
          "organization": { "type": "string", "description": "Business / practice name for a Type 2 search. Use instead of first + last." },
          "state": { "type": "string", "pattern": "^[A-Z]{2}$", "description": "Two-letter US state, optional." }
        }
      },
      "Match": {
        "type": "object",
        "properties": {
          "npi": { "type": "string" }, "type": { "type": "string", "enum": ["individual", "organization"] }, "name": { "type": "string" }, "dba": { "type": "string" },
          "state": { "type": "string" }, "city": { "type": "string" }, "taxonomy": { "type": "string" }, "taxonomyCode": { "type": "string" },
          "license": { "type": "string" }, "licenseState": { "type": "string" }, "status": { "type": "string" }, "enumerationDate": { "type": "string" }, "lastUpdated": { "type": "string" }
        }
      },
      "Registry": { "type": "object", "properties": { "source": { "type": "string" }, "refreshed": { "type": "string" } } },
      "LookupResponse": {
        "type": "object",
        "properties": { "matches": { "type": "array", "items": { "$ref": "#/components/schemas/Match" } }, "registry": { "$ref": "#/components/schemas/Registry" }, "disclosure": { "type": "string" } }
      },
      "Address": { "type": "object", "properties": { "line1": { "type": "string" }, "line2": { "type": "string" }, "city": { "type": "string" }, "state": { "type": "string" }, "zip": { "type": "string" }, "phone": { "type": "string" } } },
      "VerifyResponse": {
        "type": "object",
        "properties": {
          "npi": { "type": "string" }, "status": { "type": "string", "enum": ["active", "deactivated", "not_found"] }, "enumerationType": { "type": "string" }, "name": { "type": "string" },
          "taxonomies": { "type": "array", "items": { "type": "object", "properties": { "code": { "type": "string" }, "desc": { "type": "string" }, "primary": { "type": "boolean" }, "state": { "type": "string" }, "license": { "type": "string" } } } },
          "practiceAddress": { "$ref": "#/components/schemas/Address" }, "mailingAddress": { "$ref": "#/components/schemas/Address" },
          "enumerationDate": { "type": "string" }, "lastUpdated": { "type": "string" }, "deactivationDate": { "type": "string" },
          "registry": { "$ref": "#/components/schemas/Registry" }, "disclosure": { "type": "string" }
        }
      },
      "StatusResponse": {
        "type": "object",
        "properties": { "id": { "type": "string" }, "status": { "type": "string", "enum": ["ready", "filing", "submitted", "issued", "pended", "review", "bad_data", "failed", "npi_exists", "cancelled"] }, "npi": { "type": "string" }, "tracking": { "type": "string" }, "createdAt": { "type": "string" }, "updatedAt": { "type": "string" }, "eta": { "type": "string" }, "disclosure": { "type": "string" } }
      },
      "Error": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string" }, "field": { "type": "string" }, "message": { "type": "string" } } } } }
    }
  }
}
