https://api.arlohealth.ai/api/pricing.v1. Machine-readable contract: openapi.json next to this file. A drop-in skill file for agent platforms: skill.md.
This guide is the source of truth for how to call the routes and how to read every field. Read it once per session before relaying any number to a person.
What the data is
Estimates come from insurers’ published machine-readable rate files (the federal price-transparency files), matched to a plan, plus public CMS data about providers. Covered insurers: Anthem, any Blue Cross Blue Shield plan (priced through BlueCard host-network schedules), Blue Shield of California, UnitedHealthcare including UMR, Oxford and Surest, Cigna, Aetna, and HCSC (Blue Cross Blue Shield of IL/TX/OK/NM/MT).GET /payers lists the names accepted.
Estimates are never guarantees. Every response carries disclaimer. Relay it every time.
The data is US only. Kaiser, Medicare, Medicaid, and Medi-Cal are not supported: those calls return plan.payer = null with matchTier = no_payer and a needsMoreInfo ask saying so.
Requests
Always send a descriptiveUser-Agent (for example my-bot/1.0). Requests without one, or with a bare HTTP-library agent, may be rejected at the edge.
Every compute route also accepts
GET with flat query parameters (code, zip, latitude, longitude, radiusKm, limit, providerName, npi, payerName, employerName, planName, groupNumber, planUnavailable). Example:
Picking the service code
There is no free-text service input. You choose the CPT/HCPCS code fromGET /catalog because codes carry patient facts the server cannot infer: screening vs diagnostic intent, age band, new vs established patient, body part, contrast, duration. Confirm those facts with the person before you choose. If several codes could apply, ask rather than guess.
An unknown or missing code returns HTTP 200 with a needsMoreInfo ask and the full supportedServices list. Pick the closest code and re-call.
The response echoes a self-describing service block: code, name, appliesTo (the selection fact baked into the code), priceNote (pricing semantics), and relatedCodes (siblings selected by a different patient fact). Verify appliesTo against the actual person before relaying numbers, and switch to a relatedCodes sibling if it fits better. A 55-year-old’s annual physical is 99396, not 99395.
Location
Passlatitude and longitude when you have them, else a 5-digit zip. A ZIP that cannot be placed returns 200 with a location ask. On network-status, location.applied tells you whether the location was consumed; only re-ask when it is false.
Insurance: planHints
Anonymous calls resolve the plan fromplanHints only. Ask the person which insurer they have and pass it as planHints.payerName. Without it the response asks for it.
Read
plan.planHintsReceived after passing hints: matched: true means one of your hints selected the plan (matchedOn says which); matched: false means do not re-ask the person for the same value.
With an Arlo account token the plan can also come from the person’s linked insurance records (plan.payerSource = linked_coverage). This guide covers the anonymous path.
Reading plan
plan.matchTier tells you what the numbers are based on. plan.basis says it in words. Relay basis.
plan.sponsor is the matched plan’s identity string and can carry the plan type (HMO vs PPO). Relay it: plan type routinely flips the same hospital between in- and out-of-network.
plan.coverageNote means part of the plan’s networks is missing from the data. Providers reachable only through those networks may be absent, and “not found” is a weaker out-of-network signal.
The needsMoreInfo loop
needsMoreInfo is an array of asks: field, ask, why, how. Relay the ask to the person in plain words, then re-call with the answer. Answering upgrades ranges to exact rates. The loop ends when the array is empty or the person cannot answer (then set planHints.unavailable = true).
HTTP 200 does not mean “done”. Check needsMoreInfo on every response.
Reading search responses
facilities groups billing NPIs by street address into places of care, best rate first. Present results place-first (facility name, or the address when name is null) with the providers inside.
Per provider:
rateis the exact-plan negotiated rate (null on fallback).rateRange{min, max, median}is the spread across the insurer’s schedules when the exact plan is not matched. When the range is wide, lead withtypicalRateor the median and say it is a range.rateAssessmentfires when the rate is far from typical (1.75x or more, or 0.4x or less). Always relay it.notecarries per-provider caveats such as a facility fee that excludes the physician’s separate bill. Relay it with the number.serviceEvidence:observed(this NPI bills this service in public Medicare claims),category_observed(bills near-identical services), orunconfirmed(no record found). A contracted rate proves the code is in the contract, not that the service is bookable here. Never say a provider does not offer a service: the data misses non-Medicare practices.billingOrgis the legal entity whose contract the rate comes from.multiEntity: truemeans the NPI prices under several contracting entities and the shown rate is only the cheapest candidate. For a specific-provider quote, confirm throughnetwork-statusrather than quoting this row.signals(when present) are pre-gated public-CMS evidence. Relay each signal’sdisplaysentence as written. Never compress a percentile into “best doctor”. Never treat absence as negative. Anexclusionsignal (federal OIG exclusion list) is a legal-status safety notice: relay it plainly.medicareAnchoris a reference point.source: observedis what Medicare actually paid this provider;source: scheduleis the area’s fee-schedule rate. Neither is the person’s price or a fair-price claim.
activityNotemeans no provider there shows observed billing in public claims data. Payer files list outdated locations for years, so advise verifying the location is operating.latitude,longitude,locationPrecisionsupport maps.zip_centroidis one shared point for the whole ZIP; do not pin it as the exact location.
totalFoundcounts eligible in-network providers in the area.facilitiesis the nearest subset with usable rates.rateFetchNotemeans the response is bounded: schedules were sampled evenly (rateSampled: trueon affected rows) and/or the page covers only the nearest subset of a much larger pool. Relay it: a cheaper option may exist farther out.sortBasisstates the ordering contract: price within evidence tiers. Places with observed billing list first, each tier cheapest first, so a cheaper unconfirmed option can sit below confirmed performers. Say so when presenting order.
Reading network-status responses
matches is the list of billing entities the name or NPI matched. Read these in order:
identityCaution: a same-name person far from the given location. Verify before relaying anything.inNetwork:truemeans the provider appears WITH negotiated rates in the plan’s published files.falsemeans not found in the published files. Readnotefor how strong that signal is. Never state a hard “out of network”.billingOutlookon a rated match, FIRST.mode: single(one entity, quote it),resolvedorlikely(a leading entity with its evidence basis: lead with it and mention alternatives), orpartitioned(the price depends on WHO BILLS: relay the outlook’saskin patient-answerable terms, walk the branch the answer selects, and never quote one number while partitioned). Awarningis binding: a brand-name match does not establish the biller. Brand-operated clinics in partner markets can bill through an affiliated health system at several times the rate.billingCandidates: one branch per contracting entity, cheapest first, each withevidencetags (observedfrom adjudicated claims;payer_credentialedfrom the insurer’s own directory with an as-of date, which nominates but never settles;brand_disclosed;employer;brand_registration). A branch showingrateRangeinstead ofratehas real internal spread; present the range, never its minimum.billingCandidatesOmittedmeans more entities exist than were listed.billingNoteis present when there are multiple candidates. Never quote a single rate without resolving the entity. Who operates the clinic is usually public; for a past visit the EOB’s billing name or NPI settles it. Re-call with thatnpi.rateAssessment,rateNote,serviceEvidence,signals,medicareAnchorread as insearch.matchNotemarks matches appended by re-searching the name WITHIN the plan’s files when the regular matches were all outside it. Often the system’s main billing entity at another location. Verify identity before relying on it.networkEvidencecounts how many of the plan’s network memberships back the in-network claim. 1 to 2 is thin; 10 or more is broad participation.
inNetwork: false, that is not an out-of-network verdict. A name search checks the entities the NAME matched, not the entity that actually bills. Health systems and brands bill through legal entities that do not carry the consumer name. Resolve the billing NPI before giving any verdict; the needsMoreInfo provider_identity ask says how.
Confirm the person’s current city or ZIP first for “how much does this practice cost me” questions. The same brand bills under different legal entities in different markets at very different rates.
Reading provider-evidence responses
signals carry a display sentence each. Relay as written or summarize without changing meaning. level: facility describes the facility, never the clinician. An absence or optout signal explains missing data; absence is never negative evidence. medicareAnchors are what Medicare actually paid this provider per service: reference points, not the person’s price. There is no composite score and evidence never re-ranks price results. Do not manufacture an overall rating.
Errors and limits
Anonymous calls are rate limited per IP per minute (search 60, network-status 20, provider-evidence 60) and share a concurrency cap. A 429 carries Retry-After and error of RATE_LIMITED or BUSY. A 503 with PRICING_PUBLIC_DISABLED means anonymous pricing is paused. In all three cases tell the person the lookup is temporarily unavailable. Do not invent prices.
Malformed JSON returns 400 INVALID_JSON. Unknown paths return 404 NOT_FOUND with a link back to this guide. Server failures return 500 with PRICING_SEARCH_FAILED, PRICING_NETWORK_STATUS_FAILED, or PROVIDER_EVIDENCE_FAILED.
Every response carries X-Arlo-Api-Version and a Link header pointing at this guide (rel="service-doc") and the OpenAPI document (rel="service-desc").