Skip to content

menu

← All modules

6 endpoints.

GET /api/v1/menu

Get Menu

The menu tree visible to the current user on the active site.

200 — Successful Response

json
{
  "items": {
    "properties": {
      "id": {
        "type": "integer",
        "title": "Id"
      },
      "title": {
        "type": "string",
        "title": "Title"
      },
      "url": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "type": "null"
          }
        ],
        "title": "Url"
      },
      "icon": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "type": "null"
          }
        ],
        "title": "Icon"
      },
      "app_slug": {
        "type": "string",
        "title": "App Slug"
      },
      "min_role": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "type": "null"
          }
        ],
        "title": "Min Role"
      },
      "sort_order": {
        "type": "integer",
        "title": "Sort Order"
      },
      "colour": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "type": "null"
          }
        ],
        "title": "Colour"
      },
      "children": {
        "items": {
          "$ref": "#/components/schemas/MenuItemOut"
        },
        "type": "array",
        "title": "Children"
      }
    },
    "type": "object",
    "required": [
      "id",
      "title",
      "app_slug",
      "sort_order"
    ],
    "title": "MenuItemOut"
  },
  "type": "array",
  "title": "Response Get Menu Api V1 Menu Get"
}

POST /api/v1/menu

Create Menu Item

Request body

json
{
  "properties": {
    "parent_id": {
      "anyOf": [
        {
          "type": "integer"
        },
        {
          "type": "null"
        }
      ],
      "title": "Parent Id"
    },
    "title": {
      "type": "string",
      "title": "Title"
    },
    "url": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Url"
    },
    "icon": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Icon"
    },
    "app_slug": {
      "type": "string",
      "title": "App Slug",
      "default": "system"
    },
    "min_role": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Min Role"
    },
    "sort_order": {
      "type": "integer",
      "title": "Sort Order",
      "default": 0
    },
    "active": {
      "type": "boolean",
      "title": "Active",
      "default": true
    }
  },
  "type": "object",
  "required": [
    "title"
  ],
  "title": "MenuItemIn"
}

201 — Successful Response

json
{
  "properties": {
    "id": {
      "type": "integer",
      "title": "Id"
    },
    "title": {
      "type": "string",
      "title": "Title"
    },
    "url": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Url"
    },
    "icon": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Icon"
    },
    "app_slug": {
      "type": "string",
      "title": "App Slug"
    },
    "min_role": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Min Role"
    },
    "sort_order": {
      "type": "integer",
      "title": "Sort Order"
    },
    "colour": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Colour"
    },
    "children": {
      "items": {
        "$ref": "#/components/schemas/MenuItemOut"
      },
      "type": "array",
      "title": "Children"
    }
  },
  "type": "object",
  "required": [
    "id",
    "title",
    "app_slug",
    "sort_order"
  ],
  "title": "MenuItemOut"
}

422 — Validation Error

json
{
  "properties": {
    "detail": {
      "items": {
        "properties": {
          "loc": {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "type": "array",
            "title": "Location"
          },
          "msg": {
            "type": "string",
            "title": "Message"
          },
          "type": {
            "type": "string",
            "title": "Error Type"
          }
        },
        "type": "object",
        "required": [
          "loc",
          "msg",
          "type"
        ],
        "title": "ValidationError"
      },
      "type": "array",
      "title": "Detail"
    }
  },
  "type": "object",
  "title": "HTTPValidationError"
}

PUT /api/v1/menu/{item_id}

Update Menu Item

Parameters

NameInRequiredTypeDescription
item_idpathyesinteger

Request body

json
{
  "properties": {
    "parent_id": {
      "anyOf": [
        {
          "type": "integer"
        },
        {
          "type": "null"
        }
      ],
      "title": "Parent Id"
    },
    "title": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Title"
    },
    "url": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Url"
    },
    "icon": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Icon"
    },
    "app_slug": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "App Slug"
    },
    "min_role": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Min Role"
    },
    "sort_order": {
      "anyOf": [
        {
          "type": "integer"
        },
        {
          "type": "null"
        }
      ],
      "title": "Sort Order"
    },
    "active": {
      "anyOf": [
        {
          "type": "boolean"
        },
        {
          "type": "null"
        }
      ],
      "title": "Active"
    }
  },
  "type": "object",
  "title": "MenuItemPatch"
}

200 — Successful Response

