HFU Digital Docs
StarPlan APIEndpoints

Catalog endpoints

Programs, semesters, courses, rooms, instructors, search, statistics

These are the read-only catalog endpoints. All are anonymous (no API key required) and rate-limited per Rate limits. Every successful response is wrapped in { "data": … }.

All ids are UUIDs. Filter parameters that take strings are matched case-insensitively via contains.

Programs

GET /v1/starplan/programs

Filters: search, degreeType, archived (true returns only inactive programs; default returns active ones).

{
  "data": [
    {
      "id": "8b7c…",
      "name": "Allgemeine Informatik",
      "shortName": "AIB",
      "degreeType": "B.Sc.",
      "facultyId": "f1…",
      "isActive": true,
      "createdAt": "2024-09-01T00:00:00.000Z",
      "updatedAt": "2026-04-12T08:13:42.117Z"
    }
  ]
}

GET /v1/starplan/programs/:id

Single program. 404 if unknown.

GET /v1/starplan/programs/:id/semesters

Semesters of a program, sorted by number.

{
  "data": [
    {
      "id": "se…",
      "programId": "8b7c…",
      "name": "Semester 1",
      "number": 1,
      "academicPeriodId": "ap…",
      "createdAt": "2024-09-01T00:00:00.000Z",
      "updatedAt": "2026-04-12T08:13:42.117Z"
    }
  ]
}

GET /v1/starplan/programs/:id/courses

All occurrences for every semester of the program (union across linked academic periods).

Semesters

GET /v1/starplan/semesters

Optional programId filter. Each entry includes a nested program: { id, name, shortName }.

GET /v1/starplan/semesters/:id

Single semester. 404 if unknown.

GET /v1/starplan/semesters/:id/courses

All occurrences (materialized timetable events) for the semester's academic period. Each entry has the shape:

{
  "id": "ev…",
  "summary": "Datenbanken 1",
  "startTime": "2026-04-22T08:00:00.000Z",
  "endTime":   "2026-04-22T09:30:00.000Z",
  "weekday": 3,
  "recurrenceRule": "FREQ=WEEKLY;COUNT=14",
  "course":     { "id": "co…", "name": "Datenbanken 1", "code": "DB1" },
  "room":       { "id": "ro…", "name": "F-007", "building": "F" },
  "instructor": { "id": "in…", "name": "Prof. Dr. Beispiel" },
  "semester":   { "id": "se…", "name": "Semester 3", "program": { "id": "8b7c…", "name": "Allgemeine Informatik" } }
}

weekday is the UTC day-of-week (0 = Sunday … 6 = Saturday). instructor is the first instructor on the event or null. recurrenceRule is an iCal RRULE string or null for one-off events.

Courses

GET /v1/starplan/courses

Filters: search (matches course name), periodId (academic period). Sorted alphabetically.

{
  "data": [
    {
      "id": "co…",
      "name": "Datenbanken 1",
      "code": "DB1",
      "parentId": null,
      "metadata": {}
    }
  ]
}

GET /v1/starplan/courses/:id

Single course. 404 if unknown.

Rooms

GET /v1/starplan/rooms

Filters: search (room name), building (exact match).

{
  "data": [
    { "id": "ro…", "name": "F-007", "building": "F", "campus": "Furtwangen", "capacity": 60, "tags": ["projector", "podium"] }
  ]
}

GET /v1/starplan/rooms/:id

Single room. 404 if unknown.

GET /v1/starplan/rooms/:id/schedule

Optional from and to (ISO 8601 instants). Defaults to now and now + 180 days.

{
  "data": {
    "room":   { "id": "ro…", "name": "F-007", "building": "F", "campus": "Furtwangen", "capacity": 60, "tags": [] },
    "period": { "from": "2026-04-26T12:00:00.000Z", "to": "2026-10-23T12:00:00.000Z" },
    "courses": [
      { "id": "ev…", "summary": "Datenbanken 1", "startTime": "2026-04-29T08:00:00.000Z", "endTime": "2026-04-29T09:30:00.000Z", "weekday": 3 }
    ]
  }
}

Instructors

GET /v1/starplan/instructors

Filter: search (instructor name).

{
  "data": [
    { "id": "in…", "name": "Prof. Dr. Beispiel", "email": "beispiel@hs-furtwangen.de", "tags": [] }
  ]
}

GET /v1/starplan/instructors/:id

Single instructor. 404 if unknown.

GET /v1/starplan/instructors/:id/courses

Returns the instructor plus all course occurrences they are assigned to. The shape is { instructor: {…}, data: [Occurrence, …] } — note that this endpoint does not double-wrap in data.

GET /v1/starplan/search?q=…&type=…

Multi-resource search. Requires q length ≥ 2 — shorter queries return all four buckets empty.

type is optional and one of course | room | instructor | program. Without it, all four are searched.

{
  "data": {
    "courses":     [{ "id": "co…", "name": "Datenbanken 1", "code": "DB1" }],
    "rooms":       [{ "id": "ro…", "name": "F-007", "building": "F" }],
    "instructors": [{ "id": "in…", "name": "Prof. Dr. Beispiel", "email": "…@hs-furtwangen.de" }],
    "programs":    [{ "id": "8b7c…", "name": "Allgemeine Informatik", "shortName": "AIB", "degreeType": "B.Sc." }]
  }
}

Each bucket caps at 20 results.

Statistics & sync status

GET /v1/starplan/statistics

Counts of active resources:

{ "data": { "programs": 42, "semesters": 250, "courses": 1893, "rooms": 110, "instructors": 287, "events": 12404 } }

programs counts only active programs; the other counters are unfiltered.

GET /v1/starplan/sync/status

State of the upstream sync job:

{
  "data": {
    "lastFetchedAt": "2026-04-26T11:45:00.000Z",
    "currentPu":     "abc123",
    "baseUrl":       "https://splan.hs-furtwangen.de/.../",
    "lastError": {
      "errorMessage": "…",
      "updatedAt":    "2026-04-26T11:45:00.000Z",
      "programId":    "8b7c…",
      "semesterId":   "se…"
    }
  }
}

lastError is null when the most recent sync iteration succeeded for every program/semester pair.

On this page