Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.kaireonai.com/llms.txt

Use this file to discover all available pages before exploring further.

Categories form the top level of the business hierarchy. Each category can contain sub-categories, which in turn group offers. Categories also define custom fields (including computed fields with formulas) that are inherited by all offers within the category. All categories support soft-delete (a deletedAt timestamp is set instead of permanent removal), version tracking (the version field auto-increments on every update), and audit logging (before/after snapshots are recorded for every CRUD operation).
See the Business Hierarchy feature page for UI guidance and conceptual overview.

Base path

/api/v1/categories        # Categories
/api/v1/sub-categories    # Sub-categories

Categories

List categories

GET /api/v1/categories
Returns a paginated list of categories for the current tenant, ordered by ordinal ascending. Each category includes its sub-categories with offer counts. By default, soft-deleted categories are excluded.

Query parameters

ParameterRequiredTypeDescription
limitNointegerMaximum results per page. Default 25.
cursorNostringCursor for keyset pagination.
includeDeletedNostringSet to "true" to include soft-deleted categories in the results.

Response 200

{
  "data": [
    {
      "id": "cat_01",
      "tenantId": "t_001",
      "name": "Acquisition",
      "description": "New customer acquisition offers.",
      "icon": "user-plus",
      "color": "blue",
      "status": "active",
      "ordinal": 0,
      "version": 1,
      "deletedAt": null,
      "customFields": [
        {
          "key": "base_rate",
          "label": "Base Rate",
          "type": "number",
          "defaultValue": 0
        },
        {
          "key": "personalized_rate",
          "label": "Personalized Rate",
          "type": "computed",
          "formula": "base_rate * (1 + customer.loyalty_score / 100)",
          "outputType": "number"
        }
      ],
      "subCategories": [
        {
          "id": "sub_01",
          "name": "Credit Cards",
          "_count": { "offers": 12 }
        }
      ],
      "createdAt": "2026-03-10T12:00:00.000Z",
      "updatedAt": "2026-03-12T09:30:00.000Z"
    }
  ],
  "pagination": {
    "total": 4,
    "limit": 25,
    "hasMore": false,
    "nextCursor": null
  }
}

Error codes

CodeReason
401Missing or invalid API key / session.
403Insufficient role.

Create a category

POST /api/v1/categories

Request body

FieldRequiredTypeDescription
nameYesstring (1-255)Unique category name.
descriptionNostringCategory description.
iconNostringIcon identifier (e.g., Lucide icon name).
colorNostringDisplay color. Default "blue".
statusNoenumdraft, active (default), paused, archived.
ordinalNointeger (>= 0)Sort order. Default 0.
customFieldsNoarrayCustom field definitions (see below). Max 500 items.

Custom field object

FieldRequiredTypeDescription
keyYesstringMachine-readable field key.
labelYesstringHuman-readable label.
typeYesstringField type: text, number, boolean, select, computed.
defaultValueNoanyDefault value for the field.
formulaConditionalstringFormula expression. Required when type is computed.
outputTypeConditionalenumnumber or text. Required when type is computed.
Computed fields require both a valid formula and an outputType (number or text). The formula is validated using the formula engine. Supported namespaces: fieldName (sibling fields), customer.* (enriched data), attributes.* (request-time attributes).

Example request

{
  "name": "Retention",
  "description": "Offers aimed at retaining existing customers.",
  "color": "green",
  "ordinal": 1,
  "customFields": [
    { "key": "discount_pct", "label": "Discount %", "type": "number", "defaultValue": 10 },
    {
      "key": "final_discount",
      "label": "Final Discount",
      "type": "computed",
      "formula": "discount_pct * (customer.tenure_years > 5 ? 1.2 : 1.0)",
      "outputType": "number"
    }
  ]
}

Response 201

Returns the created category with version: 1, deletedAt: null, and sub-categories relation. An audit log entry is created with a create action and a snapshot of the new entity.

Error codes

CodeReason
400Validation error (missing name, invalid computed field).
401Missing or invalid API key / session.
403Insufficient role (requires editor or admin).
409A category with that name already exists.
415Content-Type is not application/json.

Update a category

