https://api.arlohealth.ai/api/pricing.v1
Read this guide once per conversation before you relay any number. The machine-readable contract is at /openapi.json. A drop-in skill file is at /skill.md.
Quick start
Send aUser-Agent header that names your agent. Requests with no user agent may be refused.
disclaimer. Say it to the person every time: these are estimates from published data, not a guarantee of what they will pay.
What you can answer
- The estimated in-network price of about 170 common outpatient services near a location: office and preventive visits, therapy, imaging (X-ray, CT, MRI, ultrasound, mammograms, DEXA), heart tests, common labs and STI tests, physical therapy and chiropractic, colonoscopy and endoscopy, injections, biopsies, IUD, vasectomy, sleep studies, and more.
- Whether a named doctor, clinic, brand, or hospital is in the person’s network, and what their contract prices a service at.
- Public-data evidence about one provider: how often they perform a procedure, facility outcome context, what Medicare paid them.
GET /payers lists the names the API recognizes.
Not covered: Kaiser, Medicare Advantage plans, Medicaid, Medi-Cal, Tricare, and any insurer not listed. Those return plan.payer = null with a needsMoreInfo ask saying so. Tell the person plainly that their plan is not supported yet.
Not covered: what the person will pay out of pocket on commercial insurance. The API returns the negotiated rate between the insurer and the provider. Deductibles, copays, and coinsurance are not modeled. Say “the negotiated rate is about $X; what you pay depends on your deductible and plan design.” Original Medicare is the exception: its cost sharing is set by law, and the response computes it (see the Original Medicare section).
What to get from the person
The more of this you collect, the more precise the answer. Ask for the top items first; the rest only when the response asks (needsMoreInfo) or the person volunteers them.
Do not ask for anything you cannot use: member ID, date of birth, or the subscriber’s name never change the answer. Never ask for a Social Security number.
The routes
All lookups acceptGET with the flat query parameters below, or POST with a JSON body where the plan fields nest under planHints (payerName, employerName, planName, groupNumber, unavailable). Discovery routes are cacheable for an hour.
GET /catalog
The list of services the API can price: code, name, category, appliesTo (the fact that selects this code, such as “established patient, low complexity”), and relatedCodes (siblings selected by a different fact). Pick from this list. There is no free-text service search, because the choice depends on facts about the person that only you can confirm.
If you pass a code that is not in the catalog, the response is HTTP 200 with a needsMoreInfo ask and the full supportedServices list. Pick the closest code and call again.
GET /payers
The insurers the API recognizes, the names it accepts for each, and which identifiers can select an exact plan for that insurer.
search: what does this service cost around here
Parameters: code (required in practice), zip or latitude + longitude, payerName (required for a priced answer), employerName, planName, groupNumber, planUnavailable, radiusKm (default 40), limit (default 25 places).
Returns facilities: places of care near the location, best price first, each with the providers who bill from that address and their rates. Use it for “how much is an MRI near me” and “where is the cheapest place for a physical.” It is area discovery. It does not tell you which legal entity a particular clinic bills through, so the moment the person names a clinic or doctor, switch to network-status.
network-status: is this provider in my network, and what do they charge
Parameters: providerName and/or npi, zip or coordinates (use the clinic’s location), optional code for a price, the same plan fields as search, limit (default 50, max 100).
Returns matches: the billing entities the name or NPI matched, each with inNetwork, a rate for the code if given, and a breakdown of which legal entities could bill for that provider (billingCandidates, billingOutlook). Call this first for any named doctor, clinic, brand, or hospital. Large health systems bill under many NPIs whose network status differs; the breadth of matches is the signal, so do not cut limit too low.
provider-evidence: what public data says about one provider
Parameters: npi (required), optional code to scope the evidence to one service.
Returns signals (procedure volume, facility outcome context, or an explained absence), medicareAnchors (what Medicare actually paid this provider), and a legend. Use it once the conversation is about one specific provider. Do not use it to rank a list.
The conversation loop
Responses use HTTP 200 even when they need something from you. Always checkneedsMoreInfo. Each entry has a field, an ask written for the person, a why, and a how (ask them, read a bill, or look something up). Relay the ask, get the answer, call again with it. Common asks:
service: no code was given. Pick one fromsupportedServices.code: the code is not in the catalog. Pick the closest one fromsupportedServices.location: no usable ZIP or coordinates.insurance: the insurer named is not supported. Tell the person plainly; ask whether they have other coverage.employer_or_plan: the insurer is known but not the exact plan. Ask for the employer or the plan name on the card. If the person cannot provide one, setplanUnavailable=true.group_number: the group number given does not look like a card group number (real ones contain digits). Check the value printed next to “Group” on the card before asking again.provider: nothing to look up. Give a name (city helps) or an NPI.npi: the NPI is malformed (10 digits, starting with 1 or 2) or not in the data. Verify it at npiregistry.cms.hhs.gov, or search by name.provider_identity: the name matched entities that are all outside the network, and the entity that actually bills may not carry that name. Find the billing NPI (past bill or EOB, or the practice’s website) and call again withnpi.search_area: nothing in range. WidenradiusKmor confirm the location.medicare_type: the person said “Medicare” without saying which kind. The numbers assume Original Medicare. Ask whether they have the red, white and blue card or a plan through an insurer, and re-call withpayerName“Original Medicare” or “Medicare Advantage”.payer: only with an account token, when the person’s linked records show more than one active coverage. Ask which applies and pass it aspayerName.auth: you passedpatientIdwithout an account token. Drop it.
plan.planHintsReceived. matched: true means one of them selected the plan (matchedOn says which). matched: false means do not ask the person for that value again.
Reading the numbers
plan.matchTier tells you what kind of number you have. plan.basis says it in a sentence; relay it.
Per provider or match:
rate: the exact negotiated rate.nullwhen only a range is available.rateRange{min, max, median}: the spread across the insurer’s plans. When it is wide, lead withtypicalRateor the median and say it is a range.typicalRate: the median rate for this service among this insurer’s members. A useful anchor when the range is wide.rateAssessment: present when the rate is far from typical (about 1.75x or more, or 0.4x or less). Always relay it. This is how a routine visit billed under a hospital contract at four times the going rate becomes visible.noteandservice.priceNote: pricing semantics that change the meaning of the number. Examples: therapy billed per 15 minutes, preventive care usually $0 out of pocket under the ACA, a facility fee that excludes the physician’s separate bill. Relay whenever present.setting:officeorfacility. A facility rate is the building’s charge; the physician bills separately.serviceEvidence:observedmeans this provider actually bills this service in public Medicare claims;category_observedmeans they bill near-identical services;unconfirmedmeans no record was found. A contracted rate proves the code is in the contract, not that the service is bookable there. Never say a provider does not offer a service; the data misses practices that do not bill Medicare.
Reading search results
Present results place-first: the facility name, or the address when name is null (independent practitioners), then the providers inside with their rates.
totalFoundis how many eligible in-network providers exist in the area.facilitiesis the nearest subset with usable rates. WhenrateFetchNoteis present, say that the list is the nearest options and a cheaper one may exist farther out; raisinglimitwidens the pool.sortBasisstates the ordering: places with observed billing for the service first, each group cheapest first. A cheaper unconfirmed option can sit below confirmed ones. Say so if you present the order.activityNoteon a facility: no provider there shows recent billing in public data. Insurer files keep closed locations for years. Advise confirming the location is open before sending anyone.identityNoteon a facility: its organization name covers several places of different kinds in these results (the hospital, its FQHC subpart, student health). Say which kind this place is. A cheaper same-name subpart is not the hospital.billingOrgandmultiEntityon a provider: the legal entity whose contract the rate comes from.multiEntity: truemeans this provider prices under several entities and the shown rate is only the cheapest. For a quote at a specific clinic, usenetwork-statusinstead of this row.latitude,longitude,locationPrecision: for maps.zip_centroidis one point for the whole ZIP; do not present it as the exact address.signalsandmedicareAnchorread as described under provider evidence.
Reading network-status results
Work through each match in this order.
identityCaution: a same-name person far from the given location. Confirm it is the right person before saying anything.inNetwork.truemeans the provider appears with negotiated rates in the plan’s published network files.falsemeans “not found in the published files.” Readnotefor how strong that is. Never state a hard “they are out of network.” When every match isfalse, that is still not a verdict: the entity that actually bills may not carry the consumer name. Resolve the billing NPI first (theprovider_identityask says how).billingOutlook, when a code was given. This is the first thing to read on a priced match.single: one billing entity. Quote the rate.resolvedorlikely: a leading entity with its evidence. Lead with it, mention the alternatives.partitioned: the price depends on which organization bills, and the data cannot tell. Relay the outlook’saskin plain words. What settles it is whose name is on the claim: the billing provider, NPI, or Tax ID on a past EOB or itemized bill from this practice (the insurer’s app shows past claims). Booking location, app, or brand alone do not decide it, except where the brand’s own disclosure is office-scoped and the ask says which office. Walk the branch the person’s answer selects. Never quote one number while partitioned.- A
warningis binding. A brand-name match does not establish who bills. Brand clinics in partner markets can bill through an affiliated health system at several times the rate. Present both ends and the ask.
billingCandidates: one entry per legal entity that could bill, cheapest first, each withbillingOrg,tin, the rate or range, andevidencetags. Candidates are the entities on this provider’s own rows in the insurer’s files, plus entities linked by CMS enrollment, the insurer’s directory, the brand’s own disclosure, or observed claims; sharing a network roster group with another practice is never a link.observedmeans real claims were seen under that entity (withnandlast), the only tag that settles the question;payer_credentialedmeans the insurer’s own directory lists the provider under it (directories lag, so it nominates but does not settle);brand_disclosedmeans the brand itself says billing runs through that entity. If the person has a past bill or EOB, its Tax ID identifies the right entry.billingCandidatesOmittedmeans more entities exist than were listed.billingNoteis present when there are several; never quote one number without resolving the entity.attributionNotemarks a provider whose index entry predates this attribution; its evidence-less extra candidates are noise. 4a.facilityType,subpart,parentOrganization: what kind of entity each match is. Dozens of NPIs can share one legal name (the hospital, its FQHC subpart, student health, a clinic pharmacy) at very different rates. When the name is shared, say which kind the quoted entity is, and relayidentityNotewhen present.mailingStatemarks a billing-office record rather than a clinic.deactivatedmeans the NPI is no longer active; do not send anyone there.distanceKm(when a location was given) says how far each match is; far same-name organizations stay in the list for breadth, so check it before calling a match local. 4b.organizations(top level) groups same-system matches into a tree: the parent organization, how many billing entities matched, how many are in the plan, and each entity’s kind and rate. Entities are listed nearest first when a location was given, withdistanceKmon each andnearestKmon the system; a system’s far-away sites (another city’s hospital under the same parent) are in the tree for breadth, not as the answer to a local question, so filter by distance or city before presenting. Present the system first, then the entity the person means. Never pick the cheapest same-name entity as the answer.matchNote: this match was found by searching the name inside the plan’s own files after the normal matches were all outside the plan. Often it is the health system’s main billing entity at another address. Verify identity before relying on it.networkEvidence: how many of the plan’s networks back the in-network claim. One or two is thin; ten or more is broad participation.plan.sponsor: the matched plan’s identity, which may include HMO or PPO. Say which plan the answer is about.
Original Medicare
Medicare is two different products. Original Medicare (Parts A and B, the red, white and blue card, often paired with a Medigap supplement) is supported. Medicare Advantage (Part C: a private insurer’s Medicare plan from UnitedHealthcare, Humana, Aetna, Anthem, Kaiser and others, usually an HMO or PPO) is not: its rates are not published and its copays and networks are plan-specific. Pass the person’s own words aspayerName. “Original Medicare”, “Medicare Part B”, or a supplement name (“AARP Medicare Supplement”, “Medigap Plan G”) price directly. “Medicare Advantage”, or an insurer’s name next to Medicare, returns plan.payer = null with the reason. A bare “Medicare” is priced as Original Medicare with a medicare_type ask and medicare.assumed = true; over half of people on Medicare are on Advantage plans, so ask which card they show at the doctor before the numbers stand.
What is different in an Original Medicare response:
plan.matchTierismedicare_schedule.rateis Medicare’s approved amount for the provider’s locality (medicareAnchor.sourceisschedule), or what Medicare actually paid this provider when public data has it (observed). There is norateRangeand notypicalRate.medicare(top level): the year’s Part B deductible, the coinsurance percentage, the limiting charge, whether a Medigap supplement was mentioned, and a note. Relay the note once per conversation.patientShareon each provider:afterDeductible(the 20% coinsurance),beforeDeductibleMet(the most they owe while the deductible is unmet),limitingChargeMax(only for providers who do not accept assignment), and a note. It is 0 on screening benefits (Annual Wellness Visit, screening mammogram, screening colonoscopy, bone density) and on clinical lab tests. Say “Medicare’s approved amount is Y once your deductible is met.”medicareStatusandstatusNoteon each provider or match.basissays where the network answer came from:cms_enrollmentwithassignment: participatingmeans the approved amount is payment in full;non_participatingmeans they may bill up to 15% more and may ask for payment up front, andlimitingChargeMaxis the most they can charge;observed_billingmeans they bill Medicare but assignment is not recorded, so ask the office;opt_outmeans Medicare pays nothing there andinNetworkis false;no_recordis not a verdict. RelaystatusNoteas written.searchresults are ordered by evidence tier and then distance, not price. The approved amount is the same for every provider in a locality, so the nearest enrolled provider costs the same as one farther away. Say so.- Imaging, heart tests, and procedures show the physician-office amount. When the test is done in a hospital outpatient department, Medicare pays the hospital under a separate schedule that is not included, and the
notesays so. Ask where the test will be done. service.medicareNoteappears on codes Medicare does not pay under that code and names what to use instead. The common case: Medicare does not cover a routine annual physical (99387, 99397). It covers an Annual Wellness Visit at no cost,G0438the first time andG0439every year after. Switch to that code.- Employer, plan name, and group number do nothing for Original Medicare. Do not ask for them.
search?code=73721&zip=94607&payerName=Medicare. medicare.assumed is true and a medicare_type ask is present. Say: “Assuming Original Medicare rather than a Medicare Advantage plan: Medicare’s approved amount for a knee MRI at an imaging center in Oakland is about Y (20%) once your Z if it is not. If the MRI is done at a hospital, the hospital bills a separate facility charge. Is your Medicare the red, white and blue card, or a plan through an insurer like UnitedHealthcare or Humana?”
“Does Dr. Lee in Fresno take Medicare?”
Call network-status?providerName=Lee&zip=93701&payerName=Original%20Medicare&code=99213. For each match read medicareStatus. Participating: “Dr. Lee is enrolled in Medicare and accepts assignment, so Medicare’s approved amount (Y) after your deductible.” Non-participating: “enrolled, but may charge up to 15% more than the approved amount and may ask you to pay up front.” Opted out: “Dr. Lee has opted out of Medicare; Medicare pays nothing and you would sign a private contract.” No record: “I could not find a Medicare enrollment record for this NPI; that is not a no. Call the office or check medicare.gov/care-compare.”
Reading provider evidence
Eachsignal carries a display sentence stating how the number was derived. Relay it as written or summarize without changing the meaning. A volume signal gives a floor (“at least N per year”) and a national percentile only when it is high. outcome_context with level: facility describes the facility, never the individual clinician. absence and optout explain missing data; absence is never negative evidence (pediatric, commercial-only, and newer practices legitimately lack Medicare data). An exclusion signal is a federal exclusion-list notice; relay it plainly.
medicareAnchors are what Medicare actually paid this provider per service, with source: observed (this provider’s own history) or source: schedule (the area’s fee-schedule rate). They are reference points, not the person’s price and not a claim about fairness.
There is no composite score. Never rank providers, call anyone the best, or manufacture an overall rating. Evidence never re-orders price results.
Worked examples
“How much is a knee MRI near me? I have Blue Shield of California.” Confirm with or without contrast (most knee MRIs are without: code 73721). Ask the ZIP. Callsearch?code=73721&zip=94607&payerName=Blue%20Shield%20of%20California. The response is payer_fallback with ranges and an employer_or_plan ask. Present the three cheapest places by name and address with their ranges and typicalRate, mention rateFetchNote if present, relay the disclaimer, then ask: “If you tell me the employer your plan is through, I can give you the exact rate.”
“Is One Medical in-network for me? I’m on Anthem in San Francisco, just a regular check-in visit.”
Established patient, routine: code 99213. Call network-status?providerName=One%20Medical&zip=94107&code=99213&payerName=Anthem. Matches show inNetwork: true and several billingCandidates under different Tax IDs with a partitioned or likely outlook. Do not quote one number. Say: “One Medical is in-network on Anthem. Depending on which entity bills the visit, the contract rate is between B. Their site says which health system operates the office; if you have a past One Medical bill, the Tax ID on it tells me exactly.” Then re-call with the billing NPI if they have one.
“Should I go to Dr. Graham for a colonoscopy?”
Get the NPI: network-status?providerName=Geoffrey%20Graham&zip=... (or from the person’s referral). Then provider-evidence?npi=1003041625&code=45378. Relay the volume signal’s display sentence as written and the Medicare anchor as a reference point. Do not call him the best or compare him to others. For the price, use network-status with the code and the person’s plan.
Errors and limits
Anonymous calls are limited per IP per minute:search 60, network-status 20, provider-evidence 60. A few requests are served at a time per caller; beyond that you get 429 BUSY. Both 429 shapes carry Retry-After in seconds. 503 PRICING_PUBLIC_DISABLED means anonymous pricing is paused. In all three cases tell the person the lookup is temporarily unavailable and do not invent prices.
400 INVALID_JSON for a malformed body. 404 NOT_FOUND for an unknown path, with a link back to this guide. 500 with PRICING_SEARCH_FAILED, PRICING_NETWORK_STATUS_FAILED, or PROVIDER_EVIDENCE_FAILED for a server failure; retry once, then tell the person.
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").
Calls with an Arlo account token can also use the person’s linked insurance records instead of payerName, and price for a family member with patientId. Everything else in this guide applies unchanged.
Rules
- Relay
disclaimerevery time. - Named clinic, brand, or doctor:
network-statusfirst.searchis for “around here.” - Verify
service.appliesTofits the person before you quote. Switch to arelatedCodessibling when it fits better. - Relay
priceNote,note, andrateAssessmentwhenever present. inNetwork: falsemeans “not found in the published files,” never “out of network.”- Never quote a single number while
billingOutlook.modeispartitioned, a row hasmultiEntity: true, orbillingCandidateshas more than one entry. - Never rank providers or call anyone the best. Relay evidence
displaysentences as written. Absence is not negative. - Say what the estimate is based on (
plan.basis) and which plan (plan.sponsor). - Negotiated rate is not out-of-pocket cost. Say so. On Original Medicare, quote the approved amount and
patientSharetogether. - Never price a Medicare Advantage plan as Original Medicare. When
medicare.assumedis true, ask which kind before the numbers stand.
Terms
Use is subject to https://arlohealth.ai/tos. Responses are derived from public regulatory data and contain no patient information. Do not present estimates as guarantees or rank providers on price alone. Providers can review the methodology and request corrections through the link inmethodology.