HealthCare.gov
The federal ACA Marketplace: the health and dental plans a household can actually buy for its ZIP and income, with premiums both before and after the…
The federal ACA Marketplace: the health and dental plans a household can actually buy for its ZIP and income, with premiums both before and after the premium tax credit, plus the eligibility estimate that sets those prices, whether a plan covers a given doctor or prescription, when a life change opens an enrolment window, and where to find in-person help.
Domain: healthcare.gov
Also known as: HealthCare.gov, healthcare.gov, Health Insurance Marketplace, ACA Marketplace, Obamacare
Call it directly
bowmark.providers.healthcare_gov.searchPlans({ zip, income, people?, year?, countyfips?, limit? }): Promise<{ county: healthcare_govCounty; otherCounties: healthcare_govCounty[]; year: number; total: number; plans: healthcare_govPlan[] }>
bowmark.providers.healthcare_gov.getPlan({ id, year? }): Promise<healthcare_govPlanDetail>
bowmark.providers.healthcare_gov.checkDrugCoverage({ drug, zip?, income?, people?, year?, countyfips?, limit?, planIds? }): Promise<{ drug: healthcare_govDrug; otherMatches: healthcare_govDrug[]; county: healthcare_govCounty | null; otherCounties: healthcare_govCounty[]; year: number; total: number | null; cheapestCovering: healthcare_govDrugPlanCoverage | null; plans: healthcare_govDrugPlanCoverage[] }>
bowmark.providers.healthcare_gov.checkProviderCoverage({ provider, zip?, providerType?, income?, people?, year?, countyfips?, limit?, planIds? }): Promise<{ provider: healthcare_govProvider; county: healthcare_govCounty | null; otherCounties: healthcare_govCounty[]; year: number; total: number | null; cheapestCovering: healthcare_govProviderPlanCoverage | null; plans: healthcare_govProviderPlanCoverage[] }>
bowmark.providers.healthcare_gov.searchDentalPlans({ zip, people?, year?, countyfips?, limit? }): Promise<{ county: healthcare_govCounty; otherCounties: healthcare_govCounty[]; year: number; total: number; plans: healthcare_govDentalPlan[] }>
bowmark.providers.healthcare_gov.estimateOutOfPocketCosts({ zip, income, people?, year?, countyfips?, limit? }): Promise<{ county: healthcare_govCounty; year: number; total: number; plans: healthcare_govPlanCostEstimate[]; cheapest: { byMonthlyPremium: string; byYearlyCost: string; samePlan: boolean } | null }>
bowmark.providers.healthcare_gov.checkEnrollmentEligibility(query: healthcare_govEnrollmentQuery): Promise<healthcare_govEnrollmentEligibility>
bowmark.providers.healthcare_gov.estimateEligibility({ zip, income, people, year?, countyfips? }): Promise<healthcare_govEligibilityEstimate>
bowmark.providers.healthcare_gov.findLocalHelp({ zip, radiusMiles?, types?, limit? }): Promise<healthcare_govLocalHelpResult>Functions
| Function | What it does |
|---|---|
searchPlans | The ACA Marketplace plans a household can actually buy, cheapest premium first, each with its monthly premium before AND after the advance premium tax credit, its deductible, out-of-pocket… |
getPlan | One Marketplace plan's WHOLE benefit schedule, by its HIOS plan id — the benefit-by-benefit cost sharing a search result does not carry. |
checkDrugCoverage | Which of a household's available ACA Marketplace plans cover a specific prescription — the number that moves the real cost of a plan by more than its premium does for anyone on an ongoing… |
checkProviderCoverage | Which of a household's available ACA Marketplace plans have a specific doctor, hospital or facility IN NETWORK — the question that decides a plan choice for anyone who already has a… |
searchDentalPlans | The STANDALONE dental plans a household can buy on the ACA Marketplace, cheapest premium first — a different product from the health plans searchPlans returns, sold and rated separately,… |
estimateOutOfPocketCosts | What each Marketplace plan is estimated to cost a household FOR THE YEAR — twelve after-credit premiums plus CMS's own out-of-pocket estimate — at low, medium and high healthcare use,… |
checkEnrollmentEligibility | Answers whether somebody can enrol in Marketplace coverage right now and until when — the question that decides whether searchPlans output is buyable or just informational. |
estimateEligibility | What financial help a household is estimated to get on the ACA Marketplace, BEFORE pricing any plan — the monthly advance premium tax credit, which cost-sharing-reduction variant it… |
findLocalHelp | The in-person help available near a ZIP — the Navigators, Certified Application Counselors, agents and brokers CMS lists as able to enrol somebody in Marketplace coverage — each with the… |
Types
interface healthcare_govPlan {
/** HIOS plan id — the identifier every other read on this site is keyed on. */
id: string;
name: string;
issuer: string;
issuerId: string;
/** Bronze | Silver | Gold | Platinum | Catastrophic. */
metalLevel: string;
/** HMO | PPO | EPO | POS. */
planType: string;
/** Monthly premium BEFORE the advance premium tax credit. */
premium: number;
/** Monthly premium AFTER the credit this household qualifies for. Equals
* premium when the household is not APTC-eligible; 0 when the credit covers
* the whole premium, which is a real answer at low incomes. */
premiumWithCredit: number;
/** What the household pays before cost sharing starts. Three fields because
* the Marketplace publishes two shapes: most plans combine medical and drug
* into one deductible, a minority split them, and reading only the first
* would report "$0 deductible" for a plan with a $4,500 drug deductible. */
deductible: {
combined: number | null;
medical: number | null;
drug: number | null;
/** Which cost-sharing-reduction variant these figures are for — the API
* resolves it against the household, so two households see different
* numbers for the same plan id. */
csr: string | null;
};
/** In-network maximum out-of-pocket for the year, or null if unpublished. */
outOfPocketMax: number | null;
hsaEligible: boolean;
hasNationalNetwork: boolean;
specialistReferralRequired: boolean;
/** CMS global quality rating, 1-5 stars, or null when not rated. Never 0. */
qualityRating: number | null;
/** Why the rating is null, in CMS's words (e.g. "New-Ineligible for
* Scoring"). Null when the plan IS rated. */
qualityRatingNote: string | null;
benefitsUrl: string | null;
networkUrl: string | null;
}
interface healthcare_govCounty {
name: string;
/** 5-digit FIPS code. */
fips: string;
state: string;
}
/** What one benefit costs on one network tier. `copay` and `coinsuranceRate`
* are nullable rather than 0 because the Marketplace publishes both keys on
* every row and marks the inapplicable one `Not Applicable` — reading the
* padding 0 as "0% coinsurance" would report a $100-copay plan as covering
* specialists in full. `display` is CMS's own rendering and the authority. */
interface healthcare_govBenefitCostSharing {
/** `In-Network` or `Out-of-Network`. */
networkTier: string;
/** Flat dollar copay, or null when expressed as coinsurance. */
copay: number | null;
/** Member's share, 0-1 (0.5 = 50%), or null when expressed as a copay. A rate
* of 1 with `display` "Not Covered" means you pay all of it. */
coinsuranceRate: number | null;
/** e.g. `$100`, `50% Coinsurance after deductible`, `No Charge`, `Not Covered`. */
display: string;
/** True when the plan pays this BEFORE the deductible is met (CMS's `BBD`) —
* what decides whether a $7,500 deductible stands in front of a routine visit. */
beforeDeductible: boolean;
}
interface healthcare_govBenefit {
/** CMS's own code, e.g. `SPECIALIST_VISIT`. Stable across issuers and years,
* so match on this rather than on `name`. */
type: string;
name: string;
/** Read this BEFORE the cost sharing — an uncovered benefit still carries a
* cost-sharing row. */
covered: boolean;
costSharing: healthcare_govBenefitCostSharing[];
explanation: string | null;
exclusions: string | null;
/** e.g. 30 `visits per year`. Null when the plan publishes no limit, and also
* when it flags a limit but describes it in `exclusions` prose instead of a
* number — "0 of nothing" would read as "capped at zero". */
limit: { quantity: number; unit: string } | null;
}
/** A cost figure published per household size. All nullable: a plan publishes
* only the tiers it offers. */
interface healthcare_govCostTier {
individual: number | null;
family: number | null;
/** The per-person cap INSIDE a family policy — lower than `family`, and what
* one person on a family plan actually hits first. */
familyPerPerson: number | null;
}
interface healthcare_govDeductibleDetail {
combined: healthcare_govCostTier | null;
medical: healthcare_govCostTier | null;
drug: healthcare_govCostTier | null;
}
/** CMS's standard Summary of Benefits scenario, costed for this plan. */
interface healthcare_govCoverageExample {
copay: number;
coinsurance: number;
deductible: number;
/** Cost falling outside covered benefits. */
limit: number;
}
interface healthcare_govQualityRating {
/** Overall, 1-5, or null when not rated. Never 0. */
global: number | null;
/** Why `global` is null, in CMS's words. */
notRatedReason: string | null;
clinicalQualityManagement: number | null;
enrolleeExperience: number | null;
planEfficiency: number | null;
}
/** One plan AS FILED — the whole benefit schedule, with no household applied.
* Deliberately carries NO premium: this endpoint takes no household, so the
* Marketplace answers 0 for premium, after-credit premium and out-of-pocket
* estimate alike, and publishing those would say the plan is free. */
interface healthcare_govPlanDetail {
/** HIOS plan id. */
id: string;
name: string;
issuer: string;
issuerId: string;
/** Bronze | Silver | Gold | Platinum | Catastrophic for a health plan; a
* standalone dental plan answers on this same endpoint with its own
* `High`/`Low` scale here. */
metalLevel: string;
/** HMO | PPO | EPO | POS. */
planType: string;
/** Which cost-sharing variant every figure below belongs to, in CMS's words —
* effectively always `Exchange variant (no CSR)`, because no household is
* supplied. A household that qualifies for cost-sharing reductions pays LESS
* than these figures; `searchPlans` is where its real numbers come from. */
costSharingVariant: string | null;
/** Every benefit the plan files — 67 on the plan measured, against the 10 a
* search result carries. */
benefits: healthcare_govBenefit[];
deductible: healthcare_govDeductibleDetail;
outOfPocketMax: healthcare_govCostTier | null;
qualityRating: healthcare_govQualityRating;
/** Keyed by CMS's own scenario names (`baby`, `diabetes`, `fracture`). */
coverageExamples: Record<string, healthcare_govCoverageExample>;
hsaEligible: boolean;
hasNationalNetwork: boolean;
specialistReferralRequired: boolean;
/** WHICH specialties need a referral, in CMS's own comma-separated text.
* `specialistReferralRequired` alone does not say, and on the plan measured
* the answer was a 20-specialty list rather than "all of them". */
specialistReferralText: string | null;
standardizedPlan: boolean;
rxThreeMonthMailOrder: boolean;
benefitsUrl: string | null;
networkUrl: string | null;
brochureUrl: string | null;
formularyUrl: string | null;
}
interface healthcare_govDentalPlan {
/** HIOS plan id. */
id: string;
name: string;
issuer: string;
issuerId: string;
/** `High` or `Low` — dental's own two-tier scale, NOT the Bronze/Silver/Gold
* metal levels a medical plan carries. */
coverageLevel: string;
/** HMO | PPO | EPO | POS. */
planType: string;
/** Monthly premium. There is no credit-adjusted counterpart: the advance
* premium tax credit attaches to a medical plan, and the Marketplace returned
* `premium_w_credit` equal to `premium` on every dental plan measured. */
premium: number;
/** Whether braces are covered, children and adults separately. `null` means
* the plan does not name that benefit — never collapsed into false. Child
* orthodontia is a pediatric essential health benefit and was covered by 43 of
* 43 plans measured, so ADULT is the side that discriminates: 5 of 43. */
orthodontia: { child: boolean | null; adult: boolean | null };
/** Every benefit the plan declares, in CMS's own vocabulary — routine, basic
* and major dental care for adults and children, orthodontia, accidental
* dental. */
benefits: { name: string; covered: boolean; explanation: string | null }[];
/** How long before the plan starts paying, in the issuer's words, or null for
* no waiting period. */
waitingPeriod: string | null;
/** The age a child ages off this plan. */
maxChildAge: number | null;
/** CMS's "Medical EHB Deductible". On a standalone dental plan the essential
* health benefit is the PEDIATRIC dental benefit, so this is a pediatric
* figure and not what an adult pays before cover starts. Read it with
* `brochureUrl`, not instead of it. */
ehbDeductible: number | null;
/** "Maximum Out of Pocket for Medical EHB Benefits", same pediatric caveat.
* NOT the plan's annual maximum benefit — the Marketplace does not publish
* that number machine-readably anywhere; it is in the brochure. */
ehbOutOfPocketMax: number | null;
hasNationalNetwork: boolean;
/** The Summary of Benefits — the one place the annual maximum, per-service
* coinsurance and any waiting period are actually written down. */
brochureUrl: string | null;
benefitsUrl: string | null;
networkUrl: string | null;
}
interface healthcare_govCostEstimate {
/** CMS's estimated out-of-pocket spend for the year — deductible, copays and
* coinsurance, NOT premiums. Null when the Marketplace computed none for this
* plan, rather than a zero that would read as "free to use". */
outOfPocket: number | null;
/** The whole year: twelve after-credit premiums plus outOfPocket. This is the
* figure HealthCare.gov itself shows as "Your estimated yearly cost". */
totalYearly: number | null;
}
interface healthcare_govPlanCostEstimate {
/** HIOS plan id — joins back to searchPlans. */
id: string;
name: string;
issuer: string;
metalLevel: string;
planType: string;
/** Monthly premium AFTER the advance premium tax credit. */
monthlyPremium: number;
yearlyPremium: number;
/** The ceiling the "high" estimate runs into: a plan whose high.outOfPocket
* equals this is capped here rather than genuinely estimated that low. */
outOfPocketMax: number | null;
estimates: {
low: healthcare_govCostEstimate;
medium: healthcare_govCostEstimate;
high: healthcare_govCostEstimate;
};
}
interface healthcare_govDrug {
/** RxNorm concept unique identifier — the id every drug read here is keyed on. */
rxcui: string;
/** Brand or generic name as the Marketplace prints it, e.g. "LIPITOR". */
name: string;
/** e.g. "20 mg", "100 mg/ml". Coverage differs by strength. */
strength: string;
/** How it is taken, in the Marketplace's words: "Oral Pill", "Injectable". */
route: string;
/** RxNorm's full description, e.g. "atorvastatin 20 MG Oral Tablet [Lipitor]". */
fullName: string;
doseForm: string;
}
/** `covered` — on the plan's formulary. `genericOnly` — this drug is NOT, but a
* generic equivalent is. `notCovered` — neither is. `unknown` — the issuer
* published no formulary data for this plan, which is NOT a soft no. */
type healthcare_govDrugCoverageStatus = "covered" | "genericOnly" | "notCovered" | "unknown";
interface healthcare_govDrugPlanCoverage {
/** HIOS plan id. */
planId: string;
/** Null on the `planIds` route, where no search page named the plan. */
planName: string | null;
issuer: string | null;
/** Null on the `planIds` route — the premium is priced by the plan search. */
premium: number | null;
/** After the credit. 0 is a real answer at low incomes, never a missing one. */
premiumWithCredit: number | null;
status: healthcare_govDrugCoverageStatus;
/** The generic equivalent this plan covers instead, resolved from the bare
* RxCUI the Marketplace returns to a real named drug. Only populated on
* `genericOnly`. */
generic: { drug: healthcare_govDrug } | null;
/** The plan's formulary document — the ONLY place the tier, the copay and any
* prior-authorization or step-therapy requirement are written down. The
* Marketplace's API publishes none of those. */
formularyUrl: string | null;
}
interface healthcare_govAddress {
street1: string;
street2: string;
city: string;
state: string;
zip: string;
phone: string | null;
}
interface healthcare_govProvider {
/** National Provider Identifier — the id every coverage read here is keyed on. */
npi: string;
name: string;
/** `Individual` (a person) or `Facility` (a hospital, clinic or pharmacy) —
* the Marketplace's own two words, and what its `type` filter takes. */
providerType: string;
/** Populated for an Individual — "Emergency Medicine", "Physician Assistant". */
specialties: string[];
/** Populated for a Facility — "ACH" (acute care hospital), "Retail Pharmacy". */
facilityTypes: string[];
taxonomy: string;
gender: string;
languages: string[];
/** Where the directory search found them. Null on the NPI route, which takes
* no location. */
address: healthcare_govAddress | null;
distanceMiles: number | null;
}
/** `covered` — in network. `notCovered` — not. `unknown` — the issuer published
* no provider-network data for this plan at all, which is NOT a soft no: the
* Marketplace's own front end renders it as a warning rather than as an absence
* of cover. */
type healthcare_govProviderCoverageStatus = "covered" | "notCovered" | "unknown";
interface healthcare_govProviderPlanCoverage {
/** HIOS plan id. */
planId: string;
/** Null on the `planIds` route, where no search page named the plan. */
planName: string | null;
issuer: string | null;
/** Null on the `planIds` route — a premium is priced against a household, and
* that route has none to price against. */
premium: number | null;
premiumWithCredit: number | null;
/** The plan's own provider directory — the only place its network is written
* down in full, and the analog of `formularyUrl` on a drug row. */
networkUrl: string | null;
status: healthcare_govProviderCoverageStatus;
/** Whether the provider takes new patients under THIS plan. Read it before
* choosing: `covered` + `notAccepting` is a plan whose in-network doctor will
* not see you. */
accepting: "accepting" | "notAccepting" | "unknown";
/** The provider's locations that are in network UNDER THIS PLAN — not their
* whole address list. Empty whenever the plan does not cover them. */
inNetworkAddresses: healthcare_govAddress[];
}
/** One person's slice of an eligibility estimate. Only `medicaidChip` is
* genuinely per-person; `age` and `relationship` are echoed back from the
* request so a caller can tell WHICH person each verdict is about. */
interface healthcare_govEligibilityPerson {
age: number;
/** `Self`, `Spouse`, `Child`, … — as sent, or as defaulted by age. */
relationship: string;
/** CMS's estimate that THIS person qualifies for Medicaid or CHIP instead of a
* subsidised Marketplace plan. It really does split within one household:
* children reach CHIP at incomes well above the adult Medicaid line. */
medicaidChip: boolean;
}
interface healthcare_govEligibilityEstimate {
/** The county the estimate was priced for — a ZIP can straddle two, and which
* one was used is never left silent. */
county: { name: string; fips: string; state: string };
zip: string;
year: number;
/** The annual household income it was computed FROM, echoed back. */
income: number;
/** Monthly advance premium tax credit FOR THE WHOLE HOUSEHOLD, in dollars —
* NOT per person. A caller summing a per-person list would report four times
* the real credit, which is why this is one field. `0` is a real answer. */
monthlyAptc: number;
/** Which cost-sharing-reduction variant applies, in CMS's own words
* (`"87% AV Level Silver Plan CSR"`). Null when none does. */
csr: string | null;
/** CMS's own hardship-exemption flag, passed through rather than re-derived. */
hardshipExemption: boolean;
/** Income too low for a premium tax credit, in a state that did not expand
* Medicaid, so neither route is open. The field that makes this estimate worth
* calling: the identical household at $15,000 is `inCoverageGap` in Texas and
* `medicaidChip` in Ohio. */
inCoverageGap: boolean;
/** One row per person sent, in the order they were sent. */
people: healthcare_govEligibilityPerson[];
/** How many of them CMS estimates into Medicaid or CHIP. `0` and
* `people.length` are both ordinary; anything between is the split case. */
medicaidChipCount: number;
}
interface healthcare_govEnrollmentQuery {
/** Five-digit US ZIP. */
zip: string;
/** A life change's date, ISO `YYYY-MM-DD`. Omit for the calendar alone. */
lifeEventOn?: string;
/** Which published category it was, e.g. "Moved to a new home". Validated
* against the site's live list; omit to report every category that covers it. */
lifeEventCategory?: string;
/** Evaluate against this date instead of today, ISO `YYYY-MM-DD`. */
asOf?: string;
}
interface healthcare_govLifeEventCategory {
category: string;
windows: { direction: "past" | "next"; days: number }[];
examples: string[];
}
interface healthcare_govOpenEnrollment {
/** HealthCare.gov's own flag, not arithmetic over the dates below. */
isOpen: boolean;
coversPlanYear: number;
startsOn: string;
endsOn: string;
daysLeft: number | null;
daysUntilOpen: number | null;
}
interface healthcare_govSepAssessment {
eventOn: string;
qualifies: boolean;
matches: {
category: string;
direction: "past" | "next";
windowDays: number;
/** Last day this category's window can still be used, ISO `YYYY-MM-DD`. */
windowEndsOn: string;
daysLeft: number;
}[];
}
interface healthcare_govMarketplace {
/** CMS's own code: `FFM`, `SBM`, `SupportedSBM`, `UnknownMarketplaceModel`. */
model: string;
name: string | null;
url: string | null;
/** Whether HealthCare.gov itself can enrol this ZIP. */
servesThisZip: boolean;
}
interface healthcare_govEnrollmentEligibility {
zip: string;
county: string;
countyFips: string;
state: string;
stateName: string;
planYear: number;
marketplace: healthcare_govMarketplace;
openEnrollment: healthcare_govOpenEnrollment;
qualifyingLifeEvents: healthcare_govLifeEventCategory[];
specialEnrollmentPeriod: healthcare_govSepAssessment | null;
/** False means "no window from the calendar or this life change" — NOT "no
* coverage available". Income-based Medicaid/CHIP and Tribal membership are
* open all year and are not assessed here. */
canEnrollNow: boolean;
asOf: string;
}
// Find Local Help — who near a ZIP can sit down with somebody and enrol them.
/** `assister` (a Navigator or Certified Application Counselor), `agent`, and the
* two service-area kinds. HealthCare.gov's own filter vocabulary. */
type healthcare_govHelperType = "assister" | "agent" | "statewide" | "multistate";
interface healthcare_govHelperAddress {
street: string[];
city: string;
state: string;
zip: string;
latitude: number | null;
longitude: number | null;
/** Whether somebody can turn up without an appointment. */
walkInsWelcome: boolean;
accessibleLocation: boolean;
/** The directory's own note on finding the place. Null when blank. */
note: string | null;
}
interface healthcare_govHelperHours {
/** `mon` … `sun`. */
day: string;
/** `HH:MM:SS`, local to the helper's `timezone`. */
opensAt: string;
closesAt: string;
appointmentRequired: boolean;
}
interface healthcare_govLocalHelper {
id: number;
name: string;
/** The organisation they work under, when the directory names one. */
organisation: string | null;
/** TRUE = an agent or broker, paid by commission, selling only the plans they
* carry. FALSE = an assister, certified by CMS and REQUIRED to give fair,
* impartial, accurate information about every Marketplace plan. This is the
* field that decides whether the help is free and impartial. */
isAgentOrBroker: boolean;
/** The directory's own labels, verbatim — `Agent/Broker (ABA)`, `Certified
* Application Counselor (CAC)`, … */
helperTypes: string[];
/** Miles from the searched ZIP. Null on a statewide listing. */
distanceMiles: number | null;
address: healthcare_govHelperAddress;
/** Digits as published — no reformatting, because the directory mixes formats. */
phones: string[];
emails: string[];
websites: string[];
/** `English`, `Spanish`, … in the directory's own words. */
languages: string[];
hours: healthcare_govHelperHours[];
timezone: string | null;
/** Null when unreported — never 0, which would read as "brand new". */
yearsOfService: number | null;
/** Every state they are licensed to serve. More than one is common for a
* broker, and is why a nearby result is not necessarily a local one. */
statesServed: string[];
accessibilityServices: string[];
/** The directory's own contact-card download for this helper. */
vcardUrl: string;
}
interface healthcare_govLocalHelpResult {
zip: string;
/** What the geocoder resolved the ZIP to. */
city: string;
state: string;
searchedFrom: { latitude: number; longitude: number };
radiusMiles: number;
/** Everyone matching inside the radius, across every page — not how many rows
* this call returned. */
total: number;
/** The split of `total`. Read it before the rows: the default ordering is by
* distance and is dominated by brokers. */
totalAgentsAndBrokers: number;
totalAssisters: number;
hasMore: boolean;
helpers: healthcare_govLocalHelper[];
}Examples
// Outside Open Enrollment: did losing my job coverage three weeks ago open a window?
const e = await bowmark.providers.healthcare_gov.checkEnrollmentEligibility({
zip: "78701",
lifeEventOn: "2026-07-10",
lifeEventCategory: "Loss of health coverage",
});
return {
canEnrollNow: e.canEnrollNow,
qualifies: e.specialEnrollmentPeriod?.qualifies,
deadline: e.specialEnrollmentPeriod?.matches[0]?.windowEndsOn,
nextOpenEnrollment: e.openEnrollment.startsOn,
};// Check the door before pricing anything behind it.
const e = await bowmark.providers.healthcare_gov.checkEnrollmentEligibility({ zip: "10001" });
if (!e.marketplace.servesThisZip) {
log(`${e.stateName} runs its own exchange: ${e.marketplace.name} — ${e.marketplace.url}`);
return e.marketplace;
}
const plans = await bowmark.providers.healthcare_gov.searchPlans({
zip: e.zip, income: 52000, people: [{ age: 35 }], limit: 5,
});
return plans.plans.map((p) => `${p.name} — $${p.premiumWithCredit}/mo`);