Fee Schedule Search
Status:
stableCategory:lookupAdded:2026-10-14Last reviewed:2026-10-14
Summary
Returns a priced rate-sheet slice: every code matching q, priced for
one workers' compensation jurisdiction, place of service, setting, date
and provider type, in one call. Pass a code prefix (9921) for a range
of codes, or descriptor words (office visit) for a topic. Each result
carries the code, its label, its status and its max_allowable_usd;
the location, version and citation are given once, because every row
shares them.
Like /api/lookup/fee_schedule/get,
every amount is a reference maximum, not a pricing or payment
determination: a per-unit, single-line cap before multi-line
reductions and before the lesser-of-billed-charge rule, as
amount_basis states. Coverage is the same as for get; see
/api/lookup/fee_schedule/tree for
the live list.
Endpoint
| Field | Value |
|---|---|
| Method | GET |
| Path | /api/lookup/fee_schedule/search |
| Full URL | https://engine.tripod-health.com/api/lookup/fee_schedule/search |
| Authentication | API key (required) |
| Request body | none |
| Response body | application/json |
| Idempotent | Yes |
| Rate-limited | Yes |
Authentication
Send a valid API key in the apikey header. See
authentication.md.
Request
Headers
| Header | Required | Description |
|---|---|---|
apikey | Yes | Consumer API key. |
The engine assigns its own request id to every request and returns it
in the response body's request_id. An X-Request-ID sent by the caller
is ignored. The X-Request-ID response header is the gateway's trace ID
for the same request and does not match request_id.
Path parameters
None.
Query parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
jurisdiction | string | Yes | — | A USPS state code, DC, medicare, or owcp. Case-insensitive. An unrecognized value is a 400. |
q | string | Yes | — | Search text, minimum two characters. A code-shaped value (two to five letters and digits including at least one digit, such as 9921, G22, WC0) is a code prefix and reaches every code the jurisdiction's schedule prices. Anything else is matched word by word against the descriptors the engine holds — its curated CPT codebook and state-defined codes — so other codes are found by prefix only. |
setting | string | Yes | — | facility or non_facility. |
zip | string | One of zip / locality | — | The place of service — where the provider performed the service, not the patient's address. 5 digits, or the 9-digit ZIP+4 where a ZIP spans more than one locality. |
locality | string | One of zip / locality | — | A locality or region key from tree, such as TX:18. Sending both zip and locality is a 400. |
provider_type | string | No | physician | Same values as get. Applied to every row. |
as_of | string | No | today (UTC) | The date of service whose schedule applies, YYYY-MM-DD. |
limit | int | No | 10 | Maximum results to return. Range 1–50. |
Search prices each code without modifiers and for one unit. For a line with modifiers or units, call get.
A location is required when the jurisdiction is covered. For a
no_fee_schedule or not_covered_by_engine jurisdiction, results
is empty and notes says why.
Body
None.
Response
Success — 200 OK
Request: GET /api/lookup/fee_schedule/search?jurisdiction=TX&q=9921&locality=TX:18&setting=non_facility
{
"jurisdiction": "TX",
"amount_basis": "per_unit_single_line_before_multi_line_reductions_and_before_lesser_of_billed_charge",
"setting": "non_facility",
"provider_type": {
"requested": "physician"
},
"location": {
"locality": "TX:18",
"name": "HOUSTON",
"resolved_from": "locality",
"basis": "place_of_service"
},
"version": {
"label": "TX 2026",
"effective_from": "2026-01-01",
"effective_to": "2026-12-31"
},
"citation": "28 TAC 134.203; TDI-DWC 2026 conversion factors ($72.07, $90.48); 28 TAC 134.2, 134.220, 134.230, 134.235-134.260, 129.5",
"as_of": "2026-10-14",
"results": [
{
"code": "99211",
"label": "Office or other outpatient visit for the evaluation and management of an established patient that may not require the presence of a physician or other qualified health care professional",
"status": "priced",
"max_allowable_usd": 52.71,
"method": "state_cf_rbrvs"
},
{
"code": "99212",
"label": "Office or other outpatient visit for the evaluation and management of an established patient, which requires a medically appropriate history and/or examination and straightforward medical decision making. When using total time on the date of the encounter for code selection, 10 minutes must be met or exceeded",
"status": "priced",
"max_allowable_usd": 129.81,
"method": "state_cf_rbrvs"
},
{
"code": "99213",
"label": "Office or other outpatient visit for the evaluation and management of an established patient, which requires a medically appropriate history and/or examination and low level of medical decision making. When using total time on the date of the encounter for code selection, 20 minutes must be met or exceeded",
"status": "priced",
"max_allowable_usd": 207.85,
"method": "state_cf_rbrvs"
},
{
"code": "99214",
"label": "Office or other outpatient visit for the evaluation and management of an established patient, which requires a medically appropriate history and/or examination and moderate level of medical decision making. When using total time on the date of the encounter for code selection, 30 minutes must be met or exceeded",
"status": "priced",
"max_allowable_usd": 296.49,
"method": "state_cf_rbrvs"
},
{
"code": "99215",
"label": "Office or other outpatient visit for the evaluation and management of an established patient, which requires a medically appropriate history and/or examination and high level of medical decision making. When using total time on the date of the encounter for code selection, 40 minutes must be met or exceeded",
"status": "priced",
"max_allowable_usd": 421.04,
"method": "state_cf_rbrvs"
}
],
"notes": [
{
"code": "least_of",
"text": "Texas pays the least of this maximum, the provider's usual and customary charge, or a fair and reasonable amount, unless a network contract applies (28 TAC 134.203(h))."
},
{
"code": "medicare_payment_policies",
"text": "Medicare payment policies apply on top of this per-line maximum, including the multiple procedure reductions that depend on other lines of the bill (28 TAC 134.203(b)(1))."
},
{
"code": "surgery_cf_reading",
"text": "The facility surgery conversion factor is applied to the CPT Surgery section (10004-69990); 28 TAC 134.203 names Surgery without listing codes."
}
],
"request_id": "3f4825ce-128e-454e-bfc1-c2039829a893",
"timestamp": "2026-10-14T00:34:54.228Z"
}
results is always present. An empty array is a normal response: the
query matched nothing, or the jurisdiction has no schedule the engine
covers on as_of (the reason is in notes).
Response fields
| Field | Type | Always present | Description |
|---|---|---|---|
jurisdiction | string | Yes | The normalized jurisdiction. |
amount_basis | string | Yes | Always per_unit_single_line_before_multi_line_reductions_and_before_lesser_of_billed_charge. Applies to every row. |
setting | string | Yes | Echoes setting. |
provider_type.requested | string | Yes | Echoes provider_type, or physician when omitted. |
location | object | null | Yes | { locality, name, resolved_from, basis }, as in get. null when the jurisdiction is not covered or has no schedule. |
version | object | null | Yes | The version in force on as_of: { label, effective_from, effective_to }, as in get. null when not covered, including a date after the newest version's effective_to. |
citation | string | null | Yes | The legal citation for the version. |
as_of | string | Yes | The date whose schedule was applied, YYYY-MM-DD. |
results | array | Yes | Zero or more matching codes. Code-prefix results run in code order; text results in relevance order. |
results[].code | string | Yes | The code. |
results[].label | string | null | Yes | The code's descriptor or the state's own name for it. null when none is held. |
results[].status | string | Yes | The shared status enum, as in get. |
results[].max_allowable_usd | number | null | Yes | Per-unit maximum for one line, no modifiers. null unless status is priced. |
results[].method | string | null | Yes | How the amount was produced, as in get. |
notes | array | Yes | The jurisdiction's notes, which apply to every row, as { code, text }. A text search adds text_search_coverage, stating which descriptors text matching covers. |
request_id | string | Yes | Correlation ID. Quote in support tickets. |
timestamp | string (ISO 8601 UTC) | Yes | Server time when the response was emitted. |
Status codes
| Code | Meaning | When |
|---|---|---|
200 | OK | Search ran. results may be empty. |
400 | ValidationError | A required parameter is missing; jurisdiction is unrecognized; q is shorter than two characters; limit, setting, provider_type or as_of is invalid; both zip and locality were sent, or neither for a covered jurisdiction; the ZIP spans localities without its +4; the ZIP or locality is not in the jurisdiction's map; or a parameter was repeated. field names the offender. |
401 | Unauthenticated | Missing or invalid API key. |
429 | RateLimited | Per-consumer rate limit exceeded. |
500 | InternalError | Unexpected failure. Quote request_id in the ticket. |
Examples
curl
curl -sS "https://engine.tripod-health.com/api/lookup/fee_schedule/search?jurisdiction=TX&q=9921&locality=TX:18&setting=non_facility" \
-H "apikey: $ENGINE_API_KEY"
Text search
curl -sS "https://engine.tripod-health.com/api/lookup/fee_schedule/search?jurisdiction=CA&q=office%20visit&zip=90071&setting=facility&limit=3" \
-H "apikey: $ENGINE_API_KEY"
{
"jurisdiction": "CA",
"amount_basis": "per_unit_single_line_before_multi_line_reductions_and_before_lesser_of_billed_charge",
"setting": "facility",
"provider_type": {
"requested": "physician"
},
"location": {
"locality": "CA:18",
"name": "LOS ANGELES-LONG BEACH-ANAHEIM (LOS ANGELES/ORANGE CNTY)",
"resolved_from": "zip",
"basis": "place_of_service"
},
"version": {
"label": "CA 2026-10-01",
"effective_from": "2026-10-01",
"effective_to": "2026-12-31"
},
"citation": "8 CCR 9789.12.2, 9789.19(m); DWC Administrative Director Order of 9/29/2026, services on or after 10/1/2026, adopting RVU26D",
"as_of": "2026-10-14",
"results": [
{
"code": "99211",
"label": "Office or other outpatient visit for the evaluation and management of an established patient that may not require the presence of a physician or other qualified health care professional",
"status": "priced",
"max_allowable_usd": 12.46,
"method": "state_cf_rbrvs"
},
{
"code": "99202",
"label": "Office or other outpatient visit for the evaluation and management of a new patient, which requires a medically appropriate history and/or examination and straightforward medical decision making. When using total time on the date of the encounter for code selection, 15 minutes must be met or exceeded",
"status": "priced",
"max_allowable_usd": 66.41,
"method": "state_cf_rbrvs"
},
{
"code": "99212",
"label": "Office or other outpatient visit for the evaluation and management of an established patient, which requires a medically appropriate history and/or examination and straightforward medical decision making. When using total time on the date of the encounter for code selection, 10 minutes must be met or exceeded",
"status": "priced",
"max_allowable_usd": 50.04,
"method": "state_cf_rbrvs"
}
],
"notes": [
{
"code": "lesser_of_actual_charge",
"text": "California pays the lesser of the actual charge or this maximum (8 CCR 9789.12.2(f))."
},
{
"code": "hpsa_bonus",
"text": "A 10% bonus applies in a Health Professional Shortage Area (8 CCR 9789.12.6). Send modifier AQ to apply it; the engine does not apply it from the ZIP alone."
},
{
"code": "text_search_coverage",
"text": "Text matches descriptors the engine holds: its curated CPT codebook and state-defined codes. Any other code is found by code prefix."
}
],
"request_id": "13f65649-9512-40ad-818e-0775d4c30a0c",
"timestamp": "2026-10-14T00:34:54.881Z"
}
A jurisdiction with no schedule
curl -sS "https://engine.tripod-health.com/api/lookup/fee_schedule/search?jurisdiction=IN&q=9921&setting=non_facility" \
-H "apikey: $ENGINE_API_KEY"
{
"jurisdiction": "IN",
"amount_basis": "per_unit_single_line_before_multi_line_reductions_and_before_lesser_of_billed_charge",
"setting": "non_facility",
"provider_type": {
"requested": "physician"
},
"location": null,
"version": {
"label": "IN no fee schedule",
"effective_from": "2026-01-01",
"effective_to": null
},
"citation": "WCRI, Designing Workers' Compensation Medical Fee Schedules, 2025",
"as_of": "2026-10-14",
"results": [],
"notes": [
{
"code": "no_professional_schedule",
"text": "Indiana has no professional fee schedule. It caps facility payments only, at 200% of Medicare."
}
],
"request_id": "36248166-0b44-42b2-b5af-418f0823a4d0",
"timestamp": "2026-10-14T00:34:55.156Z"
}
Python (requests)
# Uses the call() helper from quickstart.md.
from urllib.parse import urlencode
params = {"jurisdiction": "TX", "q": "9921", "locality": "TX:18", "setting": "non_facility"}
sheet = call("GET", f"/api/lookup/fee_schedule/search?{urlencode(params)}")
print(sheet["version"]["label"], sheet["location"]["name"])
for row in sheet["results"]:
amount = f"${row['max_allowable_usd']:.2f}" if row["status"] == "priced" else row["status"]
print(f"{row['code']} {amount}")
Node.js (native fetch)
// Uses the call() helper from quickstart.md.
const params = new URLSearchParams({
jurisdiction: "CA",
q: "office visit",
zip: "90071",
setting: "non_facility",
provider_type: "nurse_practitioner",
});
const sheet = await call("GET", `/api/lookup/fee_schedule/search?${params}`);
for (const row of sheet.results) {
console.log(row.code, row.status, row.max_allowable_usd);
}
TypeScript
type FeeStatus =
| "priced" | "no_published_cap" | "not_payable"
| "bundled" | "no_fee_schedule" | "not_covered_by_engine";
interface FeeScheduleSearchResponse {
jurisdiction: string;
amount_basis: string;
setting: "facility" | "non_facility";
provider_type: { requested: string };
location: {
locality: string;
name: string;
resolved_from: "zip" | "zip+4" | "locality";
basis: "place_of_service";
} | null;
version: { label: string; effective_from: string; effective_to: string | null } | null;
citation: string | null;
as_of: string;
results: {
code: string;
label: string | null;
status: FeeStatus;
max_allowable_usd: number | null;
method: string | null;
}[];
notes: { code: string; text: string; [detail: string]: unknown }[];
request_id: string;
timestamp: string;
}
const sheet = await call<FeeScheduleSearchResponse>(
"GET",
"/api/lookup/fee_schedule/search?jurisdiction=TX&q=9921&locality=TX:18&setting=non_facility",
);
Error scenarios
q too short
Send:
curl -sS "https://engine.tripod-health.com/api/lookup/fee_schedule/search?jurisdiction=TX&q=9&locality=TX:18&setting=non_facility" \
-H "apikey: $ENGINE_API_KEY" \
-w "\nHTTP %{http_code}\n"
Receive (400):
{
"timestamp": "2026-10-14T00:34:55.265Z",
"error": "ValidationError",
"message": "Query parameter 'q' must be at least 2 characters",
"field": "q",
"request_id": "69af4bb2-f48b-4d7f-b400-30320b332277"
}
Both zip and locality
Send:
curl -sS "https://engine.tripod-health.com/api/lookup/fee_schedule/search?jurisdiction=TX&q=9921&zip=77002&locality=TX:18&setting=non_facility" \
-H "apikey: $ENGINE_API_KEY" \
-w "\nHTTP %{http_code}\n"
Receive (400):
{
"timestamp": "2026-10-14T00:34:55.372Z",
"error": "ValidationError",
"message": "Send either 'zip' or 'locality', not both",
"field": "locality",
"request_id": "54d9262a-cdc7-43cf-b6b8-e45666fed5d5"
}
Intended use
- Rate sheets — "office visits in Houston today" in one call, for display or for checking a batch of billed codes against their caps.
- Code pickers with prices — a picker that shows the maximum next to each candidate code.
- Comparing settings or provider types — run the same search with
setting=facilityandsetting=non_facility, or with differentprovider_typevalues.
Mistaken use
- Do not use search for a line with modifiers or multiple units.
Search prices each code bare, for one unit. Use
/api/lookup/fee_schedule/get. - Do not read a missing code as "not payable". Text search covers only the descriptors the engine holds; search by code prefix, or call get for the exact code.
- Do not treat any row's amount as a payment. Every row is a
per-unit, single-line cap; the
notesname the rules the jurisdiction still applies. - Do not guess locality keys. Read them from
/api/lookup/fee_schedule/tree.
Debugging
- Capture
request_idfrom the response body (or, if the response has no body from the engine, theX-Request-IDresponse header). - Empty
resultswith a note such asnot_covered_by_engineorno_professional_schedule. The jurisdiction has no schedule the engine covers onas_of— for a covered jurisdiction,as_ofis before its first version or after its newest version'seffective_to. Check tree. - Empty
resultsfor a text query in a covered jurisdiction. The codes you want may have no descriptor the engine holds (see thetext_search_coveragenote). Search by code prefix instead. 400namingzip. As for get: a covered jurisdiction needs a location, and a ZIP spanning localities needs its +4.
Rate limits
See rate-limits.md for the current per-consumer limits.
Related
- lookup-fee_schedule-get.md — one service line, with modifiers, units and full components.
- lookup-fee_schedule-tree.md —
covered jurisdictions, version history, and valid
localitykeys. - lookup-cpt-search.md — search the CPT codebook without prices.
- authentication.md, errors.md, rate-limits.md, conventions.md — cross-cutting contract rules.
Change history
| Date | Change |
|---|---|
| 2026-10-14 | Initial publication. |
| 2026-10-14 | The X-Request-ID response header is the gateway's trace ID for the request and does not match request_id; quote request_id to support. |