json
{
  "properties": {
    "id": {
      "type": "integer",
      "title": "Id"
    },
    "title": {
      "type": "string",
      "title": "Title"
    },
    "url": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Url"
    },
    "icon": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Icon"
    },
    "app_slug": {
      "type": "string",
      "title": "App Slug"
    },
    "min_role": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Min Role"
    },
    "sort_order": {
      "type": "integer",
      "title": "Sort Order"
    },
    "colour": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Colour"
    },
    "children": {
      "items": {
        "$ref": "#/components/schemas/MenuItemOut"
      },
      "type": "array",
      "title": "Children"
    }
  },
  "type": "object",
  "required": [
    "id",
    "title",
    "app_slug",
    "sort_order"
  ],
  "title": "MenuItemOut"
}

422 — Validation Error

json
{
  "properties": {
    "detail": {
      "items": {
        "properties": {
          "loc": {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "type": "array",
            "title": "Location"
          },
          "msg": {
            "type": "string",
            "title": "Message"
          },
          "type": {
            "type": "string",
            "title": "Error Type"
          }
        },
        "type": "object",
        "required": [
          "loc",
          "msg",
          "type"
        ],
        "title": "ValidationError"
      },
      "type": "array",
      "title": "Detail"
    }
  },
  "type": "object",
  "title": "HTTPValidationError"
}

DELETE /api/v1/menu/{item_id}

Delete Menu Item

Parameters

NameInRequiredTypeDescription
item_idpathyesinteger

200 — Successful Response

json
{
  "type": "object",
  "additionalProperties": true,
  "title": "Response Delete Menu Item Api V1 Menu  Item Id  Delete"
}

422 — Validation Error

json
{
  "properties": {
    "detail": {
      "items": {
        "properties": {
          "loc": {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "type": "array",
            "title": "Location"
          },
          "msg": {
            "type": "string",
            "title": "Message"
          },
          "type": {
            "type": "string",
            "title": "Error Type"
          }
        },
        "type": "object",
        "required": [
          "loc",
          "msg",
          "type"
        ],
        "title": "ValidationError"
      },
      "type": "array",
      "title": "Detail"
    }
  },
  "type": "object",
  "title": "HTTPValidationError"
}

POST /api/v1/menu/reorder

Reorder Menu

Persist a new top-to-bottom order for a parent's children by rewriting sort_order. Reorders siblings within that parent only — the top-level groups (apps) themselves are never touched here; their order comes from the Apps Library (POST /apps/reorder).

The client sends only the ids it can see (visibility is gated by installed apps + role). We renumber the parent's WHOLE sibling set so those submitted ids lead in the given order, and any sibling the client couldn't see keeps its relative position right after — so reordering a partial view never makes two siblings collide on the same sort_order or silently shuffles a hidden group into the middle of the visible ones.

The same order is ALWAYS mirrored onto every other site's menu (the menu is a single platform-wide structure), matched by a stable content key since ids differ per site. Sites that don't have the parent/items are skipped; the response reports how many sites were written.

Request body

json
{
  "properties": {
    "parent_id": {
      "type": "integer",
      "title": "Parent Id"
    },
    "ordered_ids": {
      "items": {
        "type": "integer"
      },
      "type": "array",
      "title": "Ordered Ids"
    }
  },
  "type": "object",
  "required": [
    "parent_id"
  ],
  "title": "ReorderIn"
}

200 — Successful Response

json
{
  "additionalProperties": true,
  "type": "object",
  "title": "Response Reorder Menu Api V1 Menu Reorder Post"
}

422 — Validation Error

json
{
  "properties": {
    "detail": {
      "items": {
        "properties": {
          "loc": {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "type": "array",
            "title": "Location"
          },
          "msg": {
            "type": "string",
            "title": "Message"
          },
          "type": {
            "type": "string",
            "title": "Error Type"
          }
        },
        "type": "object",
        "required": [
          "loc",
          "msg",
          "type"
        ],
        "title": "ValidationError"
      },
      "type": "array",
      "title": "Detail"
    }
  },
  "type": "object",
  "title": "HTTPValidationError"
}

POST /api/v1/menu/reset

Reset Menu

Wipe the active site's menu and rebuild the canonical defaults.

200 — Successful Response

json
{
  "additionalProperties": true,
  "type": "object",
  "title": "Response Reset Menu Api V1 Menu Reset Post"
}

Lubb ERP Documentation