SeloraXDEVELOPERS

Categories

Categories API

Manage product categories for the authenticated store. Categories support a nested tree structure via parent_id, allowing you to build multi-level category hierarchies.

List Categories

Retrieve all categories for the store. Returns a flat list with parent_id for client-side tree building, ordered by position_index then name.

GET /api/apps/v1/categories

Authentication

Required. Must include valid app credentials.

Scope

read:products

Query Parameters

ParameterTypeDefaultDescription
parent_idstring--Filter by parent category. Use null or 0 for root categories, or a category ID for children of that category

Example Request

curl -X GET "https://api.selorax.io/api/apps/v1/categories" \
  -H "Authorization: Bearer <token>"

Get only root categories:

curl -X GET "https://api.selorax.io/api/apps/v1/categories?parent_id=null" \
  -H "Authorization: Bearer <token>"

Get children of a specific category:

curl -X GET "https://api.selorax.io/api/apps/v1/categories?parent_id=5" \
  -H "X-Client-Id: sx_app_..." \
  -H "X-Client-Secret: sx_secret_..." \
  -H "X-Store-Id: 22"

Response

{
  "data": [
    {
      "category_id": 5,
      "store_id": 22,
      "name": "Flowers",
      "slug": "flowers",
      "image": "categories/flowers.jpg",
      "parent_id": null,
      "is_featured": 1,
      "position_index": 1,
      "created_at": "2025-01-10T08:00:00.000Z",
      "updated_at": "2025-06-01T12:00:00.000Z",
      "products_count": 24
    },
    {
      "category_id": 8,
      "store_id": 22,
      "name": "Roses",
      "slug": "roses",
      "image": null,
      "parent_id": 5,
      "is_featured": 0,
      "position_index": 1,
      "created_at": "2025-01-10T08:30:00.000Z",
      "updated_at": "2025-06-01T12:00:00.000Z",
      "products_count": 12
    },
    {
      "category_id": 6,
      "store_id": 22,
      "name": "Gift Baskets",
      "slug": "gift-baskets",
      "image": "categories/gift-baskets.jpg",
      "parent_id": null,
      "is_featured": 0,
      "position_index": 2,
      "created_at": "2025-01-10T09:00:00.000Z",
      "updated_at": "2025-03-15T10:00:00.000Z",
      "products_count": 8
    }
  ],
  "status": 200
}

Response Fields

FieldTypeDescription
category_idintegerUnique category identifier
store_idintegerStore the category belongs to
namestringCategory name
slugstringURL-friendly slug
imagestring or nullCategory image path
parent_idinteger or nullParent category ID (null for root categories)
is_featuredinteger (0 or 1)Whether the category is featured
position_indexinteger or nullSort order within its level
products_countintegerNumber of active products in this category
created_atstring (ISO 8601)When the category was created
updated_atstring (ISO 8601)When the category was last updated

Building a Category Tree

The list endpoint returns a flat array. To build a tree on the client side, group items by parent_id — entries with parent_id: null are root nodes, and child nodes reference their parent's category_id.

Node.js Example

const response = await fetch(
  "https://api.selorax.io/api/apps/v1/categories",
  { headers: { Authorization: "Bearer sx_at_..." } }
);
const { data } = await response.json();
 
// Build tree from flat list
const roots = data.filter(c => c.parent_id === null);
const children = data.filter(c => c.parent_id !== null);
roots.forEach(root => {
  root.children = children.filter(c => c.parent_id === root.category_id);
});

Python Example

import requests
 
response = requests.get(
    "https://api.selorax.io/api/apps/v1/categories",
    headers={"Authorization": "Bearer sx_at_..."},
)
categories = response.json()["data"]
for cat in categories:
    indent = "  " if cat["parent_id"] else ""
    print(f"{indent}{cat['name']} ({cat['products_count']} products)")

Get Category

Retrieve a single category by ID, including its direct children.

GET /api/apps/v1/categories/:category_id

Authentication

Required. Must include valid app credentials.

Scope

read:products

Path Parameters

ParameterTypeDescription
category_idintegerThe category ID

Example Request

curl -X GET "https://api.selorax.io/api/apps/v1/categories/5" \
  -H "Authorization: Bearer <token>"

Response

