Check if the service is up and your API key is working before you try county lookups or quotes.
API documentation for HealthSherpa One.
Start with the tools available today: check that the service is up, find the right county for a ZIP code, and return plan quote results. Enrollment access is reviewed by our team and enabled separately after onboarding.
Get plan and premium results for one coverage type at a time, including issuer, pricing, plan details, and document links when available.
Find the county options for a ZIP code so the agent can choose the right county before requesting quotes.
List the QHP issuers active in a state for a plan year so you can build issuer filters and validate quote requests against the canonical HIOS issuer IDs.
Responses may add optional fields over time. Build your integration to ignore fields it does not recognize.
Check that HealthSherpa One is reachable and that your API key is active before making county lookup or quote requests.
Send the same x-api-key header you use for other API calls.
A successful response means the service accepted the request and recognized
your key.
GET /v1/ping
x-api-key: YOUR_API_KEY
{
"environment": "production",
"ok": true
}
200403 forbidden429 rate_limitedReturn plan quote results for one coverage type at a time. Look up the county first, then send the market, location, and household details needed to calculate plan pricing.
Use this structure to describe what the agent is quoting: the market, the county, and the household members. The logged-in portal uses the same shape for its prefilled medical example.
| Field | Use |
|---|---|
context |
Required. Product, exchange, coverage, and plan-year details. |
location |
Required. ZIP, county FIPS, and state when supplied. |
household |
Required. Applicants and applicant screening flags. |
annual_incomeeffective_date |
Optional for quote-only requests. |
filterssortpage |
Optional controls for filtering, ordering, and pagination. |
include |
Deprecated and ignored. Quotes always return the canonical payload and add a deprecation message to meta.warnings when include is supplied. |
These values are checked before the quote is processed. Invalid values
return a 400 invalid_request response with field-level details.
context.product
aca, ichraaca is the current portal example. ichra uses the same request shape.
context.exchange
on_exchange, off_exchange
context.coverage_family + context.coverage_type
medicalmedicalancillarydental, vision, supplemental_othercoverage_type matches the selected coverage_family.
context.plan_year
2020
location.zip_code + location.fips_code
GET /v1/reference/counties to resolve the county FIPS code before quoting.
location.state
fips_code.
household.applicants[].relationship
primary, spouse, dependent
household.applicants[].gender
female, male, other, unknown
household.applicants[].uses_tobacco and screening flags
true or falseuses_tobacco is required for each applicant. pregnant, blind_or_disabled, and native_american are optional booleans.
filters.medical.metal_levels[]
bronze, expanded_bronze, silver, gold, platinum, catastrophic
filters.medical.plan_types[]
hmo, ppo, epo, pos, indemnity
sort.direction
asc, desc
sort.field
medicalpremium, deductible, moopdentalpremium, deductible, moop, annual_maximumvisionpremium, exam_copay, frames_allowancesupplemental_otherpremium, issue_age_max
page.number + page.size
page.number defaults to 1. page.size defaults to 20.page.size is capped at 500.POST /v1/quotes
x-api-key: YOUR_API_KEY
Content-Type: application/json
{
"context": {
"product": "aca",
"exchange": "on_exchange",
"coverage_family": "medical",
"coverage_type": "medical",
"plan_year": 2026
},
"location": {
"zip_code": "30301",
"fips_code": "13121",
"state": "GA"
},
"household": {
"household_size": 1,
"applicants": [
{
"member_id": "primary",
"age": 30,
"date_of_birth": "1996-05-01",
"relationship": "primary",
"uses_tobacco": false,
"pregnant": false,
"blind_or_disabled": false,
"native_american": false
}
],
"annual_income": 50000,
"effective_date": "2026-05-01"
},
"sort": {
"field": "premium",
"direction": "asc"
},
"page": {
"number": 1,
"size": 20
}
}
| Field | Use |
|---|---|
plans[] |
Homogeneous for the requested coverage_type. |
| Plan data | Identifiers, issuer, network, pricing, documents, availability, subtype-specific details, and release metadata. |
meta |
coverage_type, page_number, page_size, result_count, and warnings. |
{
"plans": [
{
"plan_id": "38344AK1060001",
"variant_id": "01",
"coverage_family": "medical",
"coverage_type": "medical",
"name": "Premera Blue Cross Preferred Gold 1500",
"context": {
"product": "aca",
"exchange": "on_exchange",
"coverage_family": "medical",
"coverage_type": "medical",
"plan_year": 2026
},
"issuer": {
"issuer_id": "38344",
"name": "Premera Blue Cross Blue Shield of Alaska",
"state": "AK"
},
"pricing": {
"gross_premium": 844.15,
"ehb_premium": 843.39,
"subsidy_applied": 0.0,
"net_premium": 844.15,
"currency": "USD",
"billing_period": "monthly"
},
"documents": {
"sbc_url": "https://example.com/sbc.pdf",
"formulary_url": "https://example.com/formulary"
},
"availability": {
"service_area_id": "AKS001",
"rating_area": "1",
"state": "AK"
},
"details": {
"type": "medical",
"metal_level": "gold",
"plan_type": "ppo",
"hsa_eligible": false,
"deductible_individual": 1500,
"deductible_family": 3000,
"moop_individual": 9200,
"moop_family": 18400,
"csr_level": "none"
},
"release": {
"release_id": "2026-public-release",
"plan_year": 2026
}
}
],
"meta": {
"coverage_type": "medical",
"page_number": 1,
"page_size": 20,
"result_count": 1,
"warnings": []
}
}
200200 with an empty plans[] array and meta.result_count: 0.400 invalid_request403 forbidden429 rate_limited503 service_unavailable500 internal_error{
"error": {
"code": "invalid_request",
"message": "Validation failed.",
"details": {
"context.product": [
"Product is not included in the list"
],
"location.zip_code": [
"ZIP code must be 5 digits"
],
"household.applicants[0].member_id": [
"Member ID can't be blank"
],
"household.applicants[0].uses_tobacco": [
"Uses tobacco is required"
]
}
}
}
Find the county choices for a ZIP code before quoting. If a ZIP crosses
county lines, show the choices to the agent and send the selected
fips_code in POST /v1/quotes.
Send one required zip_code query parameter. HealthSherpa
checks its ZIP-to-county data first and falls back to the CMS Marketplace
lookup when needed.
| Field | Use |
|---|---|
zip_code |
Required five-digit query parameter. |
fips_code |
Returned county choice to carry into the quote request. |
| API Explorer | Uses this same one-field request in the logged-in portal. |
GET /v1/reference/counties?zip_code=42223
x-api-key: YOUR_API_KEY
The public response returns only the fields you need for the
next step: county name, county fips_code,
and state.
{
"counties": [
{
"fips_code": "21047",
"name": "Christian County",
"state": "KY"
},
{
"fips_code": "47125",
"name": "Montgomery County",
"state": "TN"
}
]
}
200400 invalid_requestzip_code is missing or is not a five-digit ZIP code.403 forbidden404 not_found429 rate_limited503 service_unavailable500 internal_error{
"error": {
"code": "not_found",
"message": "No counties found for ZIP 12345."
}
}
List the QHP issuers active in a state for a plan year. Use this to build issuer filters in your shopping UI or to validate that an inbound quote request targets a known HIOS issuer ID.
Send the required state query parameter and an optional
plan_year. When plan_year is omitted the response
defaults to the current ACA plan year — supply it explicitly during open
enrollment rollover or when reconciling a prior-year enrollment.
| Field | Use |
|---|---|
state |
Required two-letter uppercase US state code (e.g. FL, CA, DC). Lowercase values are rejected with 400 invalid_request. |
plan_year |
Optional integer between 2020 and 2099. Defaults to the current ACA plan year. |
hios_issuer_id |
Returned 5-digit HIOS issuer ID to carry into quote filters or downstream lookups. |
GET /v1/reference/issuers?state=FL
x-api-key: YOUR_API_KEY
One entry per HIOS issuer with a sortable display name
(issuer marketing name when present, legal name otherwise) and the
canonical 5-digit hios_issuer_id. Entries are sorted by
name (case-insensitive) and then by hios_issuer_id
as a stable tiebreaker, so clients can iterate the array directly without
re-sorting.
{
"issuers": [
{
"name": "Gulf Coast Coverage Co.",
"hios_issuer_id": "33333"
},
{
"name": "Sunshine State Health",
"hios_issuer_id": "12345"
}
]
}
200400 invalid_requeststate is missing or is not a US state code, or plan_year is not an integer in 2020..2099.403 forbidden404 not_found429 rate_limited500 internal_error{
"error": {
"code": "not_found",
"message": "No issuers found for state FL in plan year 2026."
}
}
Some workflows involve application data, document collection, carrier submission, or hosted consumer enrollment flows. These are not enabled by default. Our team reviews each request, confirms the right setup, and enables access during onboarding.
Send shoppers into a hosted HealthSherpa flow.
Start in your system, then send the shopper to HealthSherpa to review
plans and complete enrollment. Use
POST /v1/enrollment-sessions.
Submit off-exchange applications directly.
For approved partners, create drafts, fix validation issues, submit applications, handle payment steps, and track status.
Use this endpoint to send the browser to a HealthSherpa-hosted enrollment
flow for guided shopping, application preparation, and enrollment completion.
For the direct-to-consumer flow (context.flow = "self_service"),
approval is required and must be requested in the developer portal before use.
The context object is required, as is every field inside it.
This keeps product, exchange, coverage, plan year, flow, and locale
explicit on every request. Callers must also supply at least one of
location.state or top-level
plan_id. Unsupported fields anywhere in the body are rejected
with 400 invalid_request.
| Field | Use |
|---|---|
context |
Required. Product, exchange, coverage, plan year, flow, and locale. |
plan_id |
Plan ID (HIOS). Supply when not providing location.state. |
external_id |
Strongly recommended. Partner-supplied identifier echoed in the response and forwarded for CRM correlation. Must not contain PII. |
location |
Optional. Accepts zip_code, fips_code, and state. Address-level fields (address, address_2, city) are rejected. |
client |
Optional contact identity (first_name, last_name, email, phone_number). |
household |
Optional household details and applicants. household_size must be positive; applicants can include at most one primary and one spouse. |
enrollment.hra |
Optional HRA funding (amount, frequency). Other enrollment subobjects are rejected. |
campaign |
Optional marketing attribution (UTM, cid, display_phone_number). Only allowed when context.flow is self_service. |
These values are checked when the request is validated. Invalid or
unsupported values return 400 invalid_request with
field-level details.
context.product
aca
context.exchange
on_exchange
context.coverage_family + context.coverage_type
medical (both fields)
context.plan_year
2020 and 2099.
context.flow
agent_assistedself_service
context.locale
en-US, es-MXes-MX renders the hosted page in Spanish.
location.zip_code + location.fips_code
GET /v1/reference/counties to resolve a ZIP to county FIPS codes.
location.state
plan_id is not supplied.
household.household_size
1.
household.applicants[].relationship
primary, spouse, dependentprimary and one spouse.
household.applicants[].date_of_birth + household.applicants[].age
date_of_birth and age are mutually exclusive on the same applicant. date_of_birth must not be in the future.age is an integer between 0 and 130.
household.applicants[].sex
female, male
household.applicants[] screening flags
true or falseuses_tobacco, pregnant, parent_caretaker, rejected_by_medicaid_or_chip, unemployment, has_existing_coverage
household.applicants[].ichra
offered, offered_cafeteria (booleans), employee_amount, family_amount (numbers >= 0).
enrollment.hra.amount + enrollment.hra.frequency
amounthra is supplied. Number >= 0. 0 means the consumer declined HRA funding; a positive value means funding was accepted.frequencyamount > 0. Allowed: annually, monthly, quarterly, one_time.
campaign
cid, utm_source, utm_medium, utm_campaign, utm_term, utm_content, display_phone_numbercontext.flow is self_service. Sending any field with flow: "agent_assisted" is rejected with 400 invalid_request.display_phone_number is rendered in the page header. Must be a 10-digit US phone number (e.g. 8005551234, 800-555-1234, (800) 555-1234); +1-prefixed values are rejected with 400 invalid_request.POST /v1/enrollment-sessions
x-api-key: YOUR_API_KEY
Content-Type: application/json
Idempotency-Key: 9b1c4f4e-9c2c-4f8f-9a3b-1e2d3a4b5c6d
{
"external_id": "crm-lead-abc-123",
"context": {
"product": "aca",
"exchange": "on_exchange",
"coverage_family": "medical",
"coverage_type": "medical",
"plan_year": 2026,
"flow": "agent_assisted",
"locale": "en-US"
},
"client": {
"first_name": "Jane",
"last_name": "Doe",
"email": "jane@example.com",
"phone_number": "5551234567"
},
"plan_id": "12345NY0010001",
"location": {
"zip_code": "10001",
"fips_code": "36061",
"state": "NY"
},
"household": {
"annual_income": 42000,
"household_size": 1,
"applicants": [
{
"relationship": "primary",
"date_of_birth": "1990-01-01",
"sex": "female",
"uses_tobacco": false
}
]
}
}
Successful responses always return links.shopping_url and
links.client_apply_url. The external_id field is
echoed from the request when supplied; otherwise it is null.
| Field | Use |
|---|---|
external_id |
Echoed from the request when supplied; otherwise null. |
links.shopping_url |
HealthSherpa public shop URL (https://healthsherpa.com/public/shop?...). |
links.client_apply_url |
HealthSherpa public apply URL (https://healthsherpa.com/public/apply?...). Always present. |
{
"external_id": "crm-lead-abc-123",
"links": {
"shopping_url": "https://healthsherpa.com/public/shop?_agent_id=agent_admin_42&external_id=crm-lead-abc-123&fip_code=36061&household_income=42000&household_size=1&people%5Bprimary%5D%5Bage%5D=36&people%5Bprimary%5D%5Bgender%5D=female&people%5Bprimary%5D%5Btobacco%5D=false&state=NY&user_type=agent&year=2026&zip_code=10001",
"client_apply_url": "https://healthsherpa.com/public/apply?_agent_id=agent_admin_42&external_id=crm-lead-abc-123&fip_code=36061&household_income=42000&household_size=1&people%5Bprimary%5D%5Bage%5D=36&people%5Bprimary%5D%5Bgender%5D=female&people%5Bprimary%5D%5Btobacco%5D=false&plan_hios_id=12345NY0010001&state=NY&user_type=agent&year=2026&zip_code=10001"
}
}
200links.400 invalid_requestcontext fields, unsupported field anywhere in the body, neither location.state nor plan_id supplied, both date_of_birth and age on the same applicant, or campaign fields with flow: "agent_assisted".401 unauthorized403 forbiddenagent_assisted requires a healthy HealthSherpa Marketplace link with an active OAuth connection and unexpired or refreshable access token; self_service requires approved D2C deep-link access and a configured agent ID.413 payload_too_large415 unsupported_media_typeContent-Type is not supported by the endpoint.429 rate_limitedRetry-After header.500 internal_error502 bad_gateway503 service_unavailable504 gateway_timeout{
"error": {
"code": "invalid_request",
"message": "Validation failed.",
"details": {
"zip_code": [
"ZIP code must be 5 digits"
]
}
}
}
Off-Exchange Enrollment API
Approved partners can use this workflow to move an off-exchange application from draft to submission. The lifecycle is draft-based: create an application, update it until validation is clean, submit to the carrier, manage payment or post-submission actions, and track final status.
| Step | Use |
|---|---|
| Create | Open a draft application and attach plan and applicant data. |
| Validate | Inspect the returned errors[] array until the payload is ready. |
| Submit | Send the completed application to the downstream carrier. |
| Pay | Use carrier payment instructions or a payment redirect when supported. |
| Track | Poll status or consume webhook updates after submission. |
- Every create, update, and read response includes an
errors[]array. - An empty
errors[]array means the application is ready to submit. - Supporting documents, payment steps, cancellation, and termination are modeled explicitly.
| Method | Endpoint |
|---|---|
| POST | /api/v1/applicationsCreate a draft application. |
| PUT | /api/v1/applications/:idUpdate a draft application. |
| GET | /api/v1/applications/:idRetrieve details, status, and validation errors. |
| GET | /api/v1/applicationsList applications with pagination and filters. |
| POST | /api/v1/applications/:id/supporting_documentationUpload required documents. |
| POST | /api/v1/applications/:id/submitSubmit the application to the carrier. |
| POST | /api/v1/applications/:id/cancelCancel prior to effectuation. |
| POST | /api/v1/applications/:id/terminateTerminate after effectuation. |
| GET | /api/v1/applications/:id/payment_redirectGet carrier payment form data when redirect payment is supported. |
- Submission confirmation and policy-status events can be delivered by webhook.
- Payment support varies by carrier and may be inline, redirect-based, or phone-assisted.
- Environment-specific access details are shared during approval and onboarding.
Public object schemas are intentionally open so the platform can add optional fields over time without forcing a version bump for every enhancement.
- Ignore response properties they do not recognize.
- Assume object responses may gain new optional fields over time.
- Preserve the fields they understand and safely ignore the rest.
- Use strict serialization or strict deserialization settings that fail on unknown fields.
- Assume object property order is meaningful.
- Treat current response shapes as permanently closed or exhaustive.