Full Catalog Tree
Status:
stableCategory:catalogAdded:2026-04-20Last reviewed:2026-10-14
Summary
Returns the full catalog tree: every category, every resource, every operation, with version metadata and audience-aware display labels. Use this as the discovery entry point when bootstrapping a client — one call gives you everything the API advertises.
For slices of the same data, see /api/catalog/categories,
/api/catalog/resources, and
/api/catalog/operations. For single-entity
lookups see /api/catalog/category and
/api/catalog/resource.
Endpoint
| Field | Value |
|---|---|
| Method | GET |
| Path | /api/catalog/get |
| Full URL | https://engine.tripod-health.com/api/catalog/get |
| Authentication | API key (required) |
| Request body | none |
| Response body | application/json |
| Idempotent | Yes |
| Rate-limited | Yes |
Purpose
Two use cases drive this endpoint:
- Client bootstrap. A new integration reads the catalog once to learn what the API exposes. Resource names, operation paths, versions, and audience labels all live here.
- Cache warm-up. The catalog is stable for the lifetime of a
deploy; a client can cache the full response and invalidate when
versionorlast_updatedchanges. See the caching guidance below.
The response is static for a given deploy — it is loaded once at server startup and served from memory.
Authentication
Send a valid API key in the apikey header. See
authentication.md.
Request
Headers
| Header | Required | Description |
|---|---|---|
apikey | Yes | Consumer API key. |
Path parameters
None.
Query parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
audience | string | No | none | One of employee, employer, provider. When set, every entity's display_name is replaced with that audience's alias (falling back to the canonical display_name if the entity has no alias for that audience). When omitted, canonical display_name is returned for every entity. |
Body
None.
Response
Success — 200 OK
Abbreviated for readability: two of the ten categories (pain and
lookup), each trimmed to its first resource, and one of the 17
top-level resources (version). Every object shown is complete; the
live response includes every category, resource, and operation.
{
"version": "0.42.0",
"last_updated": "2026-10-13",
"categories": [
{
"name": "pain",
"display_name": "Pain",
"aliases": {
"employee": "Pain Level",
"employer": "Pain",
"provider": "Pain"
},
"description": "Subjective pain intensity and pain-oriented screening tools.",
"version": "0.1.0",
"last_updated": "2026-04-17",
"resources": [
{
"name": "orebro",
"display_name": "Orebro Musculoskeletal Pain Screening",
"aliases": {
"employee": "Pain Screening Questionnaire",
"employer": "Musculoskeletal Pain Screening",
"provider": "Orebro"
},
"description": "Orebro Musculoskeletal Pain Screening Questionnaire (OMPSQ): multi-item screening that returns a total score and a risk profile.",
"version": "1.1.0",
"last_updated": "2026-10-11",
"operations": [
{
"name": "score",
"display_name": "Score",
"aliases": {},
"description": "Submit responses to the instrument and receive its score (and profile, where the instrument supports classification).\n\nWith `?audience=`, an optional `assist_context` sets the persona and instructions for the audience-facing summary and per-item messages; on-demand references are not accepted. Both texts pass the outbound identifier scan.",
"version": "1.1.0",
"last_updated": "2026-10-11",
"http_method": "POST"
}
]
}
]
},
{
"name": "lookup",
"display_name": "Lookup",
"aliases": {
"employee": "Reference Lookup",
"employer": "Reference Data",
"provider": "Code & Reference Lookup"
},
"description": "Reference data a developer searches, fetches and navigates: industry injury rates, federal regulations, medical code sets and workers' comp fee schedules. Every resource offers `search` and `get` with `code` + `label` on each record, so one client component serves them all; code resources add `tree`. Served from the engine's own tables -- no request is passed to a third party.",
"version": "1.1.0",
"last_updated": "2026-10-13",
"resources": [
{
"name": "naics",
"display_name": "NAICS Industry Safety Reference",
"aliases": {
"employee": "Industry Injury Rates",
"employer": "Industry Safety Benchmarks",
"provider": "NAICS Industry Reference"
},
"description": "BLS recordable-injury and illness incidence rates by NAICS code, plus an OSHA-300 calculator that compares an employer's reported case counts against the national rate for their industry.",
"version": "1.0.0",
"last_updated": "2026-10-13",
"operations": [
{
"name": "search",
"display_name": "Search",
"aliases": {},
"description": "Type-ahead search by industry name or numeric NAICS prefix. Returns up to N matches ranked by code length, then code. Each hit carries `code` (the NAICS code) and `label` (the industry name).",
"version": "1.0.0",
"last_updated": "2026-10-13",
"http_method": "GET"
},
{
"name": "get",
"display_name": "Get",
"aliases": {},
"description": "Return one industry's full benchmark row by `?code=<naics>`, with the same `code` + `label` a search hit carries. Optional `?ownership=` selects the BLS ownership cohort. Responds 404 if the (code, ownership) pair is unregistered.",
"version": "1.0.0",
"last_updated": "2026-10-13",
"http_method": "GET"
},
{
"name": "calculate",
"display_name": "Calculate",
"aliases": {},
"description": "Compute employer recordable-injury incidence rates from OSHA-300 case counts and exposure hours, and compare them against the looked-up benchmark when `naics_code` is supplied; the echoed `benchmark` carries `code` + `label`. Permissive on input -- partial bodies surface as warnings, not request failures.",
"version": "1.0.0",
"last_updated": "2026-10-13",
"http_method": "POST"
}
]
}
]
}
],
"top_level_resources": [
{
"name": "version",
"display_name": "Version Info",
"aliases": {
"employee": "Version",
"employer": "API Version",
"provider": "Version"
},
"description": "Build metadata for the deployed engine: package version, catalog version, source-control SHA, and deploy timestamp.",
"version": "0.1.0",
"last_updated": "2026-04-20",
"operations": [
{
"name": "get",
"display_name": "Get",
"aliases": {},
"description": "Return the engine's current build metadata as JSON. No request body.",
"version": "0.1.0",
"last_updated": "2026-04-20",
"http_method": "GET"
}
]
}
]
}
Response fields
| Field | Type | Always present | Description |
|---|---|---|---|
version | string (SemVer) | Yes | Catalog version. Matches the catalog_version echoed on scoring responses. |
last_updated | string (ISO date, YYYY-MM-DD) | Yes | Day the catalog was last structurally changed. |
categories | array | Yes | Every registered category, each containing its resources and their operations. |
top_level_resources | array | Yes | Resources that live outside any category (for example cdri, recordability, health, catalog). Same shape as the entries inside categories[i].resources. |
Each category object:
| Field | Type | Always present | Description |
|---|---|---|---|
name | string | Yes | URL-safe identifier used in paths. |
display_name | string | Yes | Canonical display label — or the audience alias when ?audience= was set. |
aliases | object | Yes | Map from audience name to alias string. May be {} if no aliases are registered. |
description | string | Yes | One-sentence description of the category's domain. |
version | string (SemVer) | Yes | Category-level version (independent of the root version). |
last_updated | string (ISO date) | Yes | Last structural change to this category. |
resources | array | Yes | Resources inside this category. |
Each resource object uses the same shape (name, display_name,
aliases, description, version, last_updated) plus an
operations array. Each operation adds http_method ("GET" or
"POST") and has no resources array.
Status codes
| Code | Meaning | When |
|---|---|---|
200 | OK | Catalog returned. |
400 | ValidationError | audience was provided but not one of the allowed values. field: "audience". |
401 | Unauthenticated | Missing or invalid API key. |
429 | RateLimited | Per-consumer rate limit exceeded. |
Examples
The language-specific invocations below assume the call() helper (or
its equivalent) from quickstart.md.
Responses from this endpoint are ~75 KB today; the language snippets focus on iteration and discovery rather than re-pasting the full tree.
1. Canonical request and response
Send:
GET /api/catalog/get HTTP/1.1
Host: engine.tripod-health.com
apikey: $ENGINE_API_KEY
See the Success — 200 OK section above for the
full abbreviated response. The live catalog today (version 0.42.0)
carries ten categories and 17 top-level resources, 73 operations in
all. The categories are the seven instrument categories (14 scored
instruments), encounters, grading, and lookup (naics,
regulations, icd10cm, cpt, fee_schedule).
2. Calling the endpoint in your language
curl — canonical and audience variants
# Canonical display names
curl -sS "https://engine.tripod-health.com/api/catalog/get" \
-H "apikey: $ENGINE_API_KEY"
# Employee-facing labels
curl -sS "https://engine.tripod-health.com/api/catalog/get?audience=employee" \
-H "apikey: $ENGINE_API_KEY"
With ?audience=employee, canonical "Pain" becomes "Pain Level",
"Orebro Musculoskeletal Pain Screening" becomes "Pain Screening Questionnaire", and so on. The aliases map is unchanged; clients
that render multiple labels can pick from it themselves.
Python (requests)
# Uses the call() helper from quickstart.md.
catalog = call("GET", "/api/catalog/get")
print(f"catalog version {catalog['version']} last updated {catalog['last_updated']}")
for cat in catalog["categories"]:
for res in cat["resources"]:
print(f" /api/{cat['name']}/{res['name']} ({res['display_name']})")
Node.js (native fetch)
// Uses the call() helper from quickstart.md.
const catalog = await call("GET", "/api/catalog/get");
console.log(`catalog ${catalog.version} (${catalog.last_updated})`);
for (const cat of catalog.categories) {
for (const res of cat.resources) {
console.log(` /api/${cat.name}/${res.name} (${res.display_name})`);
}
}
TypeScript
// Uses the typed call<T>() helper from quickstart.md.
interface CatalogOperation {
name: string;
display_name: string;
aliases: Record<string, string>;
description: string;
version: string;
last_updated: string;
http_method: "GET" | "POST";
}
interface CatalogResource {
name: string;
display_name: string;
aliases: Record<string, string>;
description: string;
version: string;
last_updated: string;
operations: CatalogOperation[];
}
interface CatalogCategory extends Omit<CatalogResource, "operations"> {
resources: CatalogResource[];
}
interface Catalog {
version: string;
last_updated: string;
categories: CatalogCategory[];
top_level_resources: CatalogResource[];
}
const catalog = await call<Catalog>("GET", "/api/catalog/get?audience=provider");
Go
// Uses the call() helper from quickstart.md.
catalog, err := call("GET", "/api/catalog/get", nil, 3)
if err != nil {
panic(err)
}
categories := catalog["categories"].([]any)
for _, c := range categories {
cat := c.(map[string]any)
resources := cat["resources"].([]any)
for _, r := range resources {
res := r.(map[string]any)
fmt.Printf(" /api/%v/%v (%v)\n", cat["name"], res["name"], res["display_name"])
}
}
Java
// Uses the call() helper from quickstart.md.
// For real catalog traversal, deserialize into POJOs with Jackson or Gson
// rather than walking the JSON string by hand.
String catalog = call("GET", "/api/catalog/get", null, 3);
String catalogVersion = extract(catalog, "version");
System.out.println("catalog version: " + catalogVersion);
C# (.NET HttpClient)
// Uses the Call() helper from quickstart.md.
var catalog = await Call(HttpMethod.Get, "/api/catalog/get");
Console.WriteLine($"catalog {catalog.GetProperty("version").GetString()}");
foreach (var cat in catalog.GetProperty("categories").EnumerateArray())
{
var catName = cat.GetProperty("name").GetString();
foreach (var res in cat.GetProperty("resources").EnumerateArray())
{
var resName = res.GetProperty("name").GetString();
var display = res.GetProperty("display_name").GetString();
Console.WriteLine($" /api/{catName}/{resName} ({display})");
}
}
PowerShell
# Uses the Invoke-Engine helper from quickstart.md.
$catalog = Invoke-Engine -Method Get -Path "/api/catalog/get"
"catalog $($catalog.version) ($($catalog.last_updated))"
foreach ($cat in $catalog.categories) {
foreach ($res in $cat.resources) {
" /api/$($cat.name)/$($res.name) ($($res.display_name))"
}
}
3. Error scenarios
Invalid audience
Send:
curl -sS "https://engine.tripod-health.com/api/catalog/get?audience=bogus" \
-H "apikey: $ENGINE_API_KEY" \
-w "\nHTTP %{http_code}\n"
Receive (400):
{
"timestamp": "2026-10-14T00:25:30.321Z",
"error": "ValidationError",
"message": "Unknown audience 'bogus'. Valid values: employee, employer, provider.",
"field": "audience",
"request_id": "dfcb6659-2446-4e01-b387-1a496737c0ec"
}
Caching
The response is stable for the lifetime of a deploy. Invalidate only
when version or last_updated changes — polling /api/version/get
is a cheap way to detect a deploy boundary without re-reading the
whole catalog. Typical client strategy:
- On startup, fetch
/api/catalog/get(optionally with the audience your UI targets) and cache it. - Periodically (every few minutes, or on any
catalog_versionmismatch in a scoring response), call/api/version/get. - When
catalog_versiondiffers from the cachedversion, refetch/api/catalog/get.
The full catalog is ~75 KB today and grows with the catalog; caching is about avoiding unnecessary round-trips, not about bandwidth.
Intended use
- Discovering what the API exposes. One call, complete tree, every detail a codegen tool needs.
- Rendering a UI that lists instruments or composites. Use
display_namewith an?audience=that matches the UI's stakeholder. - Detecting contract drift. Cache
version+last_updated; compare on the next call.
Mistaken use
- Do not parse the response to discover paths for ad-hoc endpoints.
The catalog is the public inventory — if something is not listed,
it is not a stable public endpoint. Use
/api/catalog/operationswhen you want the flat list of(method, path)tuples. - Do not pass
?audience=if you want to preserve canonical labels. The audience-resolveddisplay_nameoverwrites the canonical one in the response; if you need both, read fromdisplay_nameand thealiasesmap. - Do not treat an empty
aliasesmap as "audience is unsupported." It just means no audience-specific label was registered for that entity. With?audience=set, the canonicaldisplay_nameis returned as the fallback, not an error. - Do not use this for every request. It is meant for bootstrapping and cache refresh. Polling it alongside every scoring call is wasteful and teaches future callers a bad pattern.
Debugging
- Capture the request ID. On an error, quote the envelope's
request_id. A successful response carries none in its body, so capture theX-Request-IDresponse header (the gateway's trace ID for the call, which support can also look up). 400 ValidationErrorwithfield: "audience"— theaudiencevalue is not one ofemployee,employer,provider. Fix the query string.- Labels do not match what the docs show. Check whether
?audience=is set on your call. Without it, canonicaldisplay_nameis returned; with it, the audience alias is used. versionmatches but a scoring response carries a newercatalog_version. That indicates the deploy is moving mid-flight — refetch and try again.
Rate limits
See rate-limits.md. The response is small and stable; caching sharply reduces the number of calls you need.
Related endpoints
GET /api/catalog/categories— same tree withouttop_level_resources.GET /api/catalog/resources— flat resource list withpath_prefixfor each.GET /api/catalog/operations— flat(method, path, version)tuples. Best surface for codegen.GET /api/catalog/category— single category by?name=.GET /api/catalog/resource— single resource by?name=(optionally?category=).GET /api/version/get— thecatalog_version+ build metadata pair this endpoint was designed to be cached against.
Change history
| Date | Change |
|---|---|
| 2026-04-20 | Initial publication. |
| 2026-10-14 | Examples recaptured against catalog 0.42.0; counts and resource lists updated. naics now sits in the lookup category with regulations, icd10cm, cpt, and fee_schedule. |
| 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. |