{
  "data": {
    "category_id": 5,
    "store_id": 22,
    "name": "Flowers",
    "slug": "flowers",
    "image": "categories/flowers.jpg",
    "parent_id": null,
    "is_featured": 1,
    "position_index": 1,
    "created_at": "2025-01-10T08:00:00.000Z",
    "updated_at": "2025-06-01T12:00:00.000Z",
    "products_count": 24,
    "children": [
      {
        "category_id": 8,
        "name": "Roses",
        "slug": "roses",
        "image": null,
        "is_featured": 0,
        "position_index": 1,
        "products_count": 12
      },
      {
        "category_id": 9,
        "name": "Tulips",
        "slug": "tulips",
        "image": null,
        "is_featured": 0,
        "position_index": 2,
        "products_count": 6
      }
    ]
  },
  "status": 200
}

Error Responses

If the category_id does not exist or does not belong to the authenticated store:

{
  "message": "Category not found.",
  "status": 404
}

Create Category

Create a new category. A URL slug is auto-generated from the name if not provided.

POST /api/apps/v1/categories

Authentication

Required. Must include valid app credentials.

Scope

write:products

Request Body

FieldTypeRequiredDescription
namestringYesCategory name (max 255 characters)
slugstringNoURL-friendly slug (max 45 characters). Auto-generated from name if omitted
parent_idinteger or nullNoParent category ID for nesting. Must belong to the same store
imagestringNoCategory image path
is_featuredintegerNo1 to feature, 0 otherwise (default 0)
position_indexintegerNoSort position within its level

Example Request

curl -X POST "https://api.selorax.io/api/apps/v1/categories" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Indoor Plants",
    "parent_id": null,
    "is_featured": 1,
    "position_index": 3
  }'

Create a subcategory:

curl -X POST "https://api.selorax.io/api/apps/v1/categories" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Succulents",
    "parent_id": 10,
    "position_index": 1
  }'

Response

{
  "data": {
    "category_id": 10,
    "store_id": 22,
    "name": "Indoor Plants",
    "slug": "indoor-plants",
    "image": null,
    "parent_id": null,
    "is_featured": 1,
    "position_index": 3,
    "created_at": "2025-06-20T10:00:00.000Z",
    "updated_at": "2025-06-20T10:00:00.000Z"
  },
  "message": "Category created.",
  "status": 201
}

Slug Uniqueness

If the generated slug already exists for the same store, a numeric suffix is appended automatically (e.g. indoor-plants-2).

Error Responses

CodeStatusMeaning
invalid_token401Token is expired or invalid
insufficient_scope403App does not have write:products scope
invalid_parent400The specified parent_id does not exist in this store
--400Validation error (missing name, etc.)

Update Category

Update an existing category. Only provided fields are modified.

PUT /api/apps/v1/categories/:category_id

Authentication

Required. Must include valid app credentials.

Scope

write:products

Path Parameters

ParameterTypeDescription
category_idintegerThe category ID to update

Request Body

FieldTypeRequiredDescription
namestringNoCategory name (max 255 characters)
slugstringNoURL-friendly slug (max 45 characters)
parent_idinteger or nullNoParent category ID. Set to null to make it a root category
imagestringNoCategory image path
is_featuredintegerNo1 to feature, 0 otherwise
position_indexinteger or nullNoSort position

At least one field must be provided.

Example Request

curl -X PUT "https://api.selorax.io/api/apps/v1/categories/10" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Houseplants",
    "is_featured": 0,
    "position_index": 5
  }'

Response

{
  "data": {
    "category_id": 10,
    "store_id": 22,
    "name": "Houseplants",
    "slug": "indoor-plants",
    "image": null,
    "parent_id": null,
    "is_featured": 0,
    "position_index": 5,
    "created_at": "2025-06-20T10:00:00.000Z",
    "updated_at": "2025-06-20T15:30:00.000Z"
  },
  "message": "Category updated.",
  "status": 200
}

Error Responses

CodeStatusMeaning
invalid_token401Token is expired or invalid
insufficient_scope403App does not have write:products scope
invalid_parent400The specified parent_id does not exist in this store
self_parent400A category cannot be its own parent
--400Validation error
--404Category not found

Delete Category

Delete a category. The category must have no products attached — reassign or remove products first.

DELETE /api/apps/v1/categories/:category_id

Authentication

Required. Must include valid app credentials.

Scope

write:products

Path Parameters

ParameterTypeDescription
category_idintegerThe category ID to delete

Example Request

curl -X DELETE "https://api.selorax.io/api/apps/v1/categories/10" \
  -H "Authorization: Bearer <token>"

Response

{
  "message": "Category deleted.",
  "status": 200
}

Error Responses

CodeStatusMeaning
invalid_token401Token is expired or invalid
insufficient_scope403App does not have write:products scope
category_has_products400Cannot delete a category that has products assigned to it
--404Category not found

Category with products error:

{
  "message": "Cannot delete category with 12 attached product(s). Remove or reassign products first.",
  "code": "category_has_products",
  "status": 400
}