Skip to main content

Category Object

Categories organize menu items into groups like “Appetizers”, “Main Courses”, “Desserts”, etc.
id
string (uuid)
Unique identifier for the category
branch_id
string (uuid)
ID of the branch this category belongs to
organization_id
string (uuid)
ID of the parent organization
name
string
Category name (1-255 characters)
description
string
Optional description (max 500 characters)
image_url
string
Optional category image URL
sort_order
integer
Display order (default: 0, lower numbers appear first)
is_active
boolean
Whether the category is visible to customers (default: true)

List Categories

GET /menu/categories

Retrieve all categories for the current branch
Required Permission: menu:read Request:
curl https://api.restai.com/v1/menu/categories \
  -H "Authorization: Bearer <token>"
Response:
{
  "success": true,
  "data": [
    {
      "id": "a1b2c3d4-e5f6-4a5b-8c9d-0e1f2a3b4c5d",
      "branch_id": "550e8400-e29b-41d4-a716-446655440000",
      "organization_id": "123e4567-e89b-12d3-a456-426614174000",
      "name": "Entradas",
      "description": "Deliciosos aperitivos para comenzar tu comida",
      "image_url": "https://example.com/images/entradas.jpg",
      "sort_order": 0,
      "is_active": true
    },
    {
      "id": "b2c3d4e5-f6a7-5b6c-9d0e-1f2a3b4c5d6e",
      "branch_id": "550e8400-e29b-41d4-a716-446655440000",
      "organization_id": "123e4567-e89b-12d3-a456-426614174000",
      "name": "Platos Principales",
      "description": "Nuestros mejores platos",
      "image_url": "https://example.com/images/principales.jpg",
      "sort_order": 1,
      "is_active": true
    },
    {
      "id": "c3d4e5f6-a7b8-6c7d-0e1f-2a3b4c5d6e7f",
      "branch_id": "550e8400-e29b-41d4-a716-446655440000",
      "organization_id": "123e4567-e89b-12d3-a456-426614174000",
      "name": "Postres",
      "description": "Dulces delicias",
      "image_url": null,
      "sort_order": 2,
      "is_active": true
    }
  ]
}

Create Category

POST /menu/categories

Create a new menu category
Required Permission: menu:create Body Parameters:
name
string
required
Category name (1-255 characters)
description
string
Category description (max 500 characters)
imageUrl
string
URL to category image (must be valid URL)
sortOrder
integer
default:"0"
Display order (min: 0)
isActive
boolean
default:"true"
Whether category is visible to customers
Request:
curl -X POST https://api.restai.com/v1/menu/categories \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Bebidas",
    "description": "Refrescantes bebidas frías y calientes",
    "imageUrl": "https://example.com/images/bebidas.jpg",
    "sortOrder": 3,
    "isActive": true
  }'
Response (201 Created):
{
  "success": true,
  "data": {
    "id": "d4e5f6a7-b8c9-7d8e-1f2a-3b4c5d6e7f8a",
    "branch_id": "550e8400-e29b-41d4-a716-446655440000",
    "organization_id": "123e4567-e89b-12d3-a456-426614174000",
    "name": "Bebidas",
    "description": "Refrescantes bebidas frías y calientes",
    "image_url": "https://example.com/images/bebidas.jpg",
    "sort_order": 3,
    "is_active": true
  }
}

Update Category

PATCH /menu/categories/:id

Update an existing category. All fields are optional.
Required Permission: menu:update Path Parameters:
id
string (uuid)
required
Category ID
Body Parameters (all optional):
name
string
Category name (1-255 characters)
description
string
Category description (max 500 characters)
imageUrl
string
URL to category image
sortOrder
integer
Display order (min: 0)
isActive
boolean
Whether category is visible to customers
Request:
curl -X PATCH https://api.restai.com/v1/menu/categories/d4e5f6a7-b8c9-7d8e-1f2a-3b4c5d6e7f8a \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Bebidas y Jugos",
    "isActive": false
  }'
Response:
{
  "success": true,
  "data": {
    "id": "d4e5f6a7-b8c9-7d8e-1f2a-3b4c5d6e7f8a",
    "branch_id": "550e8400-e29b-41d4-a716-446655440000",
    "organization_id": "123e4567-e89b-12d3-a456-426614174000",
    "name": "Bebidas y Jugos",
    "description": "Refrescantes bebidas frías y calientes",
    "image_url": "https://example.com/images/bebidas.jpg",
    "sort_order": 3,
    "is_active": false
  }
}
Error Response:
// 404 Not Found
{
  "success": false,
  "error": {
    "code": "NOT_FOUND",
    "message": "Categoría no encontrada"
  }
}

Delete Category

DELETE /menu/categories/:id

Delete a category and all its menu items
Required Permission: menu:delete Path Parameters:
id
string (uuid)
required
Category ID
Request:
curl -X DELETE https://api.restai.com/v1/menu/categories/d4e5f6a7-b8c9-7d8e-1f2a-3b4c5d6e7f8a \
  -H "Authorization: Bearer <token>"
Response:
{
  "success": true,
  "data": {
    "message": "Categoría eliminada"
  }
}
Deleting a category will cascade delete all menu items in that category due to foreign key constraints. This action cannot be undone.

Sort Order

Use the sort_order field to control the display order of categories:
[
  { "name": "Entradas", "sort_order": 0 },
  { "name": "Platos Principales", "sort_order": 1 },
  { "name": "Postres", "sort_order": 2 },
  { "name": "Bebidas", "sort_order": 3 }
]
Use increments of 10 or 100 for sort_order (0, 10, 20 or 0, 100, 200) to make it easier to insert new categories between existing ones.

Active/Inactive Categories

Use the is_active flag to temporarily hide categories without deleting them:
# Hide category from customers
curl -X PATCH https://api.restai.com/v1/menu/categories/{id} \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{ "isActive": false }'

# Show category again
curl -X PATCH https://api.restai.com/v1/menu/categories/{id} \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{ "isActive": true }'
Inactive categories and their items won’t appear in customer-facing interfaces, but remain accessible via the admin API.

Best Practices

  1. Keep names concise: Category names should be short and clear (e.g., “Entradas”, not “Entradas y Aperitivos Variados”)
  2. Use descriptions for detail: Put longer explanations in the description field
  3. Optimize images: Use compressed, web-optimized images for faster loading
  4. Logical ordering: Order categories in the sequence customers typically order (starters → mains → desserts → drinks)
  5. Consistent naming: Use consistent capitalization and language across all categories

Build docs developers (and LLMs) love