{
  "openapi": "3.0.1",
  "info": {
    "title": "NPPES NPI Bulk Scraper — Every Provider by Specialty & State",
    "description": "Pull an ENTIRE medical specialty from the official NPPES NPI Registry. The CMS API caps every query at 1,200 records; this Actor auto-splits by state and ZIP until each slice fits — 22,189 NY dentists, not 1,200. Name, phone, fax, practice address, license. Or paste NPI numbers to verify a list.",
    "version": "0.1",
    "x-build-id": "DBfdNbhJCICiUoGVd"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/scrapersdelight~nppes-provider-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-scrapersdelight-nppes-provider-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/acts/scrapersdelight~nppes-provider-scraper/runs": {
      "post": {
        "operationId": "runs-sync-scrapersdelight-nppes-provider-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor and returns information about the initiated run in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/runsResponseSchema"
                }
              }
            }
          }
        }
      }
    },
    "/acts/scrapersdelight~nppes-provider-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-scrapersdelight-nppes-provider-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "inputSchema": {
        "type": "object",
        "properties": {
          "specialties": {
            "title": "🩺 Specialties",
            "type": "array",
            "description": "Pick one or more specialties — each is enumerated separately, and every one in this list was verified live against the CMS API on 2026-08-12. CMS matches your text against the START of a NUCC taxonomy classification or specialization, which is why \"Dentist\" returns every dental sub-specialty (Dentist, Periodontics · Dentist, Orthodontics and Dentofacial Orthopedics · …) and why a mid-word fragment such as \"Medicine\", \"entist\" or \"dontic\" matches nothing at all. Leave empty ONLY if you are pasting ZIP codes or NPI numbers below — a state on its own is rejected by the API.",
            "items": {
              "type": "string",
              "enum": [
                "Dentist",
                "Dental Hygienist",
                "Pediatric Dentistry",
                "Orthodontics and Dentofacial Orthopedics",
                "Endodontics",
                "Periodontics",
                "Prosthodontics",
                "Oral & Maxillofacial Surgery",
                "Family Medicine",
                "Internal Medicine",
                "Pediatrics",
                "Obstetrics & Gynecology",
                "Emergency Medicine",
                "Anesthesiology",
                "Dermatology",
                "Ophthalmology",
                "Optometrist",
                "Radiology",
                "Surgery",
                "Orthopaedic Surgery",
                "Urology",
                "Cardiovascular Disease",
                "Gastroenterology",
                "Nephrology",
                "Neurology",
                "Psychiatry",
                "Psychologist",
                "Counselor",
                "Social Worker",
                "Marriage & Family Therapist",
                "Behavior Analyst",
                "Nurse Practitioner",
                "Registered Nurse",
                "Physician Assistant",
                "Chiropractor",
                "Podiatrist",
                "Physical Therapist",
                "Occupational Therapist",
                "Speech-Language Pathologist",
                "Audiologist",
                "Acupuncturist",
                "Massage Therapist",
                "Dietitian, Registered",
                "Nutritionist",
                "Pharmacy",
                "Pharmacist",
                "Clinic/Center",
                "General Acute Care Hospital",
                "Skilled Nursing Facility",
                "Assisted Living Facility",
                "Home Health",
                "Hospice Care, Community Based",
                "Clinical Medical Laboratory",
                "Durable Medical Equipment & Medical Supplies",
                "Ambulance",
                "Veterinarian"
              ],
              "enumTitles": [
                "Dentist — every dental sub-specialty (379,654 nationally)",
                "Dental Hygienist",
                "Pediatric Dentistry",
                "Orthodontics and Dentofacial Orthopedics",
                "Endodontics",
                "Periodontics",
                "Prosthodontics",
                "Oral & Maxillofacial Surgery",
                "Family Medicine",
                "Internal Medicine — plus every internal-medicine sub-specialty",
                "Pediatrics",
                "Obstetrics & Gynecology",
                "Emergency Medicine",
                "Anesthesiology",
                "Dermatology",
                "Ophthalmology",
                "Optometrist",
                "Radiology",
                "Surgery",
                "Orthopaedic Surgery",
                "Urology",
                "Cardiovascular Disease (cardiology)",
                "Gastroenterology",
                "Nephrology",
                "Neurology",
                "Psychiatry — note: \"Psychiatrist\" is NOT a taxonomy and fails",
                "Psychologist",
                "Counselor — incl. mental health, addiction, school",
                "Social Worker — incl. clinical social workers",
                "Marriage & Family Therapist",
                "Behavior Analyst (BCBA / ABA providers)",
                "Nurse Practitioner",
                "Registered Nurse",
                "Physician Assistant",
                "Chiropractor",
                "Podiatrist",
                "Physical Therapist",
                "Occupational Therapist",
                "Speech-Language Pathologist",
                "Audiologist",
                "Acupuncturist",
                "Massage Therapist",
                "Dietitian, Registered",
                "Nutritionist",
                "Pharmacy — the businesses (NPI-2)",
                "Pharmacist — the individuals (NPI-1)",
                "Clinic/Center — every clinic and centre type",
                "General Acute Care Hospital",
                "Skilled Nursing Facility",
                "Assisted Living Facility",
                "Home Health agencies",
                "Hospice Care, Community Based",
                "Clinical Medical Laboratory",
                "Durable Medical Equipment & Medical Supplies",
                "Ambulance services",
                "Veterinarian"
              ]
            }
          },
          "specialtiesCustom": {
            "title": "🩺 Any other specialty (free text)",
            "type": "array",
            "description": "Escape hatch for any NUCC taxonomy not in the dropdown — it is added to whatever you picked above. Type the OPENING WORDS of the taxonomy name, e.g. \"Legal Medicine\", \"Nurse Anesthetist, Certified Registered\", \"Transportation Services\". If CMS does not recognise it the run stops immediately with that explanation rather than pushing an empty dataset.",
            "items": {
              "type": "string"
            }
          },
          "states": {
            "title": "🗺️ States",
            "type": "array",
            "description": "Which states or territories to sweep. Leave EMPTY to sweep all 56 — that is the full national pull for the chosen specialty and it can run to hundreds of thousands of providers, so set \"Max providers\" first. Ignored when you paste ZIP codes or NPI numbers below.",
            "items": {
              "type": "string",
              "enum": [
                "AL",
                "AK",
                "AZ",
                "AR",
                "CA",
                "CO",
                "CT",
                "DE",
                "DC",
                "FL",
                "GA",
                "HI",
                "ID",
                "IL",
                "IN",
                "IA",
                "KS",
                "KY",
                "LA",
                "ME",
                "MD",
                "MA",
                "MI",
                "MN",
                "MS",
                "MO",
                "MT",
                "NE",
                "NV",
                "NH",
                "NJ",
                "NM",
                "NY",
                "NC",
                "ND",
                "OH",
                "OK",
                "OR",
                "PA",
                "RI",
                "SC",
                "SD",
                "TN",
                "TX",
                "UT",
                "VT",
                "VA",
                "WA",
                "WV",
                "WI",
                "WY",
                "PR",
                "VI",
                "GU",
                "AS",
                "MP"
              ],
              "enumTitles": [
                "Alabama (AL)",
                "Alaska (AK)",
                "Arizona (AZ)",
                "Arkansas (AR)",
                "California (CA)",
                "Colorado (CO)",
                "Connecticut (CT)",
                "Delaware (DE)",
                "District of Columbia (DC)",
                "Florida (FL)",
                "Georgia (GA)",
                "Hawaii (HI)",
                "Idaho (ID)",
                "Illinois (IL)",
                "Indiana (IN)",
                "Iowa (IA)",
                "Kansas (KS)",
                "Kentucky (KY)",
                "Louisiana (LA)",
                "Maine (ME)",
                "Maryland (MD)",
                "Massachusetts (MA)",
                "Michigan (MI)",
                "Minnesota (MN)",
                "Mississippi (MS)",
                "Missouri (MO)",
                "Montana (MT)",
                "Nebraska (NE)",
                "Nevada (NV)",
                "New Hampshire (NH)",
                "New Jersey (NJ)",
                "New Mexico (NM)",
                "New York (NY)",
                "North Carolina (NC)",
                "North Dakota (ND)",
                "Ohio (OH)",
                "Oklahoma (OK)",
                "Oregon (OR)",
                "Pennsylvania (PA)",
                "Rhode Island (RI)",
                "South Carolina (SC)",
                "South Dakota (SD)",
                "Tennessee (TN)",
                "Texas (TX)",
                "Utah (UT)",
                "Vermont (VT)",
                "Virginia (VA)",
                "Washington (WA)",
                "West Virginia (WV)",
                "Wisconsin (WI)",
                "Wyoming (WY)",
                "Puerto Rico (PR)",
                "US Virgin Islands (VI)",
                "Guam (GU)",
                "American Samoa (AS)",
                "Northern Mariana Islands (MP)"
              ]
            }
          },
          "postalCodes": {
            "title": "📮 ZIP codes",
            "type": "array",
            "description": "Restrict to specific ZIPs instead of whole states — full 5-digit ZIPs (10016) or shorter prefixes (100 = every ZIP starting 100). When this is set, States is ignored. A ZIP that still exceeds 1,200 providers is split further automatically. A ZIP on its own is a legal search even with NO specialty, so this is also how you pull a whole-ZIP roster of every provider of every kind.",
            "items": {
              "type": "string"
            }
          },
          "npiNumbers": {
            "title": "🔢 NPI numbers — look these up instead",
            "type": "array",
            "description": "Paste 10-digit NPI numbers to verify an existing list instead of enumerating a specialty. One API call per NPI, and EVERY other scope filter is ignored — you asked for these exact records. NPIs the registry does not hold are listed in the log and written to the key-value store under NPI_NOT_FOUND, so a credentialing run can diff its input list. You are billed only for the NPIs that came back with a record.",
            "items": {
              "type": "string"
            }
          },
          "npiType": {
            "title": "🏢 Provider type",
            "enum": [
              "",
              "NPI-1",
              "NPI-2"
            ],
            "type": "string",
            "description": "Individuals (NPI-1) are the practitioners; organizations (NPI-2) are the practices, clinics and groups — and 100.0% of organization rows carry an authorized-official name, title and phone, which is the decision-maker for most B2B outreach. A full New York dentist pull is 77.0% individuals / 23.0% organizations. Both = everything.",
            "default": ""
          },
          "practiceStateOnly": {
            "title": "Practice address must be in the selected state",
            "type": "boolean",
            "description": "IMPORTANT. The CMS state filter matches ANY address on a record — practice OR mailing — so a raw \"NY\" sweep also returns providers who merely receive post in New York. Every request already pins the practice address, which removes ZIP-cell overlap entirely, but state still leaks: measured on a full NY dentist pull, 688 of 22,187 rows (3.1%) practised out of state. Leave ON for a clean in-state list; turn OFF to keep every state-linked provider. Ignored in NPI-lookup mode.",
            "default": true
          },
          "activeOnly": {
            "title": "Active providers only",
            "type": "boolean",
            "description": "Drop deactivated NPI records. In practice CMS does not publish deactivated NPIs through the search API at all — measured on an unfiltered 23,467-row pull, 23,467 were active and 0 deactivated — so this is a belt-and-braces filter rather than a real one.",
            "default": true
          },
          "withPhoneOnly": {
            "title": "Only providers with a phone number",
            "type": "boolean",
            "description": "Keep only rows carrying a practice phone. Measured on 23,467 live NY dentist rows, phone fill is 100.0% — unlike the state licence registries, NPPES contact data is complete, so this filter normally removes nothing. Kept for the rare specialty where it does.",
            "default": false
          },
          "maxItems": {
            "title": "💯 Max providers",
            "minimum": 0,
            "type": "integer",
            "description": "Stop after this many unique providers. THIS IS YOUR COST CEILING: you are billed $0.002 per provider returned, so 100 = $0.20 and 10,000 = $20. Duplicates are dropped before billing and never count against it. Defaults to 100 so an API/MCP call that omits it can never bill a surprise — raise it for a real bulk pull. Set 0 for no cap — only with a scope you have already sized, since a nationwide specialty can run into the hundreds of thousands.",
            "default": 100
          },
          "maxRequests": {
            "title": "Max API requests",
            "minimum": 10,
            "type": "integer",
            "description": "Hard ceiling on calls to the CMS API — compute, not billing. Roughly one request per 200 providers, plus one probe per empty slice: the complete 22,187-row New York dentist pull took 278 requests, and a dense single ZIP (10016 + Student, 2,653 providers) took 689.",
            "default": 20000
          },
          "concurrency": {
            "title": "Concurrent slices",
            "minimum": 1,
            "maximum": 8,
            "type": "integer",
            "description": "How many slices to fetch at once (1–8). 4 is the measured balance and the default; the CMS API is behind CloudFront and a high sustained rate from one egress IP gets rate-blocked, which is why the proxy below is on by default. Raise it only if you also leave the proxy on.",
            "default": 4
          },
          "requestDelayMs": {
            "title": "Delay between pages (ms)",
            "minimum": 0,
            "maximum": 10000,
            "type": "integer",
            "description": "Pause between paginated requests inside one slice. 150 ms held a sustained-load test of 38/38 consecutive calls (100%) at 1.04 req/s through the Apify datacenter proxy.",
            "default": 150
          },
          "proxyConfiguration": {
            "title": "🌐 Proxy",
            "type": "object",
            "description": "Apify datacenter proxy, ON by default and recommended. The NPPES API needs no login, no API key and no residential IPs, but it sits behind CloudFront with a rate rule: during this Actor's own ZIP-mapping sweep a single un-proxied IP was blocked after roughly 5,600 calls and kept returning HTML 403 pages. The rotating datacenter pool held 38/38 consecutive calls with no block; RESIDENTIAL also works, is about 2× slower, and is not needed.",
            "default": {
              "useApifyProxy": true
            }
          }
        }
      },
      "runsResponseSchema": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "actId": {
                "type": "string"
              },
              "userId": {
                "type": "string"
              },
              "startedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "finishedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "status": {
                "type": "string",
                "example": "READY"
              },
              "meta": {
                "type": "object",
                "properties": {
                  "origin": {
                    "type": "string",
                    "example": "API"
                  },
                  "userAgent": {
                    "type": "string"
                  }
                }
              },
              "stats": {
                "type": "object",
                "properties": {
                  "inputBodyLen": {
                    "type": "integer",
                    "example": 2000
                  },
                  "rebootCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "restartCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "resurrectCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "computeUnits": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "options": {
                "type": "object",
                "properties": {
                  "build": {
                    "type": "string",
                    "example": "latest"
                  },
                  "timeoutSecs": {
                    "type": "integer",
                    "example": 300
                  },
                  "memoryMbytes": {
                    "type": "integer",
                    "example": 1024
                  },
                  "diskMbytes": {
                    "type": "integer",
                    "example": 2048
                  }
                }
              },
              "buildId": {
                "type": "string"
              },
              "defaultKeyValueStoreId": {
                "type": "string"
              },
              "defaultDatasetId": {
                "type": "string"
              },
              "defaultRequestQueueId": {
                "type": "string"
              },
              "buildNumber": {
                "type": "string",
                "example": "1.0.0"
              },
              "containerUrl": {
                "type": "string"
              },
              "usage": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "integer",
                    "example": 1
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "usageTotalUsd": {
                "type": "number",
                "example": 0.00005
              },
              "usageUsd": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "number",
                    "example": 0.00005
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}