Catalog
Categories
Fetch the tenant's full category tree as nested JSON.
View as MarkdownCategories form a self-referential tree per tenant. Each category has a slug that is unique within the tenant and auto-generated from its name. Category slugs are the values accepted by the product list's filter[category] query parameter, which matches a category and all of its active descendants.
Categories form a self-referential tree per tenant. Each category has a slug that is unique within the tenant and auto-generated from its name. Category slugs are the values accepted by the product list's filter[category] query parameter, which matches a category and all of its active descendants.
GET /v1/api/commerce/categories
Returns the tenant's full category tree as nested JSON. Only active categories are included, ordered by position at every level. An inactive parent hides its entire subtree: children of an inactive parent are orphaned out of the result, even if they are active themselves. The response is not paginated.
Parameters
None. No path, query, or body parameters.
Response fields
Each node in the data array (and recursively in each children array):
| Name | Type | Required | Description |
|---|---|---|---|
| id | string (uuid) | always | Category ID. |
| name | string | always | Category name. |
| slug | string | always | URL slug, unique per tenant. Use it as the filter[category] value on the product list endpoint. |
| description | string or null | always | Category description. |
| children | array | always | Child categories, same node shape, ordered by position. Empty array for leaf categories. |
Errors
| Status | Body | Cause |
|---|---|---|
| 401 | {"message":"Unauthenticated."} | Missing or invalid API key. |
| 403 | {"message":"Invalid ability provided."} | Key lacks the commerce:read scope. |
| 403 | {"error":"Module not enabled: commerce"} | Tenant does not have the commerce module enabled. Note the error key instead of message. |
| 403 | {"message":"Tenant suspended.","code":"tenant_suspended"} | Tenant account is suspended. |
| 429 | {"message":"Too Many Attempts."} | Rate limit of 120 requests per minute exceeded. |
curl "https://api.borkol.com/v1/api/commerce/categories" \
-H "Authorization: Bearer {api_key}" \
-H "Accept: application/json"const res = await fetch("https://api.borkol.com/v1/api/commerce/categories", {
headers: {
Authorization: `Bearer ${apiKey}`,
Accept: "application/json",
},
});
const { data } = await res.json();{
"data": [
{
"id": "7a1b3c5d-2e4f-4a6b-8c0d-1e2f3a4b5c6d",
"name": "Furniture",
"slug": "furniture",
"description": "All furniture",
"children": [
{
"id": "8b2c4d6e-3f5a-4b7c-9d1e-2f3a4b5c6d7e",
"name": "Chairs",
"slug": "chairs",
"description": null,
"children": []
}
]
},
{
"id": "1f2e3d4c-5b6a-4978-8695-a4b3c2d1e0f9",
"name": "Verandas",
"slug": "verandas",
"description": null,
"children": []
}
]
}GET /v1/api/commerce/categories
Returns the tenant's full category tree as nested JSON. Only active categories are included, ordered by position at every level. An inactive parent hides its entire subtree: children of an inactive parent are orphaned out of the result, even if they are active themselves. The response is not paginated.
Parameters
None. No path, query, or body parameters.
Response fields
Each node in the data array (and recursively in each children array):
| Name | Type | Required | Description |
|---|---|---|---|
| id | string (uuid) | always | Category ID. |
| name | string | always | Category name. |
| slug | string | always | URL slug, unique per tenant. Use it as the filter[category] value on the product list endpoint. |
| description | string or null | always | Category description. |
| children | array | always | Child categories, same node shape, ordered by position. Empty array for leaf categories. |
curl "https://api.borkol.com/v1/api/commerce/categories" \
-H "Authorization: Bearer {api_key}" \
-H "Accept: application/json"const res = await fetch("https://api.borkol.com/v1/api/commerce/categories", {
headers: {
Authorization: `Bearer ${apiKey}`,
Accept: "application/json",
},
});
const { data } = await res.json();{
"data": [
{
"id": "7a1b3c5d-2e4f-4a6b-8c0d-1e2f3a4b5c6d",
"name": "Furniture",
"slug": "furniture",
"description": "All furniture",
"children": [
{
"id": "8b2c4d6e-3f5a-4b7c-9d1e-2f3a4b5c6d7e",
"name": "Chairs",
"slug": "chairs",
"description": null,
"children": []
}
]
},
{
"id": "1f2e3d4c-5b6a-4978-8695-a4b3c2d1e0f9",
"name": "Verandas",
"slug": "verandas",
"description": null,
"children": []
}
]
}Errors
| Status | Body | Cause |
|---|---|---|
| 401 | {"message":"Unauthenticated."} | Missing or invalid API key. |
| 403 | {"message":"Invalid ability provided."} | Key lacks the commerce:read scope. |
| 403 | {"error":"Module not enabled: commerce"} | Tenant does not have the commerce module enabled. Note the error key instead of message. |
| 403 | {"message":"Tenant suspended.","code":"tenant_suspended"} | Tenant account is suspended. |
| 429 | {"message":"Too Many Attempts."} | Rate limit of 120 requests per minute exceeded. |