HealthSherpa Reference API

The Reference API from HealthSherpa — 3 operation(s) for reference.

OpenAPI Specification

healthsherpa-reference-api-openapi.yml Raw ↑
openapi: 3.1.0
info:
  title: HealthSherpa Public Enrollment Sessions Reference API
  version: 0.1.0
  description: 'Machine-readable contract for the currently available public HealthSherpa endpoints: GET /v1/ping, GET /v1/reference/counties, GET /v1/reference/issuers, GET /v1/reference/providers, POST /v1/quotes, the approval-gated POST /v1/enrollment-sessions, and the approval-gated direct enrollment endpoints GET /v1/enrollments, POST /v1/enrollments, PUT /v1/enrollments/{enrollment_id}, GET /v1/enrollments/{enrollment_id}, POST /v1/enrollments/{enrollment_id}/cancellations, POST /v1/enrollments/{enrollment_id}/terminations, POST /v1/enrollments/{enrollment_id}/submissions, GET /v1/enrollments/{enrollment_id}/payment_redirect, and POST /v1/enrollments/{enrollment_id}/supporting_documentation. Object schemas remain additive and clients should ignore response fields they do not recognize.


    Most HealthSherpa-owned errors follow the unified `ErrorResponse` schema: `{ "error": { "code": string, "message": string, "details"?: object } }`. The direct enrollment endpoints instead return service failures as a top-level `errors[]` array: `{ "errors": [ { "code": string, "message": string, "field"?: string } ] }`. Edge-generated failures (API Gateway and WAF, before a request reaches the service) always use the unified `ErrorResponse` envelope, including on the direct enrollment endpoints — most notably a missing or invalid API key (`403 forbidden`).'
servers:
- url: https://api.one.healthsherpa.com
  description: Production
