Wellward

← Guides

Request a price we don't have

Try it on a test key

curl -s -X POST "https://api.wellwardhealth.com/v1/price-requests" \
  -H "Authorization: Bearer $WELLWARD_KEY" -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"service":"colonoscopy","zip":"00030"}'

When coverage is none (or thin partial), ask us to gather a price: POST /v1/price-requests with a service (or a free-text query) and a location (zip, or lat/lng). We contact providers; it is not instant.

Keep the id it returns. To tie the result back to your own records, put your reference in metadata (up to 1 KB) — we store it, never read it, and return it on every read and webhook.

Name the providers to call first

If you know which providers you want priced, list them. We call them first, then nearby providers as usual:

{
  "service": "mri-knee",
  "zip": "75201",
  "providers": [
    { "npi": "<10-digit NPI>", "facility_name": "North Dallas Imaging" },
    { "npi": "<10-digit NPI>", "facility_name": "Baylor Scott & White – Plano" }
  ]
}
  • Up to 25 providers, each an npi and the facility_name where they practise (the place we call). An individual clinician's NPI is fine.
  • A location is still required: it is where we look for nearby providers. "Nearby" means within your radius_miles by road, not in a straight line, so a provider across a lake or bay that's close on the map but a long drive away doesn't count. Providers you list count at any distance, and so does any provider we called for your request: where few providers are near, we sometimes look a little further, and a price from one of those calls is still sent.
  • A listed provider far from the location is still called.
  • An NPI with a bad check digit, or one listed twice, is 400 and nothing is saved.

When the request completes, each entry in providers carries its own result:

FieldMeans
resultprice_obtained or no_price_obtained for that provider
price_idsthe request's prices that came from that provider
practice_idthe practice its prices are published under — the same id you see on /v1/prices and /v1/providers/{id}
viaset when the provider's price is the price of the group that bills at the facility where they work — { facility: { id, name }, group: { id, name } }. Otherwise null.

Anesthesia. An anesthesiologist rarely quotes their own price: the anesthesia group that covers their facility does. When you list an anesthesiologist, we find the facility they work at, the group that does the anesthesia there, and that group's price. The provider's entry then carries that price, with via naming the facility and the group (for example Stony Point Surgery Center and NorthStar Anesthesia), and practice_id is the group's. The price itself names the same facility in facility.

The request's own price_ids holds every price, including those from nearby providers; a price that appears under no listed provider came from nearby. The request is billed once when it obtains any price, however many providers you listed. An add-on on its own doesn't count as a price.

The service we gather

Send service (a slug from /v1/services) when you know it — that is exactly what we gather. If you send query instead, service is null at first. Our team matches your words to a catalog service before any calls are made, and service shows it from then on. It can change while the request is queued; it does not change once gathering has started.

A procedure that isn't in /v1/services? Ask for it anyway: describe it in query — CPT codes welcome — and leave service out (blank or null is fine too). Our team adds it to the catalog and gathers the price; from then on it's a catalog service anyone can request.

{ "query": "CPT 63030 lumbar laminotomy/discectomy, single level", "zip": "75201" }

Send service or query, or both; a blank or null value counts as not sent, and a request with neither is 400.

When you hear back

expected_by is the next business day, or the one after for imaging, surgery and endoscopy — and for a request we couldn't match to a catalog service, since our team adds the service first. Every request stands on its own, with its own date. Follow it with the request.completed webhook (recommended), or poll GET /v1/price-requests/{id}. There is no per-request callback URL. To list your requests, GET /v1/price-requests?state=completed.

stateMeans
queuedreceived, not started — you can still cancel
in_progresswe are contacting providers
completeddone; outcome is price_obtained (with price_ids) or no_price_obtained
expiredwe could not finish in time
cancelledyou cancelled it

Component prices

Some providers can only quote part of a service. For example, a surgeon's office knows the surgeon's fee, but the facility and anesthesia bill separately. When you named that surgeon, their fee is often exactly what you asked for, so we deliver it as a component price: coverage.all_in is false, and coverage.excludes names what isn't in it (e.g. ["facility", "anesthesia"]). A component price is in the request's price_ids and fetchable with GET /v1/prices/{id}. It never appears in search, sorting or benchmarks, where a surgeon's fee would look like the cheapest procedure. An add-on on its own (a biopsy, a lens upgrade) is never delivered as a price. When the provider stated what each part costs, coverage.components carries those amounts (component amounts), and each stated part is also a component price of its own: an MRI quoted as "$490: scan $380, read $110" gives the $490 price plus a $380 scan price and a $110 read price.

What is billed

A request is billed only when outcome is price_obtained — it produced at least one price while it was open. An all-in price and a component price both count. A price counts when it is for that service and either:

  • at a provider you listed — including a price we already held for them, whenever it was quoted (within max_age_days if you sent it). We don't re-call a provider we already have a recent price for; that price is your answer; or
  • near your location and quoted on or after the day you asked — gathered for your request.

It is not billed if we obtain no quote, or if the only quote is outside the reasonable band of prices for that service in that market or comparable markets. A request is billed once, however many prices it carries. The price then becomes available to everyone (a component price by its id only), and later Reads of it are billed as Reads. Rates: the pricing page.

Refusals

  • 409 coverage_exists — we already have full coverage there. Send max_age_days (at least 30) if you need fresher quotes.
  • 422 unsupported_service — a service we cannot gather.
  • 402 payment_required — a live key on card billing with no card; 402 spend_cap_reached — your spending cap is reached.

Idempotency

Idempotency-Key is required. Send a fresh value per request; for 24 hours, a retry with the same key and body returns the original response — the request as it was when created — instead of creating a second request (for its current state, GET /v1/price-requests/{id}) (the same key with a different body is 409 idempotency_conflict).

In test mode

A test key's request never reaches our team: 30 seconds after creation it plays out its test_scenario (default complete_with_price, for the twelve test services) — see Test mode.

API reference · Dashboard · Questions: hello@wellwardhealth.com