Skip to content

Navigation

Navigation menu management endpoints. Each menu is tied to a specific location (header, footer, sidebar, mobile) and contains a hierarchical list of items with multilingual labels.

Base path: /api/v1/navigation


Get Menu by Location

Returns the active menu for a given location. Intended for frontend navigation rendering — no authentication required.

GET /api/v1/navigation/location/{location}

Authentication: Not required

Path parameters

Parameter Type Description
location string One of: header, footer, sidebar, mobile

Response 200 OK — full NavigationMenuResponse object.

Errors

Status Description
404 Navigation menu for location not found

List Menus

GET /api/v1/navigation

Required permission: navigation:read

Response 200 OK

[
  {
    "id": "uuid",
    "slug": "main-menu",
    "location": "header",
    "is_active": true,
    "created_at": "2026-01-01T00:00:00Z",
    "updated_at": null
  }
]


Create Menu

POST /api/v1/navigation

Required permission: navigation:create

Request body

{
  "slug": "main-menu",
  "location": "header",
  "is_active": true
}

Field Type Required Constraints
slug string 2–255 characters, unique
location string One of: header, footer, sidebar, mobile, unique
is_active bool Default: true

Response 201 Created — full NavigationMenuResponse object.

Errors

Status Description
409 Navigation menu slug already exists
409 Navigation menu for location already exists

Get Menu

GET /api/v1/navigation/{id}

Required permission: navigation:read

Response 200 OK

{
  "id": "uuid",
  "slug": "main-menu",
  "location": "header",
  "is_active": true,
  "created_at": "2026-01-01T00:00:00Z",
  "updated_at": null,
  "items": [
    {
      "id": "uuid",
      "menu_id": "uuid",
      "parent_id": null,
      "type": "internal",
      "reference_type": "page",
      "reference_id": "uuid",
      "url": null,
      "order": 0,
      "is_active": true,
      "translations": [
        {
          "id": "uuid",
          "item_id": "uuid",
          "language_id": "uuid",
          "label": "About Us"
        }
      ],
      "children": [
        {
          "id": "uuid",
          "menu_id": "uuid",
          "parent_id": "uuid",
          "type": "external",
          "reference_type": null,
          "reference_id": null,
          "url": "https://example.com",
          "order": 0,
          "is_active": true,
          "translations": [],
          "children": []
        }
      ],
      "created_at": "2026-01-01T00:00:00Z",
      "updated_at": null
    }
  ]
}

Errors

Status Description
404 Navigation menu not found

Update Menu

PATCH /api/v1/navigation/{id}

Required permission: navigation:update

Request body — all fields optional

{
  "slug": "main-menu-updated",
  "is_active": false
}

Response 200 OK — updated NavigationMenuResponse object.

Errors

Status Description
404 Navigation menu not found
409 Navigation menu slug already exists

Delete Menu

DELETE /api/v1/navigation/{id}

Required permission: navigation:delete

Response 204 No Content

Warning

Deleting a menu permanently removes all its items and their translations.

Errors

Status Description
404 Navigation menu not found

Create Item

POST /api/v1/navigation/{id}/items

Required permission: navigation:update

Request body

{
  "parent_id": null,
  "type": "internal",
  "reference_type": "page",
  "reference_id": "uuid",
  "url": null,
  "order": 0,
  "is_active": true,
  "translations": [
    {
      "language_id": "uuid",
      "label": "About Us"
    }
  ]
}

Field Type Required Constraints
parent_id UUID Must exist in this menu
type string One of: internal, external, label
reference_type string ⚠️ Required for internalpage, post, category, tag
reference_id UUID ⚠️ Required for internal
url string ⚠️ Required for external, max 500 characters
order int Default: 0, min: 0
is_active bool Default: true
translations array List of language labels

Item type rules

Type reference_type reference_id url
internal ✅ Required ✅ Required
external ✅ Required
label

Response 200 OK — updated NavigationMenuResponse object.

Errors

Status Description
400 Invalid item type configuration
404 Navigation menu not found
404 Parent item not found in this menu
404 Language not found

Update Item

PATCH /api/v1/navigation/{id}/items/{item_id}

Required permission: navigation:update

Request body — all fields optional

{
  "parent_id": "uuid",
  "reference_type": "post",
  "reference_id": "uuid",
  "url": null,
  "order": 1,
  "is_active": false,
  "translations": [
    {
      "language_id": "uuid",
      "label": "Updated Label"
    }
  ]
}

translations is an optional list — if provided, each entry is upserted by the item_id + language_id combination. Existing translations for a given language will be updated; if no translation exists for that language, a new record will be created.

Response 200 OK — updated NavigationMenuResponse object.

Errors

Status Description
400 Item cannot be its own parent
400 Circular navigation hierarchy is not allowed
404 Navigation menu not found
404 Navigation item not found in this menu
404 Parent item not found in this menu
404 Language not found

Delete Item

DELETE /api/v1/navigation/{id}/items/{item_id}

Required permission: navigation:delete

Response 204 No Content

Warning

Deleting an item permanently removes all its children and their translations.

Errors

Status Description
404 Navigation menu not found
404 Navigation item not found in this menu

Reorder Items

Updates order and parent_id for multiple items in a single request. Allows full restructuring of the menu hierarchy in one call.

PATCH /api/v1/navigation/{id}/items/reorder

Required permission: navigation:update

Request body

{
  "items": [
    { "id": "uuid", "order": 0, "parent_id": null },
    { "id": "uuid", "order": 1, "parent_id": null },
    { "id": "uuid", "order": 0, "parent_id": "uuid" }
  ]
}

Response 200 OK — updated NavigationMenuResponse object.

Errors

Status Description
404 Navigation menu not found
404 Item not found in this menu