security:
- ApiKeyAuth: []
tags:
- name: Reference
paths:
  /v1/reference/counties:
    get:
      tags:
      - Reference
      summary: List counties for a ZIP code
      description: Returns the counties that overlap the supplied ZIP code. A ZIP code can cross state lines; each returned county's `state` is the canonical state for its `fips_code`. Use the selected fips_code in subsequent quote requests.
      operationId: listCounties
      parameters:
      - name: zip_code
        in: query
        required: true
        description: Five-digit ZIP code to resolve.
        schema:
          type: string
          pattern: ^[0-9]{5}$
      responses:
        '200':
          description: One or more counties found for the ZIP code.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CountiesResponse'
              example:
                counties:
                - fips_code: '12086'
                  name: Miami-Dade County
                  state: FL
        '400':
          $ref: '#/components/responses/BadRequest'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
        '502':
          $ref: '#/components/responses/BadGateway'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
        '504':
          $ref: '#/components/responses/GatewayTimeout'
  /v1/reference/issuers:
    get:
      tags:
      - Reference
      summary: List QHP issuers active in a state
      description: 'Returns the QHP issuers active in the requested state and plan year. Each entry combines a sortable display name (issuer marketing name when present, legal name otherwise) with the canonical 5-digit HIOS issuer ID for use in subsequent quote filters.


        **Plan year:** the optional `plan_year` query parameter pins the lookup to a specific year and defaults to the current ACA plan year (open enrollment for 2027 begins November 1 2026). Specify `plan_year` explicitly when reconciling enrollments from a prior year or when shopping the next year before the rollover.


        **Response ordering:** entries are sorted by `name` (case-insensitive) and then by `hios_issuer_id` as a stable tiebreaker. Clients can iterate the array directly without re-sorting.'
      operationId: listIssuers
      parameters:
      - name: state
        in: query
        required: true
        description: Two-letter uppercase US state code (e.g. `FL`). Lowercase values are rejected with `400 invalid_request` — clients must upcase before sending.
        example: FL
        schema:
          type: string
          pattern: ^[A-Z]{2}$
      - name: plan_year
        in: query
        required: false
        description: ACA plan year to scope the issuer list to. Defaults to the current ACA plan year when omitted.
        schema:
          type: integer
          minimum: 2020
          maximum: 2099
        example: 2026
      responses:
        '200':
          description: One or more issuers found for the state.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IssuersResponse'
              example:
                issuers:
                - name: Gulf Coast Coverage Co.
                  hios_issuer_id: '33333'
                - name: Sunshine State Health
                  hios_issuer_id: '12345'
        '400':
          $ref: '#/components/responses/BadRequest'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
        '502':
          $ref: '#/components/responses/BadGateway'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
        '504':
          $ref: '#/components/responses/GatewayTimeout'
  /v1/reference/providers:
    get:
      tags:
      - Reference
      summary: Search healthcare providers by name near a ZIP code
      description: 'Searches healthcare providers (individuals and facilities) by name near a ZIP code and returns paginated results with NPI and address data. This is a search-only endpoint; there is no "list all providers" mode.


        Use the returned 10-digit `npi` values when building provider selections, for example the `providers` field on an enrollment session.


        **Channel:** the required `exchange` parameter selects the marketplace channel (`on_exchange` or `off_exchange`).


        **Pagination:** results are paginated with the nested `page[number]` and `page[size]` query parameters, mirroring the quoting endpoint''s `page` object. `page[number]` defaults to 1 (values below 1 are treated as 1) and `page[size]` accepts 1 to 50, defaulting to 50 (values outside the range resolve to 50). Pagination metadata is returned under `meta` (`page_number`, `page_size`, `result_count`). An empty search returns `providers: []` with `result_count` 0.'
      operationId: searchProviders
      parameters:
      - name: query
        in: query
        required: true
        description: Provider or facility name search term.
        schema:
          type: string
          minLength: 1
        example: Smith
      - name: zip_code
        in: query
        required: true
        description: Five-digit ZIP code used for the geographic (near-ZIP) search.
        schema:
          type: string
          pattern: ^[0-9]{5}$
        example: '85001'
      - name: exchange
        in: query
        required: true
        description: Marketplace channel to search. Required. One of `on_exchange` or `off_exchange`.
        schema:
          type: string
          enum:
          - on_exchange
          - off_exchange
        example: on_exchange
      - name: page[number]
        in: query
        required: false
        description: Page number (mirrors quoting's page.number). Defaults to 1; values below 1 are treated as 1.
        schema:
          type: integer
          minimum: 1
          default: 1
        example: 1
      - name: page[size]
        in: query
        required: false
        description: Results per page (mirrors quoting's page.size), from 1 to 50. Defaults to 50; values outside this range resolve to 50.
        schema:
          type: integer
          minimum: 1
          maximum: 50
          default: 50
        example: 50
      responses:
        '200':
          description: Provider search results for the current page. An empty search returns an empty `providers` array.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProvidersResponse'
              example:
                providers:
                - first_name: John
                  last_name: Smith
                  organization_name: null
                  display_name: John Smith, MD
                  credential: MD
                  entity_type: individual
                  npi: '1972113918'
                  specialty: Family Medicine
                  specialization: General Practice
                  address_line_1: 123 Main St
                  city: Phoenix
                  state: AZ
                  zip_code: '85001'
                meta:
                  page_number: 1
                  page_size: 50
                  result_count: 1
        '400':
          $ref: '#/components/responses/BadRequest'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
        '502':
          $ref: '#/components/responses/BadGateway'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
        '504':
          $ref: '#/components/responses/GatewayTimeout'
components:
  responses:
    NotFound:
      description: The requested resource could not be found. Emitted by the backend when no supported data matches the request (for example, no counties for a ZIP), and by the API edge for unknown paths.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: not_found
              message: No counties found for ZIP 12345.
    Forbidden:
      description: The API key is missing, invalid, not authorized for this API, or the request was blocked at the API edge. Public API requests may receive this edge-generated response before the backend can return a runtime 401. When a request reaches the backend, 403 may also mean the developer account or integration is not in the state required for that operation. For `POST /v1/enrollment-sessions`, that operation documents its own flow-scoped 403 requirements (both flows require approved on-exchange enrollment access, plus `agent_assisted` OAuth link vs `self_service` deeplink agent ID) instead of using this shared response reference.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: forbidden
              message: The supplied API key is missing, invalid, or not authorized for this API.
    InternalError:
      description: An unexpected error occurred.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: internal_error
              message: An unexpected error occurred.
    ServiceUnavailable:
      description: The API is temporarily unable to serve the request. This may be returned by the API edge when the backend is unhealthy, or by the backend when an upstream catalog, quoting, or lookup service is unavailable.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: service_unavailable
              message: The service is temporarily unavailable. Please try again later.
    BadGateway:
      description: The API edge received an invalid response from the backend.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: bad_gateway
              message: The API edge received an invalid response from the backend. Please try again later.
    BadRequest:
      description: 'Request validation failed. The response body''s `error.details` map contains per-field messages when the backend produced the error; edge-generated 400s omit `details`.


        A malformed `Idempotency-Key` header is also rejected here with `code: idempotency_key_invalid`.'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: invalid_request
              message: Validation failed.
              details:
                zip_code:
                - ZIP code must be 5 digits
    RateLimited:
      description: Rate limit exceeded. Clients should back off and retry after the delay advertised in the Retry-After header.
      headers:
        Retry-After:
          description: Number of seconds the client should wait before retrying.
          schema:
            type: integer
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: rate_limited
              message: Request rate limit exceeded. Please slow down and retry shortly.
    GatewayTimeout:
      description: The API edge did not receive a timely response from the backend.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: gateway_timeout
              message: The API edge did not receive a timely response from the backend. Please try again later.
  schemas:
    ProvidersResponse:
      type: object
      additionalProperties: true
      required:
      - providers
      - meta
      properties:
        providers:
          type: array
          description: Provider results for the current page. Empty when there are no matches.
          items:
            $ref: '#/components/schemas/ProviderEntity'
        meta:
          $ref: '#/components/schemas/ProvidersResponseMeta'
    CountiesResponse:
      type: object
      additionalProperties: true
      required:
      - counties
      properties:
        counties:
          type: array
          items:
            $ref: '#/components/schemas/CountySummary'
    IssuersResponse:
      type: object
      additionalProperties: true
      required:
      - issuers
      properties:
        issuers:
          type: array
          description: Issuers active in the requested state, sorted by `name` (case-insensitive) and then by `hios_issuer_id` as a stable tiebreaker. One entry per HIOS issuer.
          items:
            $ref: '#/components/schemas/IssuerSummary'
    CountySummary:
      type: object
      additionalProperties: true
      required:
      - fips_code
      - name
      - state
      properties:
        fips_code:
          type: string
          description: Five-digit county FIPS code. The first two digits identify the county's state.
        name:
          type: string
        state:
          type: string
          description: Two-letter state code for this county, derived from the FIPS code. Border ZIP responses can include counties from more than one state.
    ErrorResponse:
      type: object
      description: 'Canonical error envelope returned by HealthSherpa-owned API endpoint, infrastructure filter, and backend service failures. The direct enrollment endpoints return their own service failures using `EnrollmentErrorsResponse` (`errors[]`), but edge-generated failures on those endpoints (API Gateway and WAF, e.g. a missing or invalid API key) still use this `ErrorResponse` envelope. Clients should treat `error.code` as the stable programmatic identifier and surface `error.message` to humans. Recognized codes include:

        - `unauthorized` (401) - backend runtime authentication failure when a request reaches a runtime that performs its own authentication

        - `forbidden` (403) - missing/invalid/unauthorized API key at the API edge, or edge policy deny

        - `invalid_request` (400) - request body or parameter validation failed

        - `not_found` (404) - resource or route not found

        - `payload_too_large` (413) - request body exceeded edge limits

        - `unsupported_media_type` (415) - unsupported Content-Type

        - `rate_limited` (429) - edge rate-limiting

        - `service_unavailable` (503) - the edge is failing to reach the backend, or an upstream catalog/quoting/lookup service is unavailable

        - `bad_gateway` (502) - the edge received an invalid response from the backend

        - `gateway_timeout` (504) - the edge did not receive a timely response from the backend

        - `internal_error` (500) - unexpected server error'
      additionalProperties: true
      required:
      - error
      properties:
        error:
          type: object
          additionalProperties: true
          required:
          - code
          - message
          properties:
            code:
              type: string
              description: Stable, machine-readable identifier for the error class (see ErrorResponse description for recognized values). Clients should branch on this field rather than on `message` or HTTP status alone.
            message:
              type: string
              description: Human-readable explanation of the error, suitable for logging or surfacing to an end user.
            details:
              type: object
              description: Optional per-field validation details. Keys are dotted/indexed paths (e.g. `household.applicants[0].age`) and values are arrays of full-sentence error messages.
              additionalProperties:
                type: array
                items:
                  type: string
    IssuerSummary:
      type: object
      additionalProperties: true
      required:
      - name
      - hios_issuer_id
      properties:
        name:
          type: string
          description: Issuer display name.
        hios_issuer_id:
          type: string
          pattern: ^[0-9]{5}$
          description: Five-digit HIOS issuer ID.
    ProviderEntity:
      type: object
      additionalProperties: true
      required:
      - npi
      properties:
        first_name:
          type:
          - string
          - 'null'
          description: Individual provider's first name. Null for organizations.
        last_name:
          type:
          - string
          - 'null'
          description: Individual provider's last name. Null for organizations.
        organization_name:
          type:
          - string
          - 'null'
          description: Organization marketing name. Null for individuals.
        display_name:
          type:
          - string
          - 'null'
          description: 'Human-friendly label: organization name for facilities, or "First Last, Credential" for individuals.'
        credential:
          type:
          - string
          - 'null'
          description: Professional credential (e.g. MD, DO, NP).
        entity_type:
          type:
          - string
          - 'null'
          description: Provider entity type, typically `individual` or `organization`.
        npi:
          type: string
          pattern: ^[0-9]{10}$
          description: Ten-digit National Provider Identifier. Use this value (no suffix) when referencing the provider in enrollment requests.
        specialty:
          type:
          - string
          - 'null'
          description: Primary taxonomy classification (e.g. Family Medicine).
        specialization:
          type:
          - string
          - 'null'
          description: Primary taxonomy specialization (e.g. General Practice).
        address_line_1:
          type:
          - string
          - 'null'
          description: First line of the provider's street address (number and street).
        city:
          type:
          - string
          - 'null'
        state:
          type:
          - string
          - 'null'
          description: Two-letter state code.
        zip_code:
          type:
          - string
          - 'null'
          description: The provider's address ZIP code (not the search ZIP).
    ProvidersResponseMeta:
      type: object
      additionalProperties: true
      required:
      - page_number
      - page_size
      - result_count
      properties:
        page_number:
          type: integer
          description: Current page number.
        page_size:
          type: integer
          description: Results per page (at most 50).
        result_count:
          type: integer
          description: Total number of matches across all pages.
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key