API Documentation

Base URL

/api

Authentication

Public read access for /api/menu. No authentication required.

GET /api/menu

Returns menu data. Defaults to the latest week if no query is provided.

curl -s https://your-domain.vercel.app/api/menu | jq

Response:

{
  "foodCourt": "Food Court 2",
  "week": "August 25 - 31, 2025",
  "menu": {
    "2025-08-25": {
      "day": "Monday",
      "meals": {
        "breakfast": { "name": "Happy Morning Breakfast", "startTime": "07:00", "endTime": "09:30", "items": ["..."] },
        "lunch": { "name": "Wholesome Lunch", "startTime": "11:45", "endTime": "14:15", "items": ["..."] },
        "snacks": { "name": "Refreshing Snacks", "startTime": "16:30", "endTime": "18:00", "items": ["..."] },
        "dinner": { "name": "Delicious Dinner", "startTime": "19:00", "endTime": "21:30", "items": ["..."] }
      }
    }
  }
}

Query parameters

  • ?week=August 25 - 31, 2025 — exact match on the week label.
  • ?weekStart=2025-08-25 — ISO date of the first day of the week.
  • ?date=2025-08-27 — returns only that specific day, in the same JSON shape.
curl -s 'https://your-domain.vercel.app/api/menu?date=2025-08-27' | jq

GET /api/history

Access historical menu data for previous weeks. All historical weeks are stored in Cloudflare R2 storage. Requires authentication.

List all weeks

Returns a summary of all available weeks with metadata:

curl -s https://your-domain.vercel.app/api/history | jq

Response:

{
  "weeks": [
    {
      "week": "August 18 - 24, 2025",
      "foodCourt": "Food Court 2",
      "startDate": "2025-08-18",
      "endDate": "2025-08-24",
      "numDays": 7
    },
    {
      "week": "August 25 - 31, 2025",
      "foodCourt": "Food Court 2",
      "startDate": "2025-08-25",
      "endDate": "2025-08-31",
      "numDays": 7
    }
  ]
}

Get specific week

Retrieve full menu data for a specific week using the weekStart parameter:

curl -s 'https://your-domain.vercel.app/api/history?weekStart=2025-08-18' | jq

Returns the same MenuData structure as /api/menu.

Query parameters

  • ?weekStart=2025-08-18 — ISO date of the first day of the week to retrieve.

Links

Errors

{
  "error": "Failed to retrieve menu data",
  "details": "..."
}

Notes

  • Excel files are parsed horizontally with fuzzy logic to separate meals per day.
  • JSON structure is validated using Zod schemas.
  • Processed JSON is stored locally (dev) and via Cloudflare R2 (prod).
  • Historical data is maintained in menu-history.json in Cloudflare R2 storage.
  • All weeks are stored and queryable via /api/menu (public) or /api/history (authenticated).
  • The latest week is cached separately in latest-menu.json for quick access.
  • Weeks are sorted by earliest date in ascending order.