PUT /api/v1/categories
Updates an existing category. Only provided fields are changed. The version field is auto-incremented and a before/after audit snapshot is recorded.

Request body

FieldRequiredTypeDescription
idYesstringCategory ID to update.
All other fields from the create schema are accepted as optional.

Response 200

Returns the updated category object with the incremented version.

Error codes

CodeReason
400Validation error.
401Missing or invalid API key / session.
403Insufficient role.
409A category with that name already exists.

Delete a category (soft-delete)

DELETE /api/v1/categories?id={categoryId}
Soft-deletes a category by setting its deletedAt timestamp. Cascade behavior: all child sub-categories and offers under this category are also soft-deleted. The version is incremented on the category and each cascaded child. An audit log entry is recorded for every affected entity.

Query parameters

ParameterRequiredTypeDescription
idYesstringCategory ID to delete.

Response 200

{
  "deleted": true,
  "id": "cat_01",
  "cascaded": 5,
  "message": "Category soft-deleted along with 5 child entities."
}

Error codes

CodeReason
400Missing id query parameter, entity not found, or entity already deleted.
401Missing or invalid API key / session.
403Insufficient role.
To restore a soft-deleted category, use POST /api/v1/restore?entityType=category&id={categoryId} (admin only). Restoring a category does not automatically restore cascaded children — you must restore sub-categories and offers individually.

Sub-categories

Sub-categories live under a category and group related offers. They also support soft-delete, version tracking, and audit logging.

List sub-categories

GET /api/v1/sub-categories

Query parameters

ParameterRequiredTypeDescription
categoryIdNostringFilter to a specific parent category.
limitNointegerMaximum results per page. Default 25.
cursorNostringCursor for keyset pagination.
includeDeletedNostringSet to "true" to include soft-deleted sub-categories.

Response 200

{
  "data": [
    {
      "id": "sub_01",
      "tenantId": "t_001",
      "categoryId": "cat_01",
      "name": "Credit Cards",
      "description": "",
      "icon": "",
      "status": "active",
      "ordinal": 0,
      "version": 1,
      "deletedAt": null,
      "customFields": [],
      "category": { "id": "cat_01", "name": "Acquisition" },
      "_count": { "offers": 12 }
    }
  ],
  "pagination": {
    "total": 3,
    "limit": 25,
    "hasMore": false,
    "nextCursor": null
  }
}

Create a sub-category

POST /api/v1/sub-categories

Request body

FieldRequiredTypeDescription
categoryIdYesstringParent category ID.
nameYesstringSub-category name.
descriptionNostringDescription.
iconNostringIcon identifier.
statusNoenumdraft, active (default), paused, archived.
ordinalNointeger (>= 0)Sort order. Default 0.
customFieldsNoarrayCustom field definitions (same schema as categories).

Response 201

Returns the created sub-category with its parent category relation, version: 1, and deletedAt: null.

Error codes

CodeReason
400Validation error (missing categoryId or name).
401Missing or invalid API key / session.
403Insufficient role.
409A sub-category with that name already exists.
415Content-Type is not application/json.

Update a sub-category

PUT /api/v1/sub-categories
Updates an existing sub-category. The version field is auto-incremented and a before/after audit snapshot is recorded.

Request body

FieldRequiredTypeDescription
idYesstringSub-category ID to update.
All other fields are optional.

Response 200

Returns the updated sub-category object with the incremented version.

Error codes

CodeReason
400Validation error or missing id.
401Missing or invalid API key / session.
403Insufficient role.
409A sub-category with that name already exists.

Delete a sub-category (soft-delete)

DELETE /api/v1/sub-categories?id={subCategoryId}
Soft-deletes a sub-category by setting its deletedAt timestamp. The version is incremented.

Query parameters

ParameterRequiredTypeDescription
idYesstringSub-category ID to delete.

Response 200

{
  "success": true
}

Error codes

CodeReason
400Missing id, entity not found, or entity already deleted.
401Missing or invalid API key / session.
403Insufficient role.

Role requirements

MethodMinimum role
GETviewer
POSTeditor
PUTeditor
DELETEeditor

Business Hierarchy

Learn more about organising categories and sub-categories in the platform UI.