{
 "openapi": "3.1.0",
 "info": {
  "title": "FindADoctor.si New Zealand API",
  "version": "nz-2026-10-15.2",
  "description": "Read-only JSON API with the same tools as the MCP server. No sign-up needed. Not medical advice; in an emergency call 111. Responses list the main fields (components.schemas); other fields may appear, so ignore fields you do not know. Fields without data are left out.",
  "x-llms-txt": "https://api-nz.findadoctor.si/llms.txt"
 },
 "servers": [
  {
   "url": "https://api-nz.findadoctor.si"
  }
 ],
 "components": {
  "schemas": {
   "Provider": {
    "type": "object",
    "properties": {
     "name": {
      "type": "string"
     },
     "url": {
      "type": "string"
     },
     "data_version": {
      "type": "string"
     }
    },
    "description": "who publishes this data and which build"
   },
   "Error": {
    "type": "object",
    "properties": {
     "error": {
      "type": "string",
      "description": "bad_args, too_slow, daily_limit, rate_limited, busy, unavailable, sign_in_required, invalid_token, cross_site, not_found, internal"
     },
     "message": {
      "type": "string",
      "description": "what to change or when to retry"
     }
    }
   },
   "SearchItem": {
    "type": "object",
    "properties": {
     "rank": {
      "type": "integer"
     },
     "doctor_id": {
      "type": "string",
      "pattern": "^nz_[0-9a-z]{12}$",
      "description": "use with get_doctor"
     },
     "name": {
      "type": "string"
     },
     "kind": {
      "type": "string",
      "description": "Healthpoint's label for the person"
     },
     "specialties": {
      "type": "array",
      "items": {
       "type": "string"
      }
     },
     "vocational_scope": {
      "type": "string"
     },
     "cities": {
      "type": "array",
      "items": {
       "type": "string"
      }
     },
     "sectors": {
      "type": "array",
      "items": {
       "type": "string",
       "enum": [
        "private",
        "public"
       ]
      }
     },
     "match_basis": {
      "type": "string",
      "enum": [
       "stated_focus",
       "services_listed",
       "shared_service_listed",
       "specialty",
       "specialty_for_symptom",
       "profile_text",
       "partial"
      ],
      "description": "with a need: how directly the doctor's own listing matches it (shared_service_listed = only a hospital department or large group page they are linked to lists it; specialty_for_symptom = the need is a symptom few doctors list and their specialty usually sees it)"
     },
     "place_match": {
      "type": "string",
      "enum": [
       "city_or_address",
       "city_in_region",
       "address_contains",
       "region_page_only"
      ],
      "description": "with a place: city or address part; a town inside the region you gave; inside an address (maybe a street name); or only on Healthpoint's region page (often visiting from elsewhere)"
     },
     "specialist_since": {
      "type": "integer",
      "description": "year first on the New Zealand specialist (vocational) register"
     },
     "recognition": {
      "type": "array",
      "items": {
       "type": "string",
       "description": "New Zealand honours (e.g. 'MNZM, 2019 New Year Honours') or a University of Auckland title"
      }
     },
     "listing": {
      "type": "string",
      "enum": [
       "medical_council_register_only"
      ],
      "description": "medical_council_register_only = on the register but no clinic listing here"
     },
     "warnings": {
      "type": "array",
      "items": {
       "type": "string"
      }
     },
     "detail_has": {
      "type": "array",
      "items": {
       "type": "string",
       "description": "what get_doctor adds for this doctor"
      }
     }
    }
   },
   "SearchResult": {
    "type": "object",
    "properties": {
     "provider": {
      "$ref": "#/components/schemas/Provider"
     },
     "before_answering": {
      "type": "string"
     },
     "total_matches": {
      "type": "integer"
     },
     "offset": {
      "type": "integer"
     },
     "results": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/SearchItem"
      }
     },
     "next_step": {
      "type": "string"
     },
     "note": {
      "type": "string"
     },
     "specialty_read_as": {
      "type": "array",
      "items": {
       "type": "string",
       "description": "with specialty: the specialty names searched"
      }
     },
     "specialty_note": {
      "type": "string"
     },
     "place_note": {
      "type": "string",
      "description": "with a town or suburb: how many more doctors match with the wider region as the place (another town of the region, or only on its Healthpoint page), and the place to search to include them"
     },
     "need_note": {
      "type": "string",
      "description": "with a need: when it is a symptom, which specialties were added (specialty_for_symptom); or that no doctor lists all its words"
     },
     "gender_note": {
      "type": "string",
      "description": "with gender: how many doctors were left out because no gender is recorded"
     },
     "gp_note": {
      "type": "string",
      "description": "the search is about general practice: use search_gp_practices for practices"
     },
     "experienced_first_note": {
      "type": "string"
     },
     "listing_note": {
      "type": "string",
      "description": "some results have no clinic listing (medical_council_register_only)"
     }
    }
   },
   "Service": {
    "type": "object",
    "properties": {
     "sector": {
      "type": "string"
     },
     "group": {
      "type": "string"
     },
     "service": {
      "type": "string"
     },
     "url": {
      "type": "string",
      "description": "Healthpoint service page"
     },
     "locations": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "address": {
         "type": "string"
        },
        "phone": {
         "type": "string",
         "description": "clinic phone as published on the service page"
        },
        "website": {
         "type": "string"
        }
       }
      }
     },
     "procedures_listed": {
      "type": "array",
      "items": {
       "type": "string"
      }
     },
     "conditions_listed": {
      "type": "array",
      "items": {
       "type": "string"
      }
     },
     "fees_category": {
      "type": "array",
      "items": {
       "type": "string"
      }
     },
     "fee_lines": {
      "type": "array",
      "items": {
       "type": "string"
      }
     },
     "ages": {
      "type": "array",
      "items": {
       "type": "string"
      }
     },
     "languages": {
      "type": "array",
      "items": {
       "type": "string"
      }
     },
     "languages_note": {
      "type": "string"
     },
     "hours": {
      "type": "array",
      "items": {
       "type": "string"
      }
     },
     "how_to_access": {
      "type": "string"
     },
     "website": {
      "type": "string"
     },
     "page_last_updated": {
      "type": "string"
     },
     "southern_cross_affiliated_provider": {
      "type": "boolean"
     },
     "nib_first_choice": {
      "type": "boolean"
     },
     "acc_mentioned": {
      "type": "boolean"
     },
     "enrolling": {
      "type": "string",
      "enum": [
       "yes",
       "restricted",
       "no",
       "does not apply",
       "unknown"
      ],
      "description": "general practice: enrolling new patients?"
     },
     "enrolling_note": {
      "type": "string"
     },
     "fees": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/FeeRow"
      }
     },
     "online_booking": {
      "type": "string"
     }
    }
   },
   "FeeRow": {
    "type": "object",
    "properties": {
     "ages": {
      "type": "string"
     },
     "without_csc": {
      "type": "string"
     },
     "with_csc": {
      "type": "string",
      "description": "Community Services Card holders"
     }
    },
    "description": "one row of the practice's fee table (usually fees for enrolled patients)"
   },
   "Doctor": {
    "type": "object",
    "properties": {
     "doctor_id": {
      "type": "string",
      "pattern": "^nz_[0-9a-z]{12}$",
      "description": "use with get_doctor"
     },
     "name": {
      "type": "string"
     },
     "kind": {
      "type": "string"
     },
     "title": {
      "type": "string"
     },
     "specialties": {
      "type": "array",
      "items": {
       "type": "string"
      }
     },
     "vocational_scope": {
      "type": "string"
     },
     "qualifications": {
      "type": "string"
     },
     "stated_focus_areas": {
      "type": "array",
      "items": {
       "type": "string"
      }
     },
     "subspecialties": {
      "type": "array",
      "items": {
       "type": "string"
      }
     },
     "further_training": {
      "type": "array",
      "items": {
       "type": "string"
      }
     },
     "languages": {
      "type": "array",
      "items": {
       "type": "string"
      }
     },
     "languages_note": {
      "type": "string"
     },
     "gender": {
      "type": "string"
     },
     "nz_registration_date": {
      "type": "string"
     },
     "sees_children": {
      "type": "string",
      "description": "yes, no (ages listed without children) or unknown"
     },
     "insurer_notes": {
      "type": "object",
      "properties": {
       "southern_cross_affiliated_provider_service": {
        "type": "boolean"
       },
       "southern_cross_affiliated_provider_own_page": {
        "type": "boolean"
       },
       "nib_first_choice_service": {
        "type": "boolean"
       },
       "nib_first_choice_own_page": {
        "type": "boolean"
       },
       "acc_mentioned": {
        "type": "boolean"
       },
       "note": {
        "type": "string"
       }
      }
     },
     "services": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/Service"
      }
     },
     "medical_council": {
      "type": "object",
      "properties": {
       "register_url": {
        "type": "string"
       },
       "matched_by": {
        "type": "string"
       },
       "status": {
        "type": "string"
       },
       "scope_of_practice": {
        "type": "string"
       },
       "vocational_scope": {
        "type": "string"
       },
       "conditions_on_practice": {
        "type": "string"
       },
       "qualifications": {
        "type": "array",
        "items": {
         "type": "string"
        }
       },
       "practising_certificate": {
        "type": "string"
       },
       "matched": {
        "type": "boolean"
       },
       "how_to_check": {
        "type": "string"
       }
      }
     },
     "listing_note": {
      "type": "string",
      "description": "on the register but no clinic listing here"
     },
     "experience": {
      "type": "object",
      "properties": {
       "vocational_scopes": {
        "type": "array",
        "items": {
         "type": "object",
         "properties": {
          "scope": {
           "type": "string"
          },
          "since": {
           "type": "string"
          },
          "years": {
           "type": "integer"
          },
          "provisional": {
           "type": "boolean"
          }
         }
        }
       },
       "specialist_since": {
        "type": "string"
       },
       "years_as_specialist_in_nz": {
        "type": "integer"
       },
       "provisional_vocational_scope": {
        "type": "string"
       },
       "first_registered_nz": {
        "type": "string"
       },
       "primary_medical_degree_year": {
        "type": "integer"
       },
       "new_zealand_honours": {
        "type": "array",
        "items": {
         "type": "object",
         "properties": {
          "honour": {
           "type": "string"
          },
          "honour_name": {
           "type": "string"
          },
          "list": {
           "type": "string"
          },
          "citation": {
           "type": "string"
          },
          "source": {
           "type": "string"
          }
         }
        }
       },
       "academic": {
        "type": "object",
        "properties": {
         "institution": {
          "type": "string"
         },
         "title": {
          "type": "string"
         },
         "positions": {
          "type": "array",
          "items": {
           "type": "string"
          }
         },
         "hospital_and_other_appointments": {
          "type": "array",
          "items": {
           "type": "string"
          }
         },
         "profile": {
          "type": "string"
         }
        }
       },
       "publications": {
        "type": "object",
        "properties": {
         "count_approx": {
          "type": "integer"
         },
         "list": {
          "type": "string"
         },
         "how_counted": {
          "type": "string"
         }
        }
       },
       "note": {
        "type": "string"
       }
      },
      "description": "seniority from the Medical Council register, honours, University of Auckland and Europe PMC; not a measure of quality"
     },
     "hospital_website_links": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "site": {
         "type": "string"
        },
        "url": {
         "type": "string"
        }
       }
      }
     },
     "warnings": {
      "type": "array",
      "items": {
       "type": "string"
      }
     },
     "sources": {
      "type": "object",
      "properties": {
       "healthpoint": {
        "type": "string"
       },
       "healthpoint_read": {
        "type": "string"
       },
       "medical_council_register": {
        "type": "string"
       },
       "medical_council_read": {
        "type": "string"
       },
       "profile_text": {
        "type": "string"
       }
      }
     },
     "note": {
      "type": "string"
     }
    }
   },
   "DoctorBatch": {
    "type": "object",
    "properties": {
     "provider": {
      "$ref": "#/components/schemas/Provider"
     },
     "daily_doctor_limit": {
      "type": "object",
      "description": "present when the daily limit matters: used, limit, message"
     },
     "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",
           "pattern": "^nz_[0-9a-z]{12}$",
           "description": "use with get_doctor"
          }
         }
        }
       }
      },
      "description": "already counted; ask again for these at no extra cost"
     },
     "left_out": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "doctor_id": {
         "type": "string",
         "pattern": "^nz_[0-9a-z]{12}$",
         "description": "use with get_doctor"
        },
        "reason": {
         "type": "string"
        }
       }
      },
      "description": "not opened: daily limit reached"
     },
     "not_found": {
      "type": "array",
      "items": {
       "type": "string"
      }
     },
     "note": {
      "type": "string"
     }
    }
   },
   "GpPractice": {
    "type": "object",
    "properties": {
     "rank": {
      "type": "integer"
     },
     "practice": {
      "type": "string"
     },
     "kind": {
      "type": "string",
      "enum": [
       "general practice",
       "urgent care"
      ]
     },
     "enrolling": {
      "type": "string",
      "enum": [
       "yes",
       "restricted",
       "no",
       "does not apply",
       "unknown"
      ],
      "description": "yes, restricted (only some people), no, does not apply (urgent care), unknown"
     },
     "enrolling_note": {
      "type": "string",
      "description": "the practice's own words about enrolment"
     },
     "place_match": {
      "type": "string",
      "enum": [
       "city_or_address",
       "city_in_region",
       "address_contains",
       "region_page_only"
      ]
     },
     "locations": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "address": {
         "type": "string"
        },
        "region": {
         "type": "string"
        },
        "phone": {
         "type": "string"
        },
        "website": {
         "type": "string"
        }
       }
      }
     },
     "fees": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/FeeRow"
      }
     },
     "fee_for_age": {
      "type": "object",
      "description": "with age: the fee row for that age"
     },
     "online_booking": {
      "type": "string"
     },
     "website": {
      "type": "string"
     },
     "hours": {
      "type": "array",
      "items": {
       "type": "string"
      }
     },
     "languages": {
      "type": "array",
      "items": {
       "type": "string"
      }
     },
     "languages_note": {
      "type": "string"
     },
     "doctors": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "doctor_id": {
         "type": "string",
         "pattern": "^nz_[0-9a-z]{12}$",
         "description": "use with get_doctor"
        },
        "name": {
         "type": "string"
        }
       }
      }
     },
     "doctors_listed": {
      "type": "integer"
     },
     "healthpoint": {
      "type": "string",
      "description": "the practice's Healthpoint page"
     },
     "page_last_updated": {
      "type": "string"
     }
    }
   },
   "GpResult": {
    "type": "object",
    "properties": {
     "provider": {
      "$ref": "#/components/schemas/Provider"
     },
     "total_matches": {
      "type": "integer"
     },
     "offset": {
      "type": "integer"
     },
     "enrolling_counts": {
      "type": "object",
      "description": "matches by enrolling status"
     },
     "results": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/GpPractice"
      }
     },
     "explain": {
      "type": "string"
     },
     "next_step": {
      "type": "string"
     },
     "note": {
      "type": "string"
     }
    }
   },
   "WaitlistRow": {
    "type": "object",
    "properties": {
     "measure": {
      "type": "string"
     },
     "month_end": {
      "type": "string"
     },
     "region": {
      "type": "string"
     },
     "district": {
      "type": "string"
     },
     "specialty": {
      "type": "string"
     },
     "total_waiting": {
      "type": "integer"
     },
     "waiting_under_120_days": {
      "type": "integer"
     },
     "share_over_120_days": {
      "type": "number"
     },
     "has_cells_under_5": {
      "type": "boolean"
     }
    }
   }
  },
  "securitySchemes": {
   "accountKey": {
    "type": "http",
    "scheme": "bearer",
    "description": "Optional account key (dk_...); accounts are by invitation during the trial."
   }
  }
 },
 "security": [
  {},
  {
   "accountKey": []
  }
 ],
 "paths": {
  "/api/v1/search": {
   "get": {
    "operationId": "searchDoctors",
    "summary": "Free short list of New Zealand doctors for a need",
    "description": "Free short list of New Zealand doctors for a need; use it first whenever the person needs a doctor or specialist in New Zealand. Give at least one of need, specialty, place or name. need = a condition, procedure or focus in plain English (e.g. 'ACL reconstruction', 'endometriosis', 'skin cancer', 'cataract surgery'); it is matched against the focus areas doctors list first, then the procedures their services list, their specialty, and their own profile text (not shown here). specialty = a name from list_specialties, a word from one (e.g. 'orthopaedic', 'ENT') or a plain word (e.g. 'eye', 'skin', 'heart'); matched word by word (word endings may differ, e.g. 'cardiologist', 'paediatrician'; not fragments inside words), and the reply's specialty_read_as lists the specialty names used. place = a New Zealand city, suburb, or region or Health NZ district (e.g. 'Christchurch', 'North Shore', 'Hawke's Bay', 'Hutt Valley'); when a town search leaves out doctors listed only on the wider region's page or in its other towns, place_note says how many and which place to use instead. Each result: doctor_id, name, specialties, vocational scope, cities, sectors (private, public), match_basis (with a need: stated_focus, services_listed (the doctor's own or a small practice's service page), shared_service_listed (a hospital department or large group page they are linked to, so not necessarily done by this doctor), specialty, specialty_for_symptom (the need is a symptom few doctors list, and their specialty usually sees it; need_note says which specialties), profile_text or partial), place_match (with a place: city_or_address, city_in_region, address_contains or region_page_only), warnings (e.g. not practising on the Medical Council register), specialist_since (year first on the Medical Council vocational, i.e. specialist, register in New Zealand), recognition (New Zealand honours, University of Auckland title), listing (medical_council_register_only when the doctor has no clinic listing here), possibly_same_person_as (another entry with the same name that may be the same doctor) and detail_has (what get_doctor adds). General practitioners are left out unless specialty is general practice (e.g. 'GP') or a name is given; to find a GP clinic use search_gp_practices. Doctors only on the register are included when practising with a specialist scope (any status with a name). Results are ranked first by how directly the doctor's own listing matches the need (doctors who list all its words; then, when the need is a symptom such as back pain, doctors whose specialty usually sees it; then doctors who list some of the words; then words only in profile text), then by place_match (with a place); with experienced_first, longer as a specialist next. Doctors known only from the Medical Council register (no clinic listing) come after all others. Not ranked by quality or outcomes. Then call get_doctor with the doctor_ids you are considering. Up to 10 results per search and paging stops at 30: narrow the need or the place instead of paging.",
    "parameters": [
     {
      "name": "need",
      "in": "query",
      "required": false,
      "description": "Condition, procedure or focus, plain English.",
      "schema": {
       "type": "string",
       "maxLength": 200
      }
     },
     {
      "name": "specialty",
      "in": "query",
      "required": false,
      "description": "Specialty name, a word from one, or a plain word like 'eye' (see list_specialties).",
      "schema": {
       "type": "string",
       "maxLength": 200
      }
     },
     {
      "name": "place",
      "in": "query",
      "required": false,
      "description": "New Zealand city, suburb, or region or Health NZ district (e.g. 'Waikato', 'Hawke's Bay', 'Capital and Coast').",
      "schema": {
       "type": "string",
       "maxLength": 200
      }
     },
     {
      "name": "name",
      "in": "query",
      "required": false,
      "description": "Doctor's name or part of it, to check a named doctor.",
      "schema": {
       "type": "string",
       "maxLength": 200
      }
     },
     {
      "name": "sector",
      "in": "query",
      "required": false,
      "description": "private = the doctor lists a private service; public = a public (Health NZ) service. Default any.",
      "schema": {
       "type": "string",
       "enum": [
        "any",
        "private",
        "public"
       ]
      }
     },
     {
      "name": "child",
      "in": "query",
      "required": false,
      "description": "True when the patient is a child: among doctors in the same place who match the need equally well, those in paediatrics or who list children in their focus come first, then those whose services say they see children; doctors whose services list only adult ages are left out. Most listings do not say, so those doctors stay in.",
      "schema": {
       "type": "boolean"
      }
     },
     {
      "name": "language",
      "in": "query",
      "required": false,
      "description": "Language other than English the doctor, or a small clinic (3 doctors or fewer) they work in, lists, e.g. 'Mandarin', 'Hindi', 'Samoan'.",
      "schema": {
       "type": "string",
       "maxLength": 200
      }
     },
     {
      "name": "gender",
      "in": "query",
      "required": false,
      "description": "Only when the person asks. Gender is recorded for only a small share of doctors (when their Healthpoint page states it); doctors without it are left out and gender_note says how many.",
      "schema": {
       "type": "string",
       "enum": [
        "female",
        "male"
       ]
      }
     },
     {
      "name": "southern_cross_affiliated",
      "in": "query",
      "required": false,
      "description": "True keeps doctors whose own Healthpoint page or at least one of whose service pages says Southern Cross Affiliated Provider (cover still depends on the policy and often prior approval; confirm).",
      "schema": {
       "type": "boolean"
      }
     },
     {
      "name": "experienced_first",
      "in": "query",
      "required": false,
      "description": "True when the person wants an experienced or senior doctor: among doctors who match equally well, those longer on the New Zealand specialist (vocational) register come first. Time on the register is not quality, and doctors who trained overseas may have practised longer than it shows.",
      "schema": {
       "type": "boolean"
      }
     },
     {
      "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).",
      "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 New Zealand",
          "url": "https://findadoctor.si/nz/",
          "data_version": "nz-public-2026-10-15.5"
         },
         "before_answering": "This is the free short list: who the doctors are, not the evidence. ...",
         "total_matches": 12,
         "offset": 0,
         "results": [
          {
           "rank": 1,
           "doctor_id": "nz_4k9m2x7qph3t",
           "name": "Dr Example Surgeon",
           "kind": "Orthopaedic Surgeon",
           "specialties": [
            "Orthopaedics"
           ],
           "vocational_scope": "Orthopaedic Surgery",
           "cities": [
            "Christchurch"
           ],
           "sectors": [
            "private"
           ],
           "match_basis": "stated_focus",
           "detail_has": [
            "5 focus areas they list",
            "clinic phone numbers and addresses",
            "Medical Council register entry"
           ]
          }
         ],
         "next_step": "Call get_doctor with doctor_ids (up to 10 at once) ...",
         "note": "Confirm phone numbers, fees, insurer status and availability with the clinic 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): send no header or a valid account key",
      "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; opening a doctor again the same day is free.",
    "parameters": [
     {
      "name": "doctor_id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "pattern": "^nz_[0-9a-z]{12}$"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result (same as the MCP tool's result)",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "provider": {
           "$ref": "#/components/schemas/Provider"
          }
         },
         "description": "Provider, then the Doctor fields"
        },
        "example": {
         "provider": {
          "name": "FindADoctor.si New Zealand",
          "url": "https://findadoctor.si/nz/",
          "data_version": "nz-public-2026-10-15.5"
         },
         "doctor_id": "nz_4k9m2x7qph3t",
         "name": "Dr Example Surgeon",
         "specialties": [
          "Orthopaedics"
         ],
         "stated_focus_areas": [
          "Hip replacement",
          "Knee arthroscopy"
         ],
         "services": [
          {
           "sector": "private",
           "service": "Example Orthopaedics",
           "url": "https://www.healthpoint.co.nz/private/orthopaedics/example-orthopaedics/",
           "locations": [
            {
             "address": "1 Example Street, Merivale, Christchurch",
             "phone": "(03) 000 0000"
            }
           ],
           "procedures_listed": [
            "Hip replacement"
           ],
           "fees_category": [
            "Fees apply"
           ],
           "southern_cross_affiliated_provider": true,
           "nib_first_choice": false,
           "acc_mentioned": true
          }
         ],
         "medical_council": {
          "status": "Practising",
          "scope_of_practice": "Vocational - Orthopaedic Surgery"
         },
         "sources": {
          "healthpoint": "https://www.healthpoint.co.nz/specialists/orthopaedics/dr-example-surgeon/"
         }
        }
       }
      }
     },
     "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): send no header or a valid account key",
      "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",
      "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 (counted)",
    "description": "ids = comma-separated doctor_ids from search results, up to 10. Each different doctor opened counts toward a daily limit (UTC day): 5 a day per network address without an account; 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. Doctors that do not fit in one reply 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.",
    "parameters": [
     {
      "name": "ids",
      "in": "query",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "e.g. nz_4k9m2x7qph3t,nz_8w2c5n1kd7ra"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result (same as the MCP tool's result)",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/DoctorBatch"
        },
        "example": {
         "provider": {
          "name": "FindADoctor.si New Zealand",
          "url": "https://findadoctor.si/nz/",
          "data_version": "nz-public-2026-10-15.5"
         },
         "doctors": [
          {
           "doctor_id": "nz_4k9m2x7qph3t",
           "name": "Dr Example Surgeon",
           "specialties": [
            "Orthopaedics"
           ],
           "stated_focus_areas": [
            "Hip replacement",
            "Knee arthroscopy"
           ],
           "services": [
            {
             "sector": "private",
             "service": "Example Orthopaedics",
             "url": "https://www.healthpoint.co.nz/private/orthopaedics/example-orthopaedics/",
             "locations": [
              {
               "address": "1 Example Street, Merivale, Christchurch",
               "phone": "(03) 000 0000"
              }
             ],
             "procedures_listed": [
              "Hip replacement"
             ],
             "fees_category": [
              "Fees apply"
             ],
             "southern_cross_affiliated_provider": true,
             "nib_first_choice": false,
             "acc_mentioned": true
            }
           ],
           "medical_council": {
            "status": "Practising",
            "scope_of_practice": "Vocational - Orthopaedic Surgery"
           },
           "sources": {
            "healthpoint": "https://www.healthpoint.co.nz/specialists/orthopaedics/dr-example-surgeon/"
           }
          }
         ]
        }
       }
      }
     },
     "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): send no header or a valid account key",
      "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",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "found": {
           "type": "boolean",
           "enum": [
            false
           ]
          }
         }
        },
        "example": {
         "found": false
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/gp-practices": {
   "get": {
    "operationId": "searchGpPractices",
    "summary": "New Zealand general practices near a place, with enrolment status and fees",
    "description": "Free list of New Zealand general practices (GP clinics), or urgent care clinics, near a place, from Healthpoint. Use it when the person needs a GP, wants to enrol with a practice, or needs urgent but not emergency care. Each practice: whether it says it is enrolling new patients (yes; restricted = only some people, e.g. family of patients or people living nearby; no; does not apply = urgent care that does not enrol; unknown = the page does not say), the practice's own enrolment note, its fee table (the first fee table on its page, usually fees for enrolled patients by age, without and with a Community Services Card; with age, the row for that age), addresses, phone numbers, website, online booking link, languages, hours, the doctors listed there (doctor_ids for get_doctor) and the date Healthpoint says the page was last updated. In New Zealand most people enrol with one general practice: visits cost less once enrolled, and a GP referral is the usual way to a public specialist. Give place or name. Practices are not doctors, so this does not count toward the daily doctor limit. Enrolment and fees change often: tell the person to phone the practice to confirm.",
    "parameters": [
     {
      "name": "place",
      "in": "query",
      "required": false,
      "description": "New Zealand city, suburb or region (e.g. 'Papanui', 'Hamilton', 'North Shore', 'Canterbury').",
      "schema": {
       "type": "string",
       "maxLength": 200
      }
     },
     {
      "name": "name",
      "in": "query",
      "required": false,
      "description": "Practice name or part of it, to check a named practice.",
      "schema": {
       "type": "string",
       "maxLength": 200
      }
     },
     {
      "name": "enrolling",
      "in": "query",
      "required": false,
      "description": "yes = only practices that say they are enrolling new patients; yes_or_restricted also keeps practices enrolling only some people (read enrolling_note). Default any (enrolling practices come first).",
      "schema": {
       "type": "string",
       "enum": [
        "any",
        "yes",
        "yes_or_restricted"
       ]
      }
     },
     {
      "name": "age",
      "in": "query",
      "required": false,
      "description": "The patient's age: each result then shows the fee row for that age.",
      "schema": {
       "type": "integer",
       "minimum": 0,
       "maximum": 120
      }
     },
     {
      "name": "language",
      "in": "query",
      "required": false,
      "description": "Language other than English the practice lists, e.g. 'Mandarin', 'Samoan', 'te reo Maori'.",
      "schema": {
       "type": "string",
       "maxLength": 200
      }
     },
     {
      "name": "kind",
      "in": "query",
      "required": false,
      "description": "gp = general practices (default; also nurse-led, online, student and rest-home practices, named so in each result's kind); urgent_care = accident and urgent medical care and after-hours clinics (no enrolment needed); any = both.",
      "schema": {
       "type": "string",
       "enum": [
        "gp",
        "urgent_care",
        "any"
       ]
      }
     },
     {
      "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 40).",
      "schema": {
       "type": "integer",
       "minimum": 0,
       "maximum": 40
      }
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result (same as the MCP tool's result)",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/GpResult"
        }
       }
      }
     },
     "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): send no header or a valid account key",
      "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 with doctor counts",
    "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": {
             "name": {
              "type": "string"
             },
             "doctors": {
              "type": "integer"
             }
            }
           }
          }
         }
        }
       }
      }
     },
     "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): send no header or a valid account key",
      "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/waitlist": {
   "get": {
    "operationId": "publicWaitlist",
    "summary": "Health NZ public waiting lists by district and specialty",
    "description": "Public-system waiting lists from Health NZ by district and specialty (latest month and the same month a year earlier): people waiting for a first specialist assessment (FSA) and for planned treatment (surgery), and the share waiting over 120 days. Use it when the person is weighing public against private, or which district is faster. Give specialty and/or district. Free.",
    "parameters": [
     {
      "name": "specialty",
      "in": "query",
      "required": false,
      "description": "e.g. 'Orthopaedic', 'ENT', 'General Surgery', 'eye'. An exact name is matched first, then names containing each word, then the same without words like 'surgery' and with common plain words mapped (eye \u2192 Ophthalmology, heart surgery \u2192 Cardiothoracic, cardiologist \u2192 Cardiology, internal medicine \u2192 General Medicine), then part of a name; both of Health NZ's names for the same specialty are returned (e.g. Orthopaedics and Orthopaedic Surgery).",
      "schema": {
       "type": "string",
       "maxLength": 200
      }
     },
     {
      "name": "district",
      "in": "query",
      "required": false,
      "description": "Health NZ district, e.g. 'Auckland', 'Canterbury', 'Capital and Coast'. Part of a name also matches (Canterbury includes South Canterbury); a city or region is read as its district (Wellington \u2192 Capital and Coast, Dunedin \u2192 Southern), shown in district_read_as.",
      "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"
          },
          "rows": {
           "type": "array",
           "items": {
            "$ref": "#/components/schemas/WaitlistRow"
           }
          },
          "more": {
           "type": "boolean"
          },
          "explain": {
           "type": "string"
          },
          "district_read_as": {
           "type": "array",
           "items": {
            "type": "string",
            "description": "district names searched when the district given was a city or region"
           }
          },
          "source": {
           "type": "string"
          },
          "next_step": {
           "type": "string"
          },
          "specialties": {
           "type": "array",
           "items": {
            "type": "string"
           }
          },
          "districts": {
           "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): send no header or a valid account key",
      "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, read dates, coverage 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"
          },
          "edition": {
           "type": "string"
          },
          "version": {
           "type": "string"
          },
          "built_at_utc": {
           "type": "string"
          },
          "counts": {
           "type": "object"
          },
          "sources": {
           "type": "array",
           "items": {
            "type": "object"
           }
          },
          "coverage": {
           "type": "string"
          },
          "what_is_not_here": {
           "type": "string"
          },
          "ranking": {
           "type": "string"
          },
          "corrections": {
           "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): send no header or a valid account key",
      "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"
        }
       }
      }
     }
    }
   }
  }
 }
}