{
 "openapi": "3.1.0",
 "info": {
  "title": "FindADoctor.si API",
  "version": "2026-10-13.4",
  "description": "Read-only JSON API with the same tools as the MCP server. No sign-up needed. Not medical advice; in an emergency call 911. Responses list the main fields (components.schemas); other fields may appear, so ignore fields you do not know. Fields without data may be missing or null.",
  "x-llms-txt": "https://api.findadoctor.si/llms.txt"
 },
 "servers": [
  {
   "url": "https://api.findadoctor.si"
  }
 ],
 "components": {
  "schemas": {
   "Provider": {
    "type": "object",
    "properties": {
     "name": {
      "type": "string"
     },
     "url": {
      "type": "string"
     },
     "data_version": {
      "type": "string",
      "description": "database version, e.g. public-2026-10-12.2"
     }
    }
   },
   "Error": {
    "type": "object",
    "properties": {
     "error": {
      "type": "string",
      "enum": [
       "bad_args",
       "too_slow",
       "daily_limit",
       "rate_limited",
       "busy",
       "unavailable",
       "cross_site",
       "not_found",
       "internal",
       "sign_in_required",
       "invalid_token"
      ],
      "description": "machine-readable kind"
     },
     "message": {
      "type": "string",
      "description": "what happened and what to do next"
     }
    },
    "required": [
     "error",
     "message"
    ]
   },
   "DailyLimit": {
    "type": "object",
    "properties": {
     "limit_per_day": {
      "type": "integer"
     },
     "opened_today": {
      "type": "integer"
     },
     "left_today": {
      "type": "integer"
     },
     "left_out_of_this_reply": {
      "type": "integer"
     },
     "message": {
      "type": "string"
     }
    },
    "description": "Present when the daily doctor limit is near or reached for this caller."
   },
   "DoctorListing": {
    "type": "object",
    "properties": {
     "rank": {
      "type": "integer"
     },
     "doctor_id": {
      "type": "string",
      "pattern": "^dr_[0-9a-z]{12}$",
      "description": "use with get_doctor"
     },
     "name": {
      "type": "string"
     },
     "degree": {
      "type": "string",
      "description": "e.g. MD, DO"
     },
     "npi": {
      "type": "string",
      "description": "10-digit NPI"
     },
     "specialty": {
      "type": "string"
     },
     "specialty_source": {
      "type": "string"
     },
     "hospital_website_specialties": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "site": {
         "type": "string"
        },
        "specialties": {
         "type": "array",
         "items": {
          "type": "string"
         }
        }
       }
      },
      "description": "departments listed on the doctor's hospital website (up to 2 sites)"
     },
     "listed_on_childrens_hospital_website": {
      "type": "boolean"
     },
     "city": {
      "type": "string"
     },
     "state": {
      "type": "string"
     },
     "distance_miles": {
      "type": "number",
      "description": "from the searched place, when searching near a place"
     },
     "match_basis": {
      "type": "string",
      "enum": [
       "direct_evidence",
       "specialty_fit",
       "other"
      ],
      "description": "why this doctor matched a condition or procedure"
     },
     "warnings": {
      "type": "array",
      "items": {
       "type": "string"
      },
      "description": "e.g. excluded from federal programs, opted out of Medicare"
     },
     "detail_has": {
      "type": "array",
      "items": {
       "type": "string"
      },
      "description": "which kinds of evidence get_doctor will show for this doctor (not the evidence itself), e.g. listed_focus_areas, procedure_volume_for_this_need, phone, languages"
     }
    },
    "required": [
     "rank",
     "doctor_id",
     "name"
    ]
   },
   "SearchResult": {
    "type": "object",
    "properties": {
     "provider": {
      "$ref": "#/components/schemas/Provider"
     },
     "before_answering": {
      "type": "string",
      "description": "read this before answering the person"
     },
     "interpreted": {
      "type": "object",
      "properties": {
       "condition_mesh": {
        "type": "array",
        "items": {
         "type": "object",
         "properties": {
          "mesh_ui": {
           "type": "string"
          },
          "name": {
           "type": "string"
          },
          "match": {
           "type": "string"
          }
         }
        },
        "description": "standard medical terms (MeSH) the condition was read as"
       },
       "volume_from_procedure_groups": {
        "type": "array",
        "items": {
         "type": "string"
        }
       },
       "location": {
        "type": "object",
        "properties": {
         "state": {
          "type": "string"
         },
         "city": {
          "type": "string"
         },
         "near_zip3_areas": {
          "type": "array",
          "items": {
           "type": "string"
          },
          "description": "near_zip without within_miles: whole 3-digit ZIP areas"
         },
         "center": {
          "type": "array",
          "items": {
           "type": "string"
          },
          "description": "within_miles: the place the distance is measured from"
         },
         "within_miles": {
          "type": "number"
         },
         "zip_codes_in_area": {
          "type": "integer"
         },
         "note": {
          "type": "string"
         }
        },
        "description": "state/city/near_zip3_areas without within_miles; center/within_miles/zip_codes_in_area with it"
       },
       "specialties": {
        "type": "array",
        "items": {
         "type": "string"
        },
        "description": "specialties searched"
       },
       "specialties_note": {
        "type": "string"
       },
       "patient": {
        "type": "string"
       },
       "medicare_patient": {
        "type": "string"
       },
       "narrower_terms_included": {
        "type": "integer",
        "description": "how many narrower MeSH terms were searched too"
       },
       "broader_terms_included": {
        "type": "array",
        "items": {
         "type": "string"
        },
        "description": "broader MeSH terms also searched"
       },
       "specialty_fit_basis": {
        "type": "string"
       },
       "patient_mix_categories": {
        "type": "array",
        "items": {
         "type": "string"
        }
       },
       "prescribing_categories": {
        "type": "array",
        "items": {
         "type": "string"
        }
       },
       "language": {
        "type": [
         "string",
         "object"
        ]
       },
       "specialty_fit": {
        "type": "array",
        "items": {
         "type": "object",
         "properties": {
          "specialty_id": {
           "type": "string"
          },
          "share_of_doctors_with_this_focus_pct": {
           "type": "integer"
          }
         }
        }
       },
       "left_out": {
        "type": "string"
       }
      },
      "description": "how the request was read; check it matches what the person asked. Other keys may appear"
     },
     "total_matches": {
      "type": "integer"
     },
     "offset": {
      "type": "integer"
     },
     "results": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/DoctorListing"
      }
     },
     "warnings": {
      "type": "array",
      "items": {
       "type": "string"
      }
     },
     "next_step": {
      "type": "string"
     }
    },
    "required": [
     "results"
    ]
   },
   "Doctor": {
    "type": "object",
    "properties": {
     "provider": {
      "$ref": "#/components/schemas/Provider"
     },
     "found": {
      "type": "boolean"
     },
     "doctor_id": {
      "type": "string",
      "pattern": "^dr_[0-9a-z]{12}$"
     },
     "daily_doctor_limit": {
      "$ref": "#/components/schemas/DailyLimit"
     },
     "warnings": {
      "type": "array",
      "items": {
       "type": "string"
      },
      "description": "read first: e.g. opted out of Medicare, excluded from federal programs, probably not a physician"
     },
     "non_physician": {
      "type": "string",
      "description": "present when the NPI record is probably not a physician (e.g. nurse practitioner)"
     },
     "childrens_hospital_doctor": {
      "type": "string",
      "description": "present when listed on a children's hospital's own website although the registered specialty is an adult one"
     },
     "npi": {
      "type": "string"
     },
     "name": {
      "type": "string"
     },
     "degree": {
      "type": "string"
     },
     "gender": {
      "type": "string"
     },
     "specialty": {
      "type": "string"
     },
     "registered_specialty": {
      "type": "object",
      "properties": {
       "npi_taxonomy": {
        "type": "string"
       },
       "cms_specialty": {
        "type": "string"
       },
       "cms_secondary_specialties": {
        "type": "string"
       },
       "specialty_matched_by": {
        "type": "string"
       }
      }
     },
     "phone": {
      "type": "string"
     },
     "phone_source": {
      "type": "string",
      "description": "where the phone number comes from and its date"
     },
     "phone_address": {
      "type": "string"
     },
     "phone_note": {
      "type": "string"
     },
     "contact_note": {
      "type": "string"
     },
     "accepting_new_patients": {
      "type": [
       "boolean",
       "null"
      ],
      "description": "what the doctor's hospital website said; confirm with the office"
     },
     "accepting_new_patients_source": {
      "type": "string"
     },
     "practice_locations": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "address": {
         "type": "string"
        },
        "phone": {
         "type": "string"
        },
        "source": {
         "type": "string"
        },
        "phone_note": {
         "type": "string"
        },
        "direct_phone_npi_registry": {
         "type": "string"
        }
       }
      }
     },
     "old_npi_registry_address": {
      "type": "object",
      "properties": {
       "address": {
        "type": "string"
       },
       "phone": {
        "type": "string"
       },
       "note": {
        "type": "string"
       }
      },
      "description": "the NPI registry's self-reported address when it is more than 60 miles from every current CMS address and not updated for over a year: probably out of date and not used for location searches"
     },
     "medical_school": {
      "type": "string"
     },
     "graduation_year": {
      "type": "string"
     },
     "telehealth_cms": {
      "type": "boolean"
     },
     "groups_cms": {
      "type": "array",
      "items": {
       "type": "string"
      }
     },
     "hospitals_cms": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "name": {
         "type": "string"
        },
        "city": {
         "type": "string"
        },
        "state": {
         "type": "string"
        },
        "cms_star": {
         "type": "integer"
        }
       }
      }
     },
     "medicare_2024": {
      "type": "object",
      "properties": {
       "patients": {
        "type": "integer"
       },
       "avg_patient_age": {
        "type": "integer"
       },
       "billed_as": {
        "type": "string"
       },
       "patient_mix_high_vs_peers": {
        "type": "array",
        "items": {
         "type": "object"
        }
       }
      }
     },
     "signature_procedures_2024": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "procedure_id": {
         "type": "string"
        },
        "label": {
         "type": "string"
        },
        "medicare_patient_days": {
         "type": "integer"
        },
        "national_rank": {
         "type": "integer"
        },
        "national_of": {
         "type": "integer"
        },
        "top_pct": {
         "type": "number"
        },
        "state": {
         "type": "string"
        },
        "state_rank": {
         "type": "integer"
        },
        "state_of": {
         "type": "integer"
        },
        "national_median": {
         "type": "number"
        }
       }
      },
      "description": "Medicare 2024 procedure volumes with national and state ranks"
     },
     "prescribing_2024": {
      "type": [
       "object",
       "string"
      ],
      "description": "Medicare Part D 2024 summary; a sentence when there is no record"
     },
     "prescribing_signals_2024": {
      "type": "object",
      "description": "medicine groups this doctor prescribes clearly more than peers (Part D 2024)"
     },
     "industry_payments": {
      "type": [
       "object",
       "string"
      ],
      "description": "Open Payments summary; a sentence when none were reported"
     },
     "industry_research_as_principal_investigator": {
      "type": "object",
      "description": "industry-sponsored research led by this doctor (Open Payments)"
     },
     "mips_2024": {
      "type": "object",
      "description": "CMS quality program (MIPS) 2024 score"
     },
     "license_state": {
      "type": "string"
     },
     "record_status": {
      "type": "string"
     },
     "npi_registry_last_updated": {
      "type": "string"
     },
     "npi_enumerated": {
      "type": "string"
     },
     "oig_exclusion": {
      "type": [
       "object",
       "null"
      ],
      "description": "present when excluded from federal health programs"
     },
     "medicare_opt_out": {
      "type": [
       "object",
       "null"
      ],
      "description": "present when the doctor opted out of Medicare"
     },
     "hospital_websites": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "site": {
         "type": "string"
        },
        "checked": {
         "type": "string",
         "description": "date the page was read"
        },
        "urls": {
         "type": "array",
         "items": {
          "type": "string"
         }
        },
        "name_on_page": {
         "type": "string"
        },
        "matched_by": {
         "type": "string",
         "description": "how the page was matched to this doctor"
        },
        "specialties": {
         "type": "array",
         "items": {
          "type": "string"
         }
        },
        "languages": {
         "type": "array",
         "items": {
          "type": "string"
         }
        },
        "education": {
         "type": "array",
         "items": {
          "type": "string"
         }
        },
        "certifications": {
         "type": "array",
         "items": {
          "type": "string"
         }
        },
        "accepting_new_patients": {
         "type": "boolean"
        },
        "languages_note": {
         "type": "string"
        },
        "focus_mesh": {
         "type": "array",
         "items": {
          "type": "object",
          "properties": {
           "mesh": {
            "type": "string",
            "description": "standard medical term (MeSH)"
           },
           "from": {
            "type": "string",
            "enum": [
             "listed",
             "listed_general",
             "statement"
            ],
            "description": "listed = the page's focus list; listed_general = general wording on that list; statement = the doctor's own profile text (counts 0.75)"
           }
          }
         },
         "description": "focus areas on the page, as MeSH terms (open urls for the page's own words)"
        },
        "phones": {
         "type": "array",
         "items": {
          "type": "string"
         },
         "description": "office phones on the page"
        },
        "addresses": {
         "type": "array",
         "items": {
          "type": "object",
          "properties": {
           "street": {
            "type": "string"
           },
           "city": {
            "type": "string"
           },
           "state": {
            "type": "string"
           },
           "zip": {
            "type": "string"
           }
          }
         },
         "description": "office addresses on the page (street may be empty)"
        },
        "insurance_listed": {
         "type": "object",
         "properties": {
          "checked": {
           "type": "string"
          },
          "url": {
           "type": "string"
          },
          "items_listed": {
           "type": "integer"
          },
          "by_insurer": {
           "type": "object"
          },
          "other": {
           "type": "array",
           "items": {
            "type": "string"
           }
          },
          "note": {
           "type": "string"
          }
         },
         "description": "insurers the hospital website listed on that date: a lead, call to confirm"
        }
       }
      },
      "description": "facts read from the doctor's hospital website"
     },
     "hospital_profile": {
      "type": "object",
      "properties": {
       "pilot": {
        "type": "string",
        "description": "which early check this comes from"
       },
       "status": {
        "type": "string"
       },
       "note": {
        "type": "string"
       },
       "trainee": {
        "type": "boolean"
       },
       "sources": {
        "type": "array",
        "items": {
         "type": "object",
         "properties": {
          "site": {
           "type": "string"
          },
          "url": {
           "type": "string"
          }
         }
        }
       },
       "focus_mesh": {
        "type": "array",
        "items": {
         "type": "object",
         "properties": {
          "phrase": {
           "type": "string",
           "description": "same as mesh_term in this edition"
          },
          "mesh_term": {
           "type": "string"
          },
          "from": {
           "type": "string"
          },
          "site": {
           "type": "string"
          }
         }
        }
       },
       "languages": {
        "type": "array",
        "items": {
         "type": "string"
        }
       },
       "phone": {
        "type": [
         "string",
         "null"
        ]
       },
       "phones_on_pages": {
        "type": "array",
        "items": {
         "type": "object",
         "properties": {
          "site": {
           "type": "string"
          },
          "phone": {
           "type": "string"
          },
          "office": {
           "type": "string"
          }
         }
        }
       },
       "departments_and_programs": {
        "type": "array",
        "items": {
         "type": "string"
        }
       },
       "pages_no_longer_exist": {
        "type": "array",
        "items": {
         "type": "string"
        }
       },
       "pages_no_longer_exist_note": {
        "type": "string"
       },
       "insurance_memorial_hermann": {
        "type": "array",
        "items": {
         "type": "string"
        }
       },
       "insurance_note": {
        "type": "string"
       }
      },
      "description": "Houston pediatric endocrinology only (an early check of hospital websites, 2026-10-08); hospital_websites has the wider read"
     },
     "caveats": {
      "type": "array",
      "items": {
       "type": "string"
      },
      "description": "read before answering"
     },
     "not_collected": {
      "type": "array",
      "items": {
       "type": "string"
      }
     },
     "more": {
      "type": "string"
     },
     "record": {
      "type": "object",
      "description": "detail=full only: the official record as read from NPPES and CMS"
     },
     "official_extras": {
      "type": "object",
      "description": "detail=full only: full prescribing, payments and MIPS data"
     },
     "database_caveats": {
      "type": "array",
      "items": {
       "type": "string"
      },
      "description": "detail=full only"
     }
    },
    "required": [
     "found"
    ],
    "description": "Evidence for one doctor. found is false when the doctor_id or NPI is unknown (HTTP 404)."
   },
   "DoctorBatch": {
    "type": "object",
    "properties": {
     "daily_doctor_limit": {
      "$ref": "#/components/schemas/DailyLimit"
     },
     "doctors": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/Doctor"
      }
     },
     "not_returned_yet": {
      "type": "object",
      "properties": {
       "message": {
        "type": "string"
       },
       "doctors": {
        "type": "array",
        "items": {
         "type": "object",
         "properties": {
          "doctor_id": {
           "type": "string"
          }
         }
        }
       }
      },
      "description": "did not fit in this reply; already counted, ask again for them at no extra cost"
     },
     "left_out": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "doctor_id": {
         "type": "string"
        },
        "reason": {
         "type": "string"
        }
       }
      },
      "description": "not opened: daily doctor limit"
     },
     "not_found": {
      "type": "array",
      "items": {
       "type": "string"
      },
      "description": "doctor_ids that do not exist"
     }
    },
    "required": [
     "doctors"
    ]
   }
  },
  "securitySchemes": {
   "accountKey": {
    "type": "http",
    "scheme": "bearer",
    "description": "Optional account key (dk_...) for a larger daily doctor limit."
   }
  }
 },
 "security": [
  {},
  {
   "accountKey": []
  }
 ],
 "paths": {
  "/api/v1/search": {
   "get": {
    "operationId": "searchDoctors",
    "summary": "Free short list of doctors for a need",
    "description": "Free short list of US doctors for a need; use it first whenever the person needs a US doctor: a specialist who focuses on a condition near a place (for a metro area use within_miles), who does the most of a procedure (sort='volume': Medicare 2024 counts with national and state ranks), or checking named doctors (name=...). Each result: doctor_id, name, degree, NPI, specialty (with its source) and the specialties their hospital website lists, city, state, distance_miles, warnings (federal exclusion list, Medicare opt-out, probably not a physician) and detail_has (what get_doctor adds for this doctor). With a condition or procedure, match_basis says whether the doctor has direct evidence for it (a listed focus, procedure volume or many such patients) or only a fitting specialty. Results are ranked by evidence of focus and experience for the need, not by quality or outcomes. Then call get_doctor with the doctor_ids you are considering (up to 10 at once) for the evidence. Up to 10 results per search and paging stops at 30: narrow the need or the place instead of paging. Conditions are matched to NLM MeSH terms (narrower terms and the general condition above it count too), common names such as 'afib' and clinical abbreviations such as 'CAD'; use English medical names when you can. Pass medicare_patient=true for anyone 65 or older or on Medicare. language= and accepting_new_patients=true filter by hospital-website pages, which most doctors do not have here; insurance cannot be filtered: if the person needs a specific plan, language or new-patient availability, find candidates on the web first when you can browse, then check them here by name. Read warnings.",
    "parameters": [
     {
      "name": "condition",
      "in": "query",
      "required": false,
      "description": "Disease, symptom or problem, e.g. 'atrial fibrillation', 'knee osteoarthritis', 'breast cancer', 'migraine'.",
      "schema": {
       "type": "string",
       "maxLength": 200
      }
     },
     {
      "name": "procedure",
      "in": "query",
      "required": false,
      "description": "Procedure or surgery, e.g. 'knee replacement', 'TAVR', 'cataract surgery', 'Mohs surgery'. See list_procedures.",
      "schema": {
       "type": "string",
       "maxLength": 200
      }
     },
     {
      "name": "specialty",
      "in": "query",
      "required": false,
      "description": "Specialty id, name, title or family, e.g. 'cardiology', 'cardiologist', 'ENT', 'GI', 'OB/GYN', 'primary care', 'pediatric neurology', 'palliative care', 'orthopaedic-surgery'. See list_specialties.",
      "schema": {
       "type": "string",
       "maxLength": 200
      }
     },
     {
      "name": "state",
      "in": "query",
      "required": false,
      "description": "US state, 2-letter code (MA) or full name. With within_miles it only identifies the city (the radius can cross state lines) and is ignored with near_zip.",
      "schema": {
       "type": "string",
       "maxLength": 200
      }
     },
     {
      "name": "city",
      "in": "query",
      "required": false,
      "description": "City of a practice location. Alone it matches only that exact city name (suburbs are separate cities); for a metro area add within_miles, e.g. city='Dallas', state='TX', within_miles=25.",
      "schema": {
       "type": "string",
       "maxLength": 200
      }
     },
     {
      "name": "near_zip",
      "in": "query",
      "required": false,
      "description": "One or more US ZIP codes, comma-separated. With within_miles: practices within that distance of these ZIPs. Without it: practices in the same 3-digit ZIP areas (one area can be only part of a big metro, e.g. Brooklyn 112 but not Manhattan 100-102).",
      "schema": {
       "type": "string",
       "maxLength": 200
      }
     },
     {
      "name": "within_miles",
      "in": "query",
      "required": false,
      "description": "Search radius in miles around city (give state too) or near_zip, e.g. 25 for a metro area, 5-10 in a dense city such as New York City, Chicago, San Francisco or Boston (25 there spans the whole metro); includes suburbs and can cross state lines. Each result then has distance_miles.",
      "schema": {
       "type": "integer",
       "minimum": 1,
       "maximum": 100
      }
     },
     {
      "name": "patient",
      "in": "query",
      "required": false,
      "description": "adult removes child-only specialties; child lists pediatric specialists and doctors listed on a children's hospital's own website (listed_on_childrens_hospital_website in results) first, unless there is evidence that they mainly treat adults.",
      "schema": {
       "type": "string",
       "enum": [
        "adult",
        "child"
       ]
      }
     },
     {
      "name": "accepting_new_patients",
      "in": "query",
      "required": false,
      "description": "true keeps only doctors listed as accepting new patients by their hospital website (others are unknown, not 'no'; confirm when booking).",
      "schema": {
       "type": "boolean"
      }
     },
     {
      "name": "language",
      "in": "query",
      "required": false,
      "description": "Language the doctor speaks other than English, e.g. 'Spanish', 'Mandarin', 'Vietnamese' (several: 'Spanish, Portuguese' = any of them). Keeps only doctors whose hospital website lists it (one site lists office staff's languages too); most doctors have no such page here, so if few results, also search the web.",
      "schema": {
       "type": "string",
       "maxLength": 200
      }
     },
     {
      "name": "gender",
      "in": "query",
      "required": false,
      "description": "Doctor's gender (NPI registry).",
      "schema": {
       "type": "string",
       "enum": [
        "F",
        "M"
       ]
      }
     },
     {
      "name": "medicare_patient",
      "in": "query",
      "required": false,
      "description": "true for a person 65 or older or on Medicare: leaves out doctors on the CMS Medicare opt-out list (Medicare and Medicare Advantage plans will not pay them except for emergency or urgent care). Without it such doctors carry a WARNING in warnings.",
      "schema": {
       "type": "boolean"
      }
     },
     {
      "name": "text",
      "in": "query",
      "required": false,
      "description": "Free-text filter over specialty, medical school, hospitals, medical group and procedure groups, e.g. a hospital name. Insurance is not searchable (some hospital-website lists are shown in results, not filtered); for languages use language.",
      "schema": {
       "type": "string",
       "maxLength": 200
      }
     },
     {
      "name": "name",
      "in": "query",
      "required": false,
      "description": "Part of the doctor's name. Name searches also return NPI records that are probably not physicians (nurse practitioners, physician assistants, etc.), marked with a WARNING; other searches leave them out.",
      "schema": {
       "type": "string",
       "maxLength": 200
      }
     },
     {
      "name": "sort",
      "in": "query",
      "required": false,
      "description": "evidence (default), volume (best Medicare procedure rank first) or standing (named principal investigator on industry-sponsored research first).",
      "schema": {
       "type": "string",
       "enum": [
        "evidence",
        "volume",
        "standing"
       ]
      }
     },
     {
      "name": "limit",
      "in": "query",
      "required": false,
      "description": "Default 10.",
      "schema": {
       "type": "integer",
       "minimum": 1,
       "maximum": 10
      }
     },
     {
      "name": "offset",
      "in": "query",
      "required": false,
      "description": "For paging (at most 20, so 30 results in all: narrow the search instead of paging further).",
      "schema": {
       "type": "integer",
       "minimum": 0,
       "maximum": 20
      }
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result (same as the MCP tool's result)",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/SearchResult"
        },
        "example": {
         "provider": {
          "name": "FindADoctor.si",
          "url": "https://findadoctor.si",
          "data_version": "public-2026-10-12.2"
         },
         "before_answering": "This is the free short list: who the doctors are, not the evidence. ...",
         "interpreted": {
          "condition_mesh": [
           {
            "mesh_ui": "D001281",
            "name": "Atrial Fibrillation",
            "match": "exact"
           }
          ],
          "location": {
           "state": "TX",
           "city": "Houston"
          }
         },
         "total_matches": 214,
         "offset": 0,
         "results": [
          {
           "rank": 1,
           "doctor_id": "dr_4k9m2x7qph3t",
           "name": "Jane Example",
           "degree": "MD",
           "npi": "1234567893",
           "specialty": "Cardiac Electrophysiology",
           "specialty_source": "official records (NPI registry, CMS)",
           "city": "Houston",
           "state": "TX",
           "match_basis": "direct_evidence",
           "detail_has": [
            "hospital_website_profile",
            "listed_focus_areas",
            "procedure_volume_for_this_need",
            "phone"
           ]
          }
         ],
         "warnings": [],
         "next_step": "Call get_doctor with doctor_ids (up to 10 at once) ..."
        }
       }
      }
     },
     "400": {
      "description": "bad arguments, or the search was too broad (too_slow): the message says what to change",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "401": {
      "description": "the Authorization header was sent but is invalid or expired (invalid_token): sign in again or send no header; the WWW-Authenticate header points to the sign-in metadata",
      "headers": {
       "WWW-Authenticate": {
        "schema": {
         "type": "string"
        }
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "429": {
      "description": "rate_limited (too many requests) or daily_limit (daily doctor limit reached); the message says when it resets",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "headers": {
       "Retry-After": {
        "description": "seconds to wait",
        "schema": {
         "type": "integer"
        }
       }
      }
     },
     "500": {
      "description": "internal error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "503": {
      "description": "busy or starting (busy, unavailable): retry after Retry-After",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "headers": {
       "Retry-After": {
        "description": "seconds to wait",
        "schema": {
         "type": "integer"
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/doctors/{doctor_id}": {
   "get": {
    "operationId": "getDoctor",
    "summary": "Evidence for one doctor (counted)",
    "description": "doctor_id from a search result. Each different doctor opened counts toward a daily limit (UTC day): 5 a day per network address without an account, 100 a day with an account key; opening a doctor again the same day is free.",
    "parameters": [
     {
      "name": "doctor_id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "pattern": "^dr_[0-9a-z]{12}$"
      }
     },
     {
      "name": "detail",
      "in": "query",
      "schema": {
       "type": "string",
       "enum": [
        "summary",
        "full"
       ]
      },
      "description": "summary (default) or full"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result (same as the MCP tool's result)",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Doctor"
        },
        "example": {
         "provider": {
          "name": "FindADoctor.si",
          "url": "https://findadoctor.si",
          "data_version": "public-2026-10-12.2"
         },
         "found": true,
         "doctor_id": "dr_4k9m2x7qph3t",
         "npi": "1234567893",
         "name": "Jane Example",
         "degree": "MD",
         "specialty": "Cardiac Electrophysiology",
         "registered_specialty": {
          "npi_taxonomy": "Clinical Cardiac Electrophysiology",
          "cms_specialty": "CARDIAC ELECTROPHYSIOLOGY",
          "specialty_matched_by": "crosswalk"
         },
         "phone": "713-555-0100",
         "phone_source": "CMS Doctors and Clinicians file (released 2026-09-10)",
         "practice_locations": [
          {
           "address": "100 Example St, Houston, TX 77030",
           "phone": "713-555-0100",
           "source": "CMS Doctors and Clinicians file"
          }
         ],
         "signature_procedures_2024": [
          {
           "procedure_id": "afib_ablation",
           "label": "Atrial fibrillation catheter ablation",
           "medicare_patient_days": 120,
           "national_rank": 85,
           "national_of": 2400,
           "top_pct": 3.5,
           "state": "TX",
           "state_rank": 6,
           "state_of": 190,
           "national_median": 31.0
          }
         ],
         "hospital_websites": [
          {
           "site": "Example Health",
           "checked": "2026-10-10",
           "urls": [
            "https://www.example.org/doctors/jane-example"
           ],
           "languages": [
            "English",
            "Spanish"
           ],
           "focus_mesh": [
            {
             "mesh_ui": "D001281",
             "name": "Atrial Fibrillation"
            }
           ]
          }
         ],
         "caveats": [
          "Call the office to confirm insurance, languages and new patients before booking."
         ]
        }
       }
      }
     },
     "400": {
      "description": "bad arguments, or the search was too broad (too_slow): the message says what to change",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "401": {
      "description": "the Authorization header was sent but is invalid or expired (invalid_token): sign in again or send no header; the WWW-Authenticate header points to the sign-in metadata",
      "headers": {
       "WWW-Authenticate": {
        "schema": {
         "type": "string"
        }
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "429": {
      "description": "rate_limited (too many requests) or daily_limit (daily doctor limit reached); the message says when it resets",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "headers": {
       "Retry-After": {
        "description": "seconds to wait",
        "schema": {
         "type": "integer"
        }
       }
      }
     },
     "500": {
      "description": "internal error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "503": {
      "description": "busy or starting (busy, unavailable): retry after Retry-After",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "headers": {
       "Retry-After": {
        "description": "seconds to wait",
        "schema": {
         "type": "integer"
        }
       }
      }
     },
     "403": {
      "description": "cross_site: a web page in another site's browser asked for doctor details without an account key",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "404": {
      "description": "unknown doctor_id or NPI",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "found": {
           "type": "boolean",
           "enum": [
            false
           ]
          }
         }
        },
        "example": {
         "found": false
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/doctors": {
   "get": {
    "operationId": "getDoctors",
    "summary": "Evidence for up to 10 doctors, or one by NPI (counted)",
    "description": "Give ids (comma-separated doctor_ids from search results, up to 10) or npi. Each different doctor opened counts toward a daily limit (UTC day): 5 a day per network address without an account, 100 a day with an account key; opening a doctor again the same day is free. When the limit runs out mid-request, the doctors that fit are returned and the rest are listed in left_out. One reply holds about 2-3 doctors (1 with detail=full); the others are listed in not_returned_yet, already counted, so ask again for them at no extra cost. Web pages calling this from a browser need an account key (cross-site requests without Authorization are refused).",
    "parameters": [
     {
      "name": "ids",
      "in": "query",
      "schema": {
       "type": "string"
      },
      "description": "e.g. dr_4k9m2x7qph3t,dr_8w2c5n1kd7ra"
     },
     {
      "name": "npi",
      "in": "query",
      "schema": {
       "type": "string",
       "pattern": "^[0-9]{10}$"
      }
     },
     {
      "name": "detail",
      "in": "query",
      "schema": {
       "type": "string",
       "enum": [
        "summary",
        "full"
       ]
      },
      "description": "summary (default) or full"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result (same as the MCP tool's result)",
      "content": {
       "application/json": {
        "schema": {
         "oneOf": [
          {
           "$ref": "#/components/schemas/DoctorBatch"
          },
          {
           "$ref": "#/components/schemas/Doctor"
          }
         ]
        },
        "example": {
         "doctors": [
          {
           "provider": {
            "name": "FindADoctor.si",
            "url": "https://findadoctor.si",
            "data_version": "public-2026-10-12.2"
           },
           "found": true,
           "doctor_id": "dr_4k9m2x7qph3t",
           "npi": "1234567893",
           "name": "Jane Example",
           "degree": "MD",
           "specialty": "Cardiac Electrophysiology",
           "registered_specialty": {
            "npi_taxonomy": "Clinical Cardiac Electrophysiology",
            "cms_specialty": "CARDIAC ELECTROPHYSIOLOGY",
            "specialty_matched_by": "crosswalk"
           },
           "phone": "713-555-0100",
           "phone_source": "CMS Doctors and Clinicians file (released 2026-09-10)",
           "practice_locations": [
            {
             "address": "100 Example St, Houston, TX 77030",
             "phone": "713-555-0100",
             "source": "CMS Doctors and Clinicians file"
            }
           ],
           "signature_procedures_2024": [
            {
             "procedure_id": "afib_ablation",
             "label": "Atrial fibrillation catheter ablation",
             "medicare_patient_days": 120,
             "national_rank": 85,
             "national_of": 2400,
             "top_pct": 3.5,
             "state": "TX",
             "state_rank": 6,
             "state_of": 190,
             "national_median": 31.0
            }
           ],
           "hospital_websites": [
            {
             "site": "Example Health",
             "checked": "2026-10-10",
             "urls": [
              "https://www.example.org/doctors/jane-example"
             ],
             "languages": [
              "English",
              "Spanish"
             ],
             "focus_mesh": [
              {
               "mesh_ui": "D001281",
               "name": "Atrial Fibrillation"
              }
             ]
            }
           ],
           "caveats": [
            "Call the office to confirm insurance, languages and new patients before booking."
           ]
          }
         ],
         "not_returned_yet": {
          "message": "1 more doctor did not fit in this reply. ...",
          "doctors": [
           {
            "doctor_id": "dr_8w2c5n1kd7ra"
           }
          ]
         }
        }
       }
      }
     },
     "400": {
      "description": "bad arguments, or the search was too broad (too_slow): the message says what to change",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "401": {
      "description": "the Authorization header was sent but is invalid or expired (invalid_token): sign in again or send no header; the WWW-Authenticate header points to the sign-in metadata",
      "headers": {
       "WWW-Authenticate": {
        "schema": {
         "type": "string"
        }
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "429": {
      "description": "rate_limited (too many requests) or daily_limit (daily doctor limit reached); the message says when it resets",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "headers": {
       "Retry-After": {
        "description": "seconds to wait",
        "schema": {
         "type": "integer"
        }
       }
      }
     },
     "500": {
      "description": "internal error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "503": {
      "description": "busy or starting (busy, unavailable): retry after Retry-After",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "headers": {
       "Retry-After": {
        "description": "seconds to wait",
        "schema": {
         "type": "integer"
        }
       }
      }
     },
     "403": {
      "description": "cross_site: a web page in another site's browser asked for doctor details without an account key",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "404": {
      "description": "unknown doctor_id or NPI",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "found": {
           "type": "boolean",
           "enum": [
            false
           ]
          }
         }
        },
        "example": {
         "found": false
        }
       }
      }
     }
    },
    "x-reply-shape": "ids gives DoctorBatch; npi gives one Doctor"
   }
  },
  "/api/v1/terms": {
   "get": {
    "operationId": "lookupTerms",
    "summary": "How the database reads a condition or procedure",
    "parameters": [
     {
      "name": "text",
      "in": "query",
      "required": true,
      "description": "",
      "schema": {
       "type": "string",
       "maxLength": 200
      }
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result (same as the MCP tool's result)",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "provider": {
           "$ref": "#/components/schemas/Provider"
          },
          "text": {
           "type": "string"
          },
          "conditions_mesh": {
           "type": "array",
           "items": {
            "type": "object",
            "properties": {
             "mesh_ui": {
              "type": "string"
             },
             "name": {
              "type": "string"
             },
             "match": {
              "type": "string"
             },
             "doctors_listing_it_as_focus": {
              "type": "integer"
             },
             "entry_terms": {
              "type": "array",
              "items": {
               "type": "string"
              }
             }
            }
           }
          },
          "procedure_groups": {
           "type": "array",
           "items": {
            "type": "object",
            "properties": {
             "procedure_id": {
              "type": "string"
             },
             "label": {
              "type": "string"
             },
             "cpt_codes": {
              "type": "string",
              "description": "several items separated by '; '"
             },
             "also_called": {
              "type": "string",
              "description": "several items separated by '; '"
             }
            }
           }
          },
          "specialties": {
           "type": "array",
           "items": {
            "type": "object"
           }
          },
          "how_to_use": {
           "type": "string"
          }
         }
        }
       }
      }
     },
     "400": {
      "description": "bad arguments, or the search was too broad (too_slow): the message says what to change",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "401": {
      "description": "the Authorization header was sent but is invalid or expired (invalid_token): sign in again or send no header; the WWW-Authenticate header points to the sign-in metadata",
      "headers": {
       "WWW-Authenticate": {
        "schema": {
         "type": "string"
        }
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "429": {
      "description": "rate_limited (too many requests) or daily_limit (daily doctor limit reached); the message says when it resets",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "headers": {
       "Retry-After": {
        "description": "seconds to wait",
        "schema": {
         "type": "integer"
        }
       }
      }
     },
     "500": {
      "description": "internal error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "503": {
      "description": "busy or starting (busy, unavailable): retry after Retry-After",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "headers": {
       "Retry-After": {
        "description": "seconds to wait",
        "schema": {
         "type": "integer"
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/procedures": {
   "get": {
    "operationId": "listProcedures",
    "summary": "The 81 procedure groups with Medicare volumes",
    "responses": {
     "200": {
      "description": "JSON result (same as the MCP tool's result)",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "provider": {
           "$ref": "#/components/schemas/Provider"
          },
          "procedure_groups": {
           "type": "array",
           "items": {
            "type": "object",
            "properties": {
             "procedure_id": {
              "type": "string"
             },
             "label": {
              "type": "string"
             },
             "cpt_codes": {
              "type": "string",
              "description": "several items separated by '; '"
             },
             "also_called": {
              "type": "string",
              "description": "several items separated by '; '"
             },
             "related_mesh": {
              "type": "string",
              "description": "several items separated by '; '"
             },
             "us_physicians_billing_2024": {
              "type": "integer"
             },
             "national_median_per_physician": {
              "type": "number"
             },
             "note": {
              "type": "string"
             }
            }
           }
          },
          "how_to_read": {
           "type": "string"
          }
         }
        }
       }
      }
     },
     "400": {
      "description": "bad arguments, or the search was too broad (too_slow): the message says what to change",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "401": {
      "description": "the Authorization header was sent but is invalid or expired (invalid_token): sign in again or send no header; the WWW-Authenticate header points to the sign-in metadata",
      "headers": {
       "WWW-Authenticate": {
        "schema": {
         "type": "string"
        }
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "429": {
      "description": "rate_limited (too many requests) or daily_limit (daily doctor limit reached); the message says when it resets",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "headers": {
       "Retry-After": {
        "description": "seconds to wait",
        "schema": {
         "type": "integer"
        }
       }
      }
     },
     "500": {
      "description": "internal error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "503": {
      "description": "busy or starting (busy, unavailable): retry after Retry-After",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "headers": {
       "Retry-After": {
        "description": "seconds to wait",
        "schema": {
         "type": "integer"
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/specialties": {
   "get": {
    "operationId": "listSpecialties",
    "summary": "Specialty names",
    "responses": {
     "200": {
      "description": "JSON result (same as the MCP tool's result)",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "provider": {
           "$ref": "#/components/schemas/Provider"
          },
          "specialties": {
           "type": "array",
           "items": {
            "type": "object",
            "properties": {
             "specialty_id": {
              "type": "string"
             },
             "label": {
              "type": "string"
             },
             "family": {
              "type": "string"
             },
             "doctors": {
              "type": "integer"
             }
            }
           }
          },
          "note": {
           "type": "string"
          }
         }
        }
       }
      }
     },
     "400": {
      "description": "bad arguments, or the search was too broad (too_slow): the message says what to change",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "401": {
      "description": "the Authorization header was sent but is invalid or expired (invalid_token): sign in again or send no header; the WWW-Authenticate header points to the sign-in metadata",
      "headers": {
       "WWW-Authenticate": {
        "schema": {
         "type": "string"
        }
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "429": {
      "description": "rate_limited (too many requests) or daily_limit (daily doctor limit reached); the message says when it resets",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "headers": {
       "Retry-After": {
        "description": "seconds to wait",
        "schema": {
         "type": "integer"
        }
       }
      }
     },
     "500": {
      "description": "internal error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "503": {
      "description": "busy or starting (busy, unavailable): retry after Retry-After",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "headers": {
       "Retry-After": {
        "description": "seconds to wait",
        "schema": {
         "type": "integer"
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/about": {
   "get": {
    "operationId": "aboutDatabase",
    "summary": "Sources, build date, coverage, scoring and caveats",
    "responses": {
     "200": {
      "description": "JSON result (same as the MCP tool's result)",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "provider": {
           "$ref": "#/components/schemas/Provider"
          },
          "name": {
           "type": "string"
          },
          "description": {
           "type": "string"
          },
          "built": {
           "type": "string"
          },
          "schema_version": {
           "type": "string"
          },
          "doctors": {
           "type": "integer"
          },
          "physicians": {
           "type": "object",
           "description": "counts by kind of record"
          },
          "hospital_websites": {
           "type": "object",
           "description": "website coverage: doctors, sites, dates read"
          },
          "public_edition_rules": {
           "type": "object",
           "description": "what this public edition leaves out"
          },
          "sources": {
           "type": "array",
           "items": {
            "type": "string"
           }
          },
          "caveats": {
           "type": "array",
           "items": {
            "type": "string"
           }
          },
          "scoring": {
           "type": "string",
           "description": "how search results are ranked"
          },
          "how_to_use": {
           "type": "string"
          },
          "not_collected": {
           "type": "array",
           "items": {
            "type": "string"
           }
          }
         }
        }
       }
      }
     },
     "400": {
      "description": "bad arguments, or the search was too broad (too_slow): the message says what to change",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "401": {
      "description": "the Authorization header was sent but is invalid or expired (invalid_token): sign in again or send no header; the WWW-Authenticate header points to the sign-in metadata",
      "headers": {
       "WWW-Authenticate": {
        "schema": {
         "type": "string"
        }
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "429": {
      "description": "rate_limited (too many requests) or daily_limit (daily doctor limit reached); the message says when it resets",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "headers": {
       "Retry-After": {
        "description": "seconds to wait",
        "schema": {
         "type": "integer"
        }
       }
      }
     },
     "500": {
      "description": "internal error",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "503": {
      "description": "busy or starting (busy, unavailable): retry after Retry-After",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "headers": {
       "Retry-After": {
        "description": "seconds to wait",
        "schema": {
         "type": "integer"
        }
       }
      }
     }
    }
   }
  }
 }
}