{"v":"<h2 id=\"user-content-proposal-use-a-local-copy-of-the-nppes-file-not-the-live-api\" dir=\"auto\">Proposal: use a local copy of the NPPES file, not the live API<\/h2>\n<p dir=\"auto\">CMS publishes the whole NPI registry as a free download (<a href=\"https:\/\/download.cms.gov\/nppes\/NPI_Files.html\" rel=\"nofollow\">https:\/\/download.cms.gov\/nppes\/NPI_Files.html<\/a>): a <strong>full file each month<\/strong>, a <strong>weekly update file<\/strong>, and a <strong>monthly list of deactivated NPIs<\/strong>. We can load it into our own table and search that table, so a visit never calls out to anything.<\/p>\n<p dir=\"auto\"><strong>Import<\/strong> (<code>scripts\/import-npi.php<\/code>, run on a monthly timer, then weekly for updates):<\/p>\n<ul dir=\"auto\">\n<li>Stream the CSV inside the zip. The full file is about 9 GB with 300+ columns, so read it row by row and keep only what we use.<\/li>\n<li>Keep <strong>individuals<\/strong> (entity type 1) whose practice location is in <strong>Texas<\/strong>, plus <strong>organisations<\/strong> (entity type 2) with a pharmacy taxonomy (<code>3336*<\/code>), which covers E1 as well.<\/li>\n<li>Columns to keep: NPI, last\/first\/middle name, credential, primary taxonomy (shown as specialty), practice address, city, ZIP, phone, fax, deactivation date.<\/li>\n<li>Upsert by NPI. Mark deactivated NPIs inactive rather than deleting them, so an old visit still resolves to the doctor it named.<\/li>\n<li>New table <code>npi_provider<\/code> via <code>migrations\/<\/code>. It holds only public data, so it is stored in plaintext with no PHI. Index it on (last name, first name) and ZIP.<\/li>\n<\/ul>\n<p dir=\"auto\"><strong>Lookup<\/strong> (<code>\/do\/npiSearch<\/code>, gated like the visit screens):<\/p>\n<ul dir=\"auto\">\n<li>Staff type a last name and optionally a first name, and can narrow by city or ZIP. We return up to about 20 matches showing name, credential, specialty and city. Staff pick one, address and phone fill in, and staff can still edit them.<\/li>\n<li>Searching by name alone isn&#39;t precise enough for common surnames. Narrowing by city or ZIP fixes that. Defaulting to the client&#39;s own ZIP would also work, and it is safe because the search stays on our server.<\/li>\n<li>Store the <strong>NPI<\/strong> with the answer, not just the address text, so we can trace which record was picked.<\/li>\n<\/ul>\n<p dir=\"auto\"><strong>Why a download beats the API:<\/strong> nothing about the client, not even the doctor&#39;s name, leaves our server. Production needs no outbound access at visit time. Search speed doesn&#39;t depend on CMS being up. The weekly update file keeps us at most a week behind the registry.<\/p>\n<p dir=\"auto\">The open question for the customer still applies: if they keep their own list of doctors, we could load it into the same table as an extra source.<\/p>\n"}