For developers

Developers

Heads Up offers free, read-only access to its kids'-program catalogue, one city at a time - the same public data shown on the site.

Base URL: /api/{city}
Read-onlyJSONCORS-enabled
GET/api/{city}/programs

Search and filter the program catalogue for one city. calgary is the only city currently covered.

Query params

  • categoryProgram category, e.g. swimming, camps, arts.
  • ageAge in years; matches programs whose age range includes it.
  • areaNeighbourhood id (UUID). A name or quadrant is ignored, not matched.
  • maxCostMaximum cost, in cents.
  • adaptiveSet to 1 to include only adaptive/inclusive programs.
  • qFree-text search over program name, category, venue, neighbourhood and description, falling back to a misspelling-tolerant match when nothing matches exactly.
  • cursorPagination cursor from a previous response's meta.next_cursor.

Example request

/api/calgary/programs?category=swimming&age=6

Example response

{
  "data": [
    {
      "id": "b3f1c2a0-...",
      "name": "Parent & Tot Swim",
      "category": "swimming",
      "age_min": 6,
      "age_max": 12,
      "cost_cents": 9000,
      "adaptive": false,
      "city": "calgary",
      "url": "https://headsup.kids/calgary/programs/parent-tot-swim-b3f1c2a0",
      "provider": { "name": "City of Calgary", "slug": "city-of-calgary" },
      "neighbourhood": { "name": "Beltline", "slug": "beltline" },
      "venue": { "name": "Repsol Sport Centre" }
    }
  ],
  "meta": { "total": 41, "next_cursor": "a1b2c3d4-5678-4e9f-a012-3456789abcde", "city": "calgary" }
}

Unknown or uncovered city (404)

{
  "error": {
    "code": "unknown_city",
    "message": "No published catalogue for \"seattle\"."
  }
}
GET/api/{city}/programs/{id}

Fetch a single program by id. Each registration carries opens_precision: on a "day" row the clock portion of registration_opens_at is a midnight placeholder and only the date is real.

Example request

/api/calgary/programs/b3f1c2a0-1234-4a5b-8c6d-9e0f1a2b3c4d

Example response

{
  "data": {
    "id": "b3f1c2a0-...",
    "name": "Parent & Tot Swim",
    "category": "swimming",
    "age_min": 6,
    "age_max": 12,
    "cost_cents": 9000,
    "adaptive": false,
    "city": "calgary",
    "url": "https://headsup.kids/calgary/programs/parent-tot-swim-b3f1c2a0",
    "provider": { "name": "City of Calgary", "slug": null },
    "neighbourhood": { "name": "Beltline", "slug": null },
    "description": "A parent-participation intro to the water.",
    "venue": {
      "name": "Repsol Sport Centre",
      "address": "2225 Macleod Trail S",
      "neighbourhood": "Beltline",
      "lat": 51.03,
      "lng": -114.06
    },
    "sessions": [
      {
        "starts_on": "2026-09-08",
        "ends_on": "2026-12-15",
        "start_time": "16:00:00",
        "end_time": "17:00:00"
      }
    ],
    "registrations": [
      {
        "season": "fall 2026",
        "preview_opens_at": null,
        "registration_opens_at": "2026-08-12T06:00:00Z",
        "opens_precision": "day",
        "registration_closes_at": null,
        "confidence": "confirmed",
        "audience": "public",
        "source_url": "https://example.com/registration"
      },
      {
        "season": "fall 2026",
        "preview_opens_at": null,
        "registration_opens_at": "2026-08-10T06:00:00Z",
        "opens_precision": "day",
        "registration_closes_at": null,
        "confidence": "confirmed",
        "audience": "member",
        "source_url": "https://example.com/registration"
      }
    ]
  }
}

Not found (404)

{
  "error": {
    "code": "not_found",
    "message": "No program with that id."
  }
}
GET/api/{city}/calendar

Upcoming registration-open dates for one city, soonest first. Read opens_precision before rendering a time: on a "day" row the clock portion of registration_opens_at is a midnight placeholder and only the date is real.

Query params

  • limitNumber of events to return. Default 200, max 500.

Example request

/api/calgary/calendar?limit=5

Example response

{
  "data": [
    {
      "id": "c4a2d3b1-...",
      "program_id": "b3f1c2a0-...",
      "program_name": "Parent & Tot Swim",
      "season": "Fall 2026",
      "registration_opens_at": "2026-08-15T14:00:00.000Z",
      "opens_precision": "minute",
      "confidence": "confirmed",
      "audience": "public",
      "source_url": "https://www.calgary.ca/..."
    }
  ],
  "meta": { "city": "calgary" }
}

The API is read-only and CORS-enabled. No authentication is required. There is no version segment: the shape below is the current and only contract, and a breaking change ships as a breaking change rather than behind a new prefix.