Skip to main content

Dishes

This section documents the dish bank endpoints of the MiseOS API.

The dish bank contains all approved dishes that can be reused when planning weekly menus.

Dishes typically originate from approved dish suggestions, but head chefs and sous chefs can also create dishes manually when needed.

Each dish stores:

  • Danish and optional English names and descriptions
  • associated allergens
  • the originating week and year
  • the kitchen station responsible for the dish

Only active dishes can be used when building weekly menus or ingredient requests.

Dish lifecycle
#

flowchart LR
    Suggestion["Dish Suggestion"] -->|Approved| Dish["Dish created in dish bank"]
    Dish -->|Used in| Menu["Weekly Menu"]
    Dish -->|Deactivate| Inactive["Inactive Dish"]

Endpoints
#

MethodURLAuth
GET/dishesHEAD_CHEF, SOUS_CHEF
GET/dishes/searchKITCHEN_STAFF
GET/dishes/availableHEAD_CHEF, SOUS_CHEF
GET/dishes/groupedHEAD_CHEF, SOUS_CHEF
GET/dishes/{id}KITCHEN_STAFF
POST/dishesHEAD_CHEF, SOUS_CHEF
PUT/dishes/{id}HEAD_CHEF, SOUS_CHEF
PATCH/dishes/{id}/activateHEAD_CHEF, SOUS_CHEF
PATCH/dishes/{id}/deactivateHEAD_CHEF, SOUS_CHEF
DELETE/dishes/{id}HEAD_CHEF, SOUS_CHEF

Response objects
#

The dish API returns several response structures depending on the endpoint.

Dish response object
#

Represents a complete dish from the dish bank.

Used by: GET /dishes, GET /dishes/{id}, POST /dishes, PUT /dishes/{id}, PATCH /dishes/{id}/activate, PATCH /dishes/{id}/deactivate

{
  "id": 1,
  "nameDA": "Røget Laks",
  "nameEN": "Smoked Salmon",
  "descriptionDA": "Laks med dildcreme og rugbrødschips",
  "descriptionEN": "Salmon with dill cream and rye bread chips",
  "station": { "id": 1, "name": "Cold Kitchen" },
  "createdBy": { "id": 1, "firstName": "Gordon", "lastName": "Ramsay" },
  "allergens": [
    { "id": 1, "nameDA": "Gluten", "nameEN": "Gluten", "displayNumber": 1 },
    { "id": 4, "nameDA": "Fisk", "nameEN": "Fish", "displayNumber": 4 }
  ],
  "active": true,
  "originWeek": 7,
  "originYear": 2026,
  "hasTranslations": true,
  "createdAt": "2026-02-15 12:00",
  "updatedAt": "2026-02-20 15:30"
}

DishOption response object
#

A lightweight representation used when selecting dishes for menus or browsing grouped lists.

Used by: GET /dishes/grouped, GET /dishes/available

{
  "dishId": 1,
  "dishName": "Røget Laks",
  "dishDescription": "Laks med dildcreme og rugbrødschips",
  "stationName": "Cold Kitchen",
  "isActive": true
}

AvailableDishes response object
#

Represents dishes available for building a specific weekly menu. Separates dishes created in the requested week (thisWeekDishes) from dishes already in the bank from previous weeks (fromDishBank).

Used by: GET /dishes/available

{
  "week": 20,
  "year": 2026,
  "thisWeekDishes": {
    "Cold Kitchen": [
      {
        "dishId": 1,
        "dishName": "Røget Laks",
        "dishDescription": "Laks med dildcreme og rugbrødschips",
        "stationName": "Cold Kitchen",
        "isActive": true
      }
    ]
  },
  "fromDishBank": {
    "Hot Kitchen": [
      {
        "dishId": 2,
        "dishName": "Bøf Bearnaise",
        "dishDescription": "Oksemørbrad med hjemmelavet bearnaise",
        "stationName": "Hot Kitchen",
        "isActive": true
      },
      {
        "dishId": 5,
        "dishName": "Stegt Flæsk",
        "dishDescription": "Med persillesovs og kartofler",
        "stationName": "Hot Kitchen",
        "isActive": true
      }
    ],
    "Pastry": [
      {
        "dishId": 9,
        "dishName": "Chokolademousse",
        "dishDescription": "Mørk chokolade med flødeskum",
        "stationName": "Pastry",
        "isActive": true
      }
    ]
  }
}

GET /dishes
#

Returns all dishes with optional filters. Only accessible to head chefs and sous chefs — for management and menu planning. Line cooks use GET /dishes/search.

Query parameters

ParameterTypeDescription
stationIdLongFilter by station
activeBooleanFilter by active status

Example request

curl -H "Authorization: Bearer <token>" \
  "https://miseos.corral.dk/api/v1/dishes?stationId=1&active=true"

Response 200 — array of dish objects.

[
  {
    "id": 1,
    "nameDA": "Røget Laks",
    "nameEN": "Smoked Salmon",
    "descriptionDA": "Laks med dildcreme og rugbrødschips",
    "descriptionEN": "Salmon with dill cream and rye bread chips",
    "station": { "id": 1, "name": "Cold Kitchen" },
    "createdBy": { "id": 1, "firstName": "Gordon", "lastName": "Ramsay" },
    "allergens": [
      { "id": 1, "nameDA": "Gluten", "nameEN": "Gluten", "displayNumber": 1 },
      { "id": 4, "nameDA": "Fisk", "nameEN": "Fish", "displayNumber": 4 }
    ],
    "active": true,
    "originWeek": 7,
    "originYear": 2026,
    "hasTranslations": true,
    "createdAt": "2026-02-15 12:00",
    "updatedAt": "2026-02-20 15:30"
  },
  {
    "id": 2,
    "nameDA": "Bøf Bearnaise",
    "nameEN": "Beef Bearnaise",
    "descriptionDA": "Oksemørbrad med hjemmelavet bearnaise",
    "descriptionEN": "Beef tenderloin with homemade bearnaise",
    "station": { "id": 2, "name": "Hot Kitchen" },
    "createdBy": { "id": 1, "firstName": "Gordon", "lastName": "Ramsay" },
    "allergens": [
      { "id": 2, "nameDA": "Æg", "nameEN": "Eggs", "displayNumber": 2 },
      { "id": 7, "nameDA": "Mælk", "nameEN": "Milk", "displayNumber": 7 }
    ],
    "active": true,
    "originWeek": 6,
    "originYear": 2026,
    "hasTranslations": true,
    "createdAt": "2026-02-10 12:00",
    "updatedAt": "2026-02-18 15:30"
  }
]

GET /dishes/search
#

Searches dishes by name in both Danish and English. Returns partial matches. Available to all kitchen staff.

Query parameters

ParameterTypeDescription
queryStringSearch term — minimum 2 characters

Example request

curl -H "Authorization: Bearer <token>" \
  "https://miseos.corral.dk/api/v1/dishes/search?query=laks"

Response 200 — array of dish objects.

Errors

StatusCause
400Query is blank or fewer than 2 characters

GET /dishes/available
#

Returns dishes available for a specific week’s menu, grouped by station. Separates new dishes from that week from the existing dish bank.

Query parameters

ParameterTypeDescription
weekIntegerISO week number (required)
yearIntegerYear (required)

Example request

curl -H "Authorization: Bearer <token>" \
  "https://miseos.corral.dk/api/v1/dishes/available?week=20&year=2026"

Response 200 — AvailableDishes object.


GET /dishes/grouped
#

Returns all active dishes grouped by station name. Intended for menu planning — a complete overview of what is available per station.

Example request

curl -H "Authorization: Bearer <token>" \
  "https://miseos.corral.dk/api/v1/dishes/grouped"

Response 200

{
  "Cold Kitchen": [
    {
      "dishId": 1,
      "dishName": "Røget Laks",
      "dishDescription": "Laks med dildcreme og rugbrødschips",
      "stationName": "Cold Kitchen",
      "isActive": true
    },
    {
      "dishId": 4,
      "dishName": "Roastbeef",
      "dishDescription": "Roastbeef med remoulade og sprøde løg",
      "stationName": "Cold Kitchen",
      "isActive": true
    }
  ],
  "Hot Kitchen": [
    {
      "dishId": 2,
      "dishName": "Bøf Bearnaise",
      "dishDescription": "Oksemørbrad med hjemmelavet bearnaise",
      "stationName": "Hot Kitchen",
      "isActive": true
    },
    {
      "dishId": 3,
      "dishName": "Tarteletter",
      "dishDescription": "Høns i asparges",
      "stationName": "Hot Kitchen",
      "isActive": true
    },
    {
      "dishId": 5,
      "dishName": "Stegt Flæsk",
      "dishDescription": "Med persillesovs og kartofler",
      "stationName": "Hot Kitchen",
      "isActive": true
    }
  ],
  "Pastry": [
    {
      "dishId": 9,
      "dishName": "Chokolademousse",
      "dishDescription": "Mørk chokolade med flødeskum",
      "stationName": "Pastry",
      "isActive": true
    }
  ]
}

GET /dishes/{id}
#

Returns a single dish by ID. Available to all kitchen staff.

Example request

curl -H "Authorization: Bearer <token>" \
  "https://miseos.corral.dk/api/v1/dishes/1"

Response 200 — dish object.

Errors

StatusCause
400ID is not a positive number
404Dish not found

POST /dishes
#

Creates a new dish manually. The dish is assigned the current week and year as its origin and is active by default.

Example request

curl -X POST \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "nameDA": "Grillet Kylling",
    "descriptionDA": "Serveret med citron og timian",
    "stationId": 2,
    "allergenIds": [1, 3]
  }' \
  "https://miseos.corral.dk/api/v1/dishes"

Request body

{
  "nameDA": "Grillet Kylling",
  "descriptionDA": "Serveret med citron og timian",
  "stationId": 2,
  "allergenIds": [1, 3]
}

allergenIds is optional — omit or send an empty array for a dish with no allergens.

Response 201 — created dish object.

Errors

StatusCause
404Station not found

PUT /dishes/{id}
#

Updates a dish. English fields are optional — set to null if no translation exists yet.

Example request

curl -X PUT \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "nameDA": "Grillet Kylling",
    "descriptionDA": "Serveret med citron og timian",
    "nameEN": "Grilled Chicken",
    "descriptionEN": "Served with lemon and thyme",
    "allergenIds": [1]
  }' \
  "https://miseos.corral.dk/api/v1/dishes/7"

Request body

{
  "nameDA": "Grillet Kylling",
  "descriptionDA": "Serveret med citron og timian",
  "nameEN": "Grilled Chicken",
  "descriptionEN": "Served with lemon and thyme",
  "allergenIds": [1]
}

Response 200 — updated dish object.

Errors

StatusCause
404Dish not found

PATCH /dishes/{id}/activate
#

Reactivates a previously deactivated dish. The dish becomes available again for menus and ingredient requests.

Example request

curl -X PATCH \
  -H "Authorization: Bearer <token>" \
  "https://miseos.corral.dk/api/v1/dishes/6/activate"

Response 200 — updated dish object with active: true.


PATCH /dishes/{id}/deactivate
#

Deactivates a dish. Deactivated dishes cannot be added to menus or ingredient requests but remain in the system for historical reference. Prefer deactivation over deletion when the dish has been used in menus.

Example request

curl -X PATCH \
  -H "Authorization: Bearer <token>" \
  "https://miseos.corral.dk/api/v1/dishes/6/deactivate"

Response 200 — updated dish object with active: false.


DELETE /dishes/{id}
#

Permanently deletes a dish. Fails if the dish is used in any weekly menu — use deactivate instead.

Example request

curl -X DELETE \
  -H "Authorization: Bearer <token>" \
  "https://miseos.corral.dk/api/v1/dishes/10"

Response 204 — no content.

Errors

StatusCause
404Dish not found
409Dish is used in one or more weekly menus