Single Catalog Category
Status:
stableCategory:catalogAdded:2026-04-20Last reviewed:2026-04-21
Summary
Returns one category — identified by ?name= — with its nested
resources and operations. Use this when you already know which
category you want; it returns less data than
/api/catalog/categories and no more work
than /api/catalog/get.
Endpoint
| Field | Value |
|---|---|
| Method | GET |
| Path | /api/catalog/category |
| Full URL | https://engine.tripod-health.com/api/catalog/category |
| Authentication | API key (required) |
| Request body | none |
| Response body | application/json |
| Idempotent | Yes |
| Rate-limited | Yes |
Purpose
- Direct lookup when you know the category name. Cheaper and easier to consume than slicing it out of the full catalog.
- Verifying a category exists before constructing URLs that depend on it.
- Fetching audience-specific labels for just one category. Pair
with
?audience=and you get the labels you need without paying for the whole catalog.
Authentication
Send a valid API key in the apikey header. See
authentication.md.
Request
Headers
| Header | Required | Description |
|---|---|---|
apikey | Yes | Consumer API key. |
X-Request-ID | No | Optional correlation ID. Echoed in the X-Request-ID response header. |
Path parameters
None.
Query parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
name | string | Yes | — | Category name (for example "pain", "function"). Must match a registered category exactly — lookup is case-sensitive. |
audience | string | No | none | One of employee, employer, provider. Replaces the category's (and nested resources' and operations') display_name with that audience's alias, falling back to canonical labels when no alias is registered. |
Body
None.
Response
Success — 200 OK
The response is a single category object, identical in shape to one
element of the categories[] array from
/api/catalog/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": "0.1.0",
"last_updated": "2026-04-17",
"operations": [
{ "name": "questions", "display_name": "Questions", "aliases": {}, "description": "Return the instrument's items, ordering, and answer choices so the caller can render or present them.", "version": "0.1.0", "last_updated": "2026-04-17", "http_method": "GET" },
{ "name": "score", "display_name": "Score", "aliases": {}, "description": "Submit responses to the instrument and receive its score (and profile, where the instrument supports classification).", "version": "0.1.0", "last_updated": "2026-04-17", "http_method": "POST" }
]
}
]
}
Response fields
Same as one element of the categories[] array from
/api/catalog/categories. Key fields:
| Field | Type | Always present | Description |
|---|---|---|---|
name | string | Yes | Category identifier used in paths. |
display_name | string | Yes | Canonical label, or the audience alias when ?audience= was set. |
aliases | object | Yes | Audience-to-label map. May be {}. |
description | string | Yes | One-sentence description of the category. |
version | string (SemVer) | Yes | Category-level version. |
last_updated | string (ISO date) | Yes | Last structural change. |
resources | array | Yes | Resources in this category. Each follows the resource shape documented in /api/catalog/resources (except without category / path_prefix — see below). |
Status codes
| Code | Meaning | When |
|---|---|---|
200 | OK | Category returned. |
400 | ValidationError | name was not provided. Also emitted when audience is not one of the allowed values. field names the offending parameter. |
401 | Unauthenticated | Missing or invalid API key. |
404 | NotFound | No category with that name is registered. |
429 | RateLimited | Per-consumer rate limit exceeded. |
Examples
The language-specific invocations below assume the call() helper (or
its equivalent) from quickstart.md.
1. Canonical request and response
Send:
GET /api/catalog/category?name=pain HTTP/1.1
Host: engine.tripod-health.com
apikey: $ENGINE_API_KEY
X-Request-ID: docs-catalog-category-canonical
Receive (200 OK):
{
"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": "0.1.0",
"last_updated": "2026-04-17",
"operations": [
{
"name": "questions",
"display_name": "Questions",
"aliases": {},
"description": "Return the instrument's items, ordering, and answer choices so the caller can render or present them.",
"version": "0.1.0",
"last_updated": "2026-04-17",
"http_method": "GET"
},
{
"name": "score",
"display_name": "Score",
"aliases": {},
"description": "Submit responses to the instrument and receive its score (and profile, where the instrument supports classification).",
"version": "0.1.0",
"last_updated": "2026-04-17",
"http_method": "POST"
}
]
}
]
}
The live pain category today carries two resources (orebro,
pain_scale); only the first is shown above.
2. Calling the endpoint in your language
curl
# Canonical labels
curl -sS "https://engine.tripod-health.com/api/catalog/category?name=pain" \
-H "apikey: $ENGINE_API_KEY"
# Employee-facing labels. display_name on the category becomes "Pain Level";
# every nested resource's display_name uses its employee alias. Canonical
# labels remain in the aliases map.
curl -sS "https://engine.tripod-health.com/api/catalog/category?name=function&audience=employee" \
-H "apikey: $ENGINE_API_KEY"
Python (requests)
# Uses the call() + EngineError from quickstart.md.
try:
cat = call("GET", "/api/catalog/category?name=function&audience=provider")
except EngineError as e:
if e.status == 404:
raise RuntimeError("function category is not registered in this deploy")
raise
for res in cat["resources"]:
print(f" {res['display_name']} (/api/{cat['name']}/{res['name']})")
Node.js (native fetch)
// Uses the call() + EngineError from quickstart.md.
try {
const cat = await call("GET", "/api/catalog/category?name=pain");
for (const res of cat.resources) {
console.log(` ${res.display_name} (/api/${cat.name}/${res.name})`);
}
} catch (e) {
if (e.status === 404) console.warn("pain category not registered");
else throw e;
}
TypeScript
// Uses the typed call<T>() helper from quickstart.md.
// The CatalogCategory type is the same one shown in catalog-categories.md.
const category = await call<CatalogCategory>(
"GET",
"/api/catalog/category?name=pain&audience=provider",
);
Go
// Uses the call() helper from quickstart.md.
cat, err := call("GET", "/api/catalog/category?name=pain", nil, 3)
if err != nil {
if ee, ok := err.(*EngineError); ok && ee.Status == 404 {
log.Println("pain category not registered")
return
}
panic(err)
}
fmt.Println(cat["display_name"])
Java
// Uses the call() helper from quickstart.md.
try {
String cat = call("GET", "/api/catalog/category?name=pain", null, 3);
System.out.println(extract(cat, "display_name"));
} catch (EngineException e) {
if (e.status == 404) System.err.println("pain category not registered");
else throw e;
}
C# (.NET HttpClient)
// Uses the Call() helper from quickstart.md.
try
{
var cat = await Call(HttpMethod.Get, "/api/catalog/category?name=pain");
Console.WriteLine(cat.GetProperty("display_name").GetString());
}
catch (HttpRequestException ex) when (ex.Message.Contains("404"))
{
Console.Error.WriteLine("pain category not registered");
}
PowerShell
# Uses the Invoke-Engine helper from quickstart.md.
try {
$cat = Invoke-Engine -Method Get -Path "/api/catalog/category?name=pain"
$cat.display_name
} catch {
if ($_.Exception.Message -match "404") {
Write-Warning "pain category not registered"
} else { throw }
}
3. Error scenarios
Missing name
Send:
curl -sS "https://engine.tripod-health.com/api/catalog/category" \
-H "apikey: $ENGINE_API_KEY" \
-H "X-Request-ID: docs-catalog-category-missing-name" \
-w "\nHTTP %{http_code}\n"
Receive (400):
{
"timestamp": "2026-04-21T23:05:31.464Z",
"error": "ValidationError",
"message": "Query parameter 'name' is required",
"field": "name",
"request_id": "docs-catalog-category-missing-name"
}
Unknown category
Send:
curl -sS "https://engine.tripod-health.com/api/catalog/category?name=frobnitz" \
-H "apikey: $ENGINE_API_KEY" \
-H "X-Request-ID: docs-catalog-category-unknown" \
-w "\nHTTP %{http_code}\n"
Receive (404):
{
"timestamp": "2026-04-21T23:05:31.850Z",
"error": "NotFound",
"message": "Category 'frobnitz' is not registered",
"request_id": "docs-catalog-category-unknown"
}
Invalid audience
Send:
curl -sS "https://engine.tripod-health.com/api/catalog/category?name=pain&audience=bogus" \
-H "apikey: $ENGINE_API_KEY" \
-H "X-Request-ID: docs-catalog-category-bad-audience" \
-w "\nHTTP %{http_code}\n"
Receive (400):
{
"timestamp": "2026-04-21T23:05:32.240Z",
"error": "ValidationError",
"message": "Unknown audience 'bogus'. Valid values: employee, employer, provider.",
"field": "audience",
"request_id": "docs-catalog-category-bad-audience"
}
Intended use
- Validating a category name before constructing URLs. A
200confirms the category exists and gives you the resources inside it. - Rendering a single category's details. A UI drilling into a category can fetch just that category instead of the full catalog.
- Checking whether a category's
versionorlast_updatedhas moved without pulling the full tree.
Mistaken use
- Do not pass
?name=with the category'sdisplay_namevalue. The lookup is on the canonicalnamefield (URL-safe identifier like"pain","rtw_belief"), not on the human-readable label. Passing"Pain Severity"returns404. - Do not use this to discover which categories exist. Use
/api/catalog/categories. A negative result from/category?name=Xcannot distinguish "X was removed" from "X never existed." - Do not URL-decode
nameexpecting Trinity to tolerate synonyms. The match is exact, byte-for-byte. - Do not assume
resources[]is sorted alphabetically. Resources appear in catalog declaration order within the category. Sort client-side if you need a specific order.
Debugging
- Capture the
X-Request-IDresponse header. 400 ValidationErrorwithfield: "name"— you did not include?name=in the query string, or it was empty.400 ValidationErrorwithfield: "audience"—audiencewas set to something other thanemployee,employer,provider.404 NotFound— the category does not exist in the current deploy. Cross-reference with/api/catalog/categoriesto see which categories are live; check/api/version/getto see which deploy you are hitting.- Category exists but nested resources look wrong. Check the
versionandlast_updatedfields on the category and its resources — something may have moved between your cache and the current deploy.
Rate limits
See rate-limits.md.
Related endpoints
GET /api/catalog/get— full catalog tree.GET /api/catalog/categories— all categories at once.GET /api/catalog/resource— single resource by?name=, optionally scoped by?category=.
Change history
| Date | Change |
|---|---|
| 2026-04-20 | Initial publication. |