API v3

JSON for the canteen menus on this site.

Endpoints

Method Path Returns
GET /api/v3/canteens Every canteen with a menu
GET /api/v3/canteens/{canteen_id} One canteen and its menu, week by week

Conventions

Method
Every endpoint is a GET.
Data
Menus come from Kanpla, as of the last fetch.
Dates
ISO 8601, YYYY-MM-DD.
Times
UTC, ISO 8601.
Success
200 with {"data": ...}
Bad request
400 for a ?week that is not an ISO week.
Not found
404 for an unknown canteen_id.

Error body

{"detail": "Canteen not found"}

GET /api/v3/canteens

Every canteen with a menu.

Fields

Field Type Meaning
canteen_id string The canteen's identifier; the {canteen_id} in the path below.
name string Display name.
provider string Where the menu comes from; kanpla.
Example response
{
  "data": [
    {
      "canteen_id": "jonsvollsgaten2",
      "name": "Jonsvollsgaten 2",
      "provider": "kanpla"
    }
  ]
}

GET /api/v3/canteens/{canteen_id}

One canteen and this week's menu. From Friday, next week's too, once Kanpla has published it.

Parameters

{canteen_id}
path; a canteen_id from the canteen list.
?week=YYYY-WW
query, optional; that ISO year and week alone, such as 2026-40. With no menu stored for it, days is empty and fetched_at null.

Fields

Also canteen_id, name and provider, as in the list.

Field Type Meaning
weeks object[] The weeks, oldest first.
weeks[].week_start string The week's Monday.
weeks[].week_number integer The ISO week number.
weeks[].fetched_at string | null The last update from Kanpla. Null before the first.
weeks[].days object[] The days with a menu: date, meals.
days[].meals object[] The day's dishes, in the canteen menu's order.
dish.name string The dish.
dish.description string | null More about the dish.
dish.title string | null Kanpla's name for the menu slot, as given, such as Dagens suppe.
dish.allergens string[] Kanpla's allergen keys, in English, such as fish.
dish.labels string[] Diets, such as pescatarian.
dish.pictograms string[] Contents, such as pork.
Example response
{
  "data": {
    "canteen_id": "jonsvollsgaten2",
    "name": "Jonsvollsgaten 2",
    "provider": "kanpla",
    "weeks": [
      {
        "week_start": "2026-09-28",
        "week_number": 40,
        "fetched_at": "2026-10-01T07:17:07+00:00",
        "days": [
          {
            "date": "2026-10-01",
            "meals": [
              {
                "name": "Fiskekaker med potet og hvitsaus",
                "description": "Fiskekaker med deilig saus, potet og salat",
                "title": "Dagens Varmrett",
                "allergens": ["fish", "milk"],
                "labels": ["pescatarian"],
                "pictograms": []
              },
              {
                "name": "Løksuppe med brød",
                "description": null,
                "title": "Dagens suppe",
                "allergens": [],
                "labels": [],
                "pictograms": []
              }
            ]
          }
        ]
      }
    ]
  }
}

Older versions

Both still answer. API v2 splits each day's dishes into hot and soup and has no title. API v1 gives this week only, with garnish for the description.