Skip to content

Calendar API — Entwickler-Referenz

REST-API fuer das Advanced Calendar Modul. Alle Endpunkte unter /api/platform/v1/calendar/.

Authentifizierung

Alle Endpunkte erfordern einen Bearer Token im Authorization Header. Sowohl Platform-JWT (Web-Client) als auch Customer-JWT (Portal) werden akzeptiert.

Authorization: Bearer {token}

Layer-Endpunkte

GET /calendar/layers

Gibt alle Kalender-Layer zurueck die der Benutzer sehen darf.

Admin/Portal-User: Sehen alle Layer des Tenants. Normale User: Sehen Layer 1 (Schule) + Layer fuer Spaces in denen sie Mitglied sind.

Response:

json
{
  "layers": [
    {
      "id": "cmngef4yw...",
      "tenantId": "cmneba...",
      "spaceId": null,
      "userId": null,
      "level": 1,
      "name": "Schulkalender",
      "color": "#3b82f6",
      "isPublic": false,
      "publicToken": null,
      "eventCount": 42,
      "subscribed": true,
      "createdAt": "2026-04-01T..."
    }
  ]
}

POST /calendar/layers

Erstellt einen neuen Layer.

Request Body:

json
{
  "spaceId": "Kollegium",
  "level": 2,
  "name": "Feiertage",
  "color": "#ef4444"
}
FeldTypPflichtBeschreibung
spaceIdstringNeinSpace-ID (null fuer Level 1)
levelnumberJa1=Schule, 2=Space, 3=Raum, 4=Nutzer
namestringJaName des Layers (max 255 Zeichen)
colorstringNeinHex-Farbe (Default: #3b82f6)

Level 1 kann nur von Admins erstellt werden.

PATCH /calendar/layers/:layerId

Aktualisiert einen Layer.

Request Body (alle optional):

json
{
  "name": "Neuer Name",
  "color": "#10b981",
  "isPublic": true
}

Bei isPublic: true wird automatisch ein publicToken generiert.

DELETE /calendar/layers/:layerId

Loescht einen Layer und alle zugehoerigen Events. HTTP 204.

POST /calendar/layers/:layerId/subscribe

Blendet einen Layer fuer den aktuellen Benutzer ein. HTTP 201.

DELETE /calendar/layers/:layerId/subscribe

Blendet einen Layer fuer den aktuellen Benutzer aus. HTTP 204.


Event-Endpunkte

GET /calendar/events

Gibt Events fuer die angegebenen Layer im Zeitraum zurueck.

Query-Parameter:

ParameterTypPflichtBeschreibung
fromISO 8601JaStartdatum
toISO 8601JaEnddatum
layersstringNeinKomma-getrennte Layer-IDs. Default: alle abonnierten Layer

Response:

json
{
  "events": [
    {
      "id": "cmnh...",
      "layerId": "cmngef...",
      "tenantId": "cmneba...",
      "uid": "abc123@prilog.chat",
      "title": "Lehrerkonferenz",
      "description": "Tagesordnung siehe Anhang",
      "location": "Aula",
      "dtstart": "2026-04-15T14:00:00.000Z",
      "dtend": "2026-04-15T16:00:00.000Z",
      "allDay": false,
      "rrule": null,
      "exdates": [],
      "status": "CONFIRMED",
      "transparency": "OPAQUE",
      "color": null,
      "categories": [],
      "organizerId": "@admin:schule.prilog.team",
      "attendees": [],
      "version": 1,
      "createdAt": "2026-04-01T...",
      "updatedAt": "2026-04-01T...",
      "layer": {
        "color": "#3b82f6",
        "name": "Schulkalender",
        "level": 1
      }
    }
  ]
}

POST /calendar/events

Erstellt ein neues Event.

Request Body:

json
{
  "layerId": "cmngef4yw...",
  "title": "Elternabend",
  "description": "Klasse 8a",
  "location": "Raum 201",
  "dtstart": "2026-04-20T18:00:00.000Z",
  "dtend": "2026-04-20T20:00:00.000Z",
  "allDay": false,
  "rrule": "FREQ=MONTHLY",
  "status": "CONFIRMED",
  "color": "#ef4444",
  "categories": ["eltern", "klasse8"],
  "attendees": ["@mueller:schule.prilog.team"]
}
FeldTypPflichtBeschreibung
layerIdstringJaZiel-Layer
titlestringJaTitel (max 500 Zeichen)
dtstartISO 8601JaStartzeit
dtendISO 8601NeinEndzeit
allDaybooleanNeinGanztaegig (Default: false)
descriptionstringNeinBeschreibung (max 10000 Zeichen)
locationstringNeinOrt (max 500 Zeichen)
rrulestringNeinWiederholungsregel (RFC 5545)
statusstringNeinTENTATIVE / CONFIRMED / CANCELLED
colorstringNeinUeberschreibt Layer-Farbe
categoriesstring[]NeinTags
attendeesstring[]NeinTeilnehmer (Matrix-User-IDs)

PUT /calendar/events/:eventId

Aktualisiert ein Event. Erfordert das version-Feld fuer Optimistic Locking.

Request Body:

json
{
  "title": "Elternabend (verschoben)",
  "dtstart": "2026-04-22T18:00:00.000Z",
  "version": 1
}

Bei Version-Konflikt: HTTP 409 mit Meldung "Termin wurde in der Zwischenzeit geaendert."

DELETE /calendar/events/:eventId

Loescht ein Event. HTTP 204.


iCal-Endpunkte

GET /calendar/ical/:layerId

Gibt den .ics-Feed eines Layers zurueck (authentifiziert).

Response Headers:

  • Content-Type: text/calendar; charset=utf-8
  • ETag: "{timestamp}"
  • Cache-Control: max-age=300

Unterstuetzt HTTP 304 Not Modified via If-None-Match Header.

GET /calendar/public/:token

Gibt den oeffentlichen .ics-Feed zurueck (kein Login noetig).

Der token wird automatisch generiert wenn ein Layer auf isPublic: true gesetzt wird.

Response Headers:

  • Content-Type: text/calendar; charset=utf-8
  • Access-Control-Allow-Origin: *

POST /calendar/import

Importiert eine .ics-Datei in einen Layer.

Request Body:

json
{
  "layerId": "cmngef4yw...",
  "icsContent": "BEGIN:VCALENDAR\r\nVERSION:2.0\r\n..."
}

Response:

json
{
  "imported": 15,
  "skipped": 3,
  "total": 18
}

Duplikate werden anhand der UID erkannt und uebersprungen.


Aufgaben-Kalender-Sync

Aufgaben aus dem Projekt-Modul werden automatisch mit dem Kalender synchronisiert:

  • Aufgabe mit Faelligkeitsdatum → CalendarEvent im "Aufgaben {Space}" Layer
  • Event-UID: task-{itemId}@prilog.chat
  • Ganztaegig von startDate bis dueDate
  • Status "done" → Event wird als CANCELLED markiert
  • Datum entfernt → Event wird geloescht
  • Sync passiert bei: Item Create, Item Update, Item Move

Layer-Hierarchie

LevelBezeichnungSichtbarkeitErstellt durch
1SchuleAlle im TenantSystem (automatisch)
2SpaceSpace-MitgliederAdmin oder System
3RaumSpace-MitgliederAdmin (zukuenftig)
4NutzerNur der Nutzer selbstNutzer (zukuenftig)

Layer 1 wird automatisch beim Aktivieren des Calendar-Moduls erstellt. Layer 2 wird automatisch bei jeder Space-Erstellung erstellt. "Aufgaben {Space}"-Layer werden vom Projekt-Modul erstellt.