Get menu

http
GET /v1/menu

Returns the complete current (draft) state of the menu — categories, ingredients and all non-deleted products with their compositions and modifier groups. Use it to verify what a sync produced or to reconcile DuckHub against your POS before a cleanup.

Draft state, not the published snapshot

This endpoint reflects the menu as it is right now, including unpublished changes and products with menuVisible: false. What guests see is the latest publication snapshot.

Items are identified by externalId only (no internal ids). Items created manually in the DuckHub app have externalId: null.

Example#

bash
curl https://api.duck-hub.com/v1/menu \
  -H "Authorization: Bearer dk_live_your_api_key"

Response#

200 OK. All lists are sorted by sortOrder; priceMinor and priceAdjustment are integers in minor currency units:

json
{
  "generatedAt": "2026-07-05T12:00:00.000Z",
  "categories": [
    { "externalId": "cat-pizza", "name": "Pizza", "sortOrder": 1 }
  ],
  "ingredients": [
    { "externalId": "ing-mozzarella", "name": "Mozzarella", "sortOrder": 0 },
    { "externalId": "ing-olives", "name": "Olives", "sortOrder": 0 }
  ],
  "products": [
    {
      "externalId": "prod-margherita",
      "name": "Margherita",
      "description": "Tomato, mozzarella, basil",
      "priceMinor": 21500,
      "categoryExternalId": "cat-pizza",
      "sortOrder": 0,
      "menuVisible": true,
      "ingredients": [
        { "externalId": "ing-mozzarella", "name": "Mozzarella" }
      ],
      "modifierGroups": [
        {
          "name": "Extras",
          "type": "add_ingredients",
          "isRequired": false,
          "sortOrder": 0,
          "options": [
            {
              "ingredientExternalId": "ing-olives",
              "ingredientName": "Olives",
              "action": "add",
              "priceAdjustment": 2500,
              "sortOrder": 0
            }
          ]
        }
      ]
    }
  ]
}

Field-by-field details for every object are in the field reference.

Errors#