\".",
"request_id": "req_…"
}
```
→ [Alle Fehlercodes](/api/errors/)
# not_found
> 404 · Diesen Endpunkt gibt es nicht.
**Diesen Endpunkt gibt es nicht.**
| | |
| ------------ | ---------------------------------- |
| HTTP-Status | `404` |
| `code` | `not_found` |
| Wiederholen? | Nein, erst die Anfrage korrigieren |
## Was das bedeutet
[Abschnitt betitelt „Was das bedeutet“](#was-das-bedeutet)
Pfad oder Methode existieren unter `/v1` nicht. Diesen Fehler siehst du nur mit gültigem Key; ohne Key antwortet die API mit `401 missing_api_key`.
## So behebst du es
[Abschnitt betitelt „So behebst du es“](#so-behebst-du-es)
Prüfe Pfad, Methode und Basis-URL (`https://api.kalender-sync.de/v1`). Alle Endpunkte stehen in der [OpenAPI-Datei](https://api.kalender-sync.de/v1/openapi.json).
## Beispiel
[Abschnitt betitelt „Beispiel“](#beispiel)
```json
{
"type": "https://docs.kalender-sync.de/en/api/errors/not_found",
"title": "Not found",
"status": 404,
"code": "not_found",
"detail": "No such endpoint.",
"request_id": "req_…"
}
```
→ [Alle Fehlercodes](/api/errors/)
# payload_too_large
> 413 · Der Request-Body ist zu groß.
**Der Request-Body ist zu groß.**
| | |
| ------------ | ---------------------------------- |
| HTTP-Status | `413` |
| `code` | `payload_too_large` |
| Wiederholen? | Nein, erst die Anfrage korrigieren |
## Was das bedeutet
[Abschnitt betitelt „Was das bedeutet“](#was-das-bedeutet)
JSON-Bodies dürfen bis 1 MB groß sein (auch beim Batch), Bild-Uploads etwas über 2 MB.
## So behebst du es
[Abschnitt betitelt „So behebst du es“](#so-behebst-du-es)
Teile große Batches auf, kürze lange Beschreibungen, oder verkleinere das Bild.
## Beispiel
[Abschnitt betitelt „Beispiel“](#beispiel)
```json
{
"type": "https://docs.kalender-sync.de/en/api/errors/payload_too_large",
"title": "The request body is too large",
"status": 413,
"code": "payload_too_large",
"request_id": "req_…"
}
```
→ [Alle Fehlercodes](/api/errors/)
# plan_required
> 403 · Für diesen Live-Kalender reicht der Tarif nicht.
**Für diesen Live-Kalender reicht der Tarif nicht.**
| | |
| ------------ | ---------------------------------- |
| HTTP-Status | `403` |
| `code` | `plan_required` |
| Wiederholen? | Nein, erst die Anfrage korrigieren |
## Was das bedeutet
[Abschnitt betitelt „Was das bedeutet“](#was-das-bedeutet)
Entweder versuchst du im Free-Tarif einen Live-Kalender anzulegen, oder dein Konto hat mehr Live-Kalender, als der Tarif umfasst (zum Beispiel nach einem Downgrade oder nach dem Test-Zeitraum). Im zweiten Fall laufen Feeds und Abo-Seiten weiter, nur Schreibzugriffe werden abgelehnt.
## So behebst du es
[Abschnitt betitelt „So behebst du es“](#so-behebst-du-es)
Teste mit einem Sandbox-Key (`ks_test_`), wechsle in einen größeren Tarif, oder lösche einen Live-Kalender. Sandbox-Kalender sind davon nie betroffen. → [Tarife und Limits](/abo-kalender/tarife/)
## Beispiel
[Abschnitt betitelt „Beispiel“](#beispiel)
```json
{
"type": "https://docs.kalender-sync.de/en/api/errors/plan_required",
"title": "The API key is not allowed to do this",
"status": 403,
"code": "plan_required",
"detail": "Live calendars need the Basic or Professional plan. The calendar stays subscribable; writes resume after an upgrade.",
"request_id": "req_…"
}
```
→ [Alle Fehlercodes](/api/errors/)
# rate_limited
> 429 · Zu viele Anfragen.
**Zu viele Anfragen.**
| | |
| ------------ | ------------------------ |
| HTTP-Status | `429` |
| `code` | `rate_limited` |
| Wiederholen? | Ja, nach einer Wartezeit |
## Was das bedeutet
[Abschnitt betitelt „Was das bedeutet“](#was-das-bedeutet)
Der Key hat mehr als 120 Anfragen in einem Fenster von 60 Sekunden geschickt, oder von deiner IP-Adresse kamen mehr als 600 Anfragen pro Minute.
## So behebst du es
[Abschnitt betitelt „So behebst du es“](#so-behebst-du-es)
Warte so viele Sekunden, wie der Header `Retry-After` angibt, und wiederhole dann. Nutze für viele Termine den [Batch](/api/batch/) (100 Operationen zählen als eine Anfrage). → [Limits](/api/limits/)
## Beispiel
[Abschnitt betitelt „Beispiel“](#beispiel)
```json
{
"type": "https://docs.kalender-sync.de/en/api/errors/rate_limited",
"title": "Too many requests",
"status": 429,
"code": "rate_limited",
"detail": "This key may send 120 requests per 60 seconds.",
"request_id": "req_…"
}
```
→ [Alle Fehlercodes](/api/errors/)
# sequence_mismatch
> 409 · Der Termin hat sich seit der übergebenen Sequence geändert.
**Der Termin hat sich seit der übergebenen Sequence geändert.**
| | |
| ------------ | ---------------------------------- |
| HTTP-Status | `409` |
| `code` | `sequence_mismatch` |
| Wiederholen? | Nein, erst die Anfrage korrigieren |
## Was das bedeutet
[Abschnitt betitelt „Was das bedeutet“](#was-das-bedeutet)
Du hast `If-Match` mit einer `sequence` geschickt, aber der Termin hat inzwischen eine andere, oder es gibt ihn noch gar nicht.
## So behebst du es
[Abschnitt betitelt „So behebst du es“](#so-behebst-du-es)
Lies den Termin neu (`GET`), führe die Änderungen zusammen und schreib mit der aktuellen `sequence`. Brauchst du keinen Schutz vor parallelen Änderungen, lass `If-Match` weg.
## Beispiel
[Abschnitt betitelt „Beispiel“](#beispiel)
```json
{
"type": "https://docs.kalender-sync.de/en/api/errors/sequence_mismatch",
"title": "Conflict",
"status": 409,
"code": "sequence_mismatch",
"detail": "The event changed since the sequence you sent.",
"request_id": "req_…"
}
```
→ [Alle Fehlercodes](/api/errors/)
# sync_completed
> 409 · Der Full Sync ist schon abgeschlossen.
**Der Full Sync ist schon abgeschlossen.**
| | |
| ------------ | ---------------------------------- |
| HTTP-Status | `409` |
| `code` | `sync_completed` |
| Wiederholen? | Nein, erst die Anfrage korrigieren |
## Was das bedeutet
[Abschnitt betitelt „Was das bedeutet“](#was-das-bedeutet)
Du hast einen Batch mit einer `sync_id` geschickt oder `complete` aufgerufen, nachdem der Sync bereits abgeschlossen war.
## So behebst du es
[Abschnitt betitelt „So behebst du es“](#so-behebst-du-es)
Für einen neuen Abgleich einen neuen Sync starten. Ein doppeltes `complete` nach einem Netzwerkfehler kannst du ignorieren: Der erste Aufruf war erfolgreich.
## Beispiel
[Abschnitt betitelt „Beispiel“](#beispiel)
```json
{
"type": "https://docs.kalender-sync.de/en/api/errors/sync_completed",
"title": "Conflict",
"status": 409,
"code": "sync_completed",
"detail": "This sync is already complete.",
"request_id": "req_…"
}
```
→ [Alle Fehlercodes](/api/errors/)
# sync_expired
> 409 · Der Full Sync ist abgelaufen.
**Der Full Sync ist abgelaufen.**
| | |
| ------------ | ---------------------------------- |
| HTTP-Status | `409` |
| `code` | `sync_expired` |
| Wiederholen? | Nein, erst die Anfrage korrigieren |
## Was das bedeutet
[Abschnitt betitelt „Was das bedeutet“](#was-das-bedeutet)
Ein Full Sync ist eine Stunde gültig. Danach nimmt er keine Batches mehr an und lässt sich nicht abschließen. Gelöscht wurde dabei nichts.
## So behebst du es
[Abschnitt betitelt „So behebst du es“](#so-behebst-du-es)
Starte einen neuen Sync und schick alle Termine erneut. Bei sehr vielen Terminen: Batches mit 100 Operationen nutzen und das [Rate Limit](/api/limits/) im Blick behalten.
## Beispiel
[Abschnitt betitelt „Beispiel“](#beispiel)
```json
{
"type": "https://docs.kalender-sync.de/en/api/errors/sync_expired",
"title": "Conflict",
"status": 409,
"code": "sync_expired",
"detail": "This sync expired after one hour. Start a new one.",
"request_id": "req_…"
}
```
→ [Alle Fehlercodes](/api/errors/)
# sync_not_found
> 404 · Kein Full Sync mit dieser ID für diesen Kalender.
**Kein Full Sync mit dieser ID für diesen Kalender.**
| | |
| ------------ | ---------------------------------- |
| HTTP-Status | `404` |
| `code` | `sync_not_found` |
| Wiederholen? | Nein, erst die Anfrage korrigieren |
## Was das bedeutet
[Abschnitt betitelt „Was das bedeutet“](#was-das-bedeutet)
Die `sync_id` existiert nicht oder gehört zu einem anderen Kalender.
## So behebst du es
[Abschnitt betitelt „So behebst du es“](#so-behebst-du-es)
Nutze die `sync_id` aus `POST …/syncs` für denselben Kalender. → [Full Sync](/api/full-sync/)
## Beispiel
[Abschnitt betitelt „Beispiel“](#beispiel)
```json
{
"type": "https://docs.kalender-sync.de/en/api/errors/sync_not_found",
"title": "Not found",
"status": 404,
"code": "sync_not_found",
"detail": "No sync with this id for this calendar.",
"request_id": "req_…"
}
```
→ [Alle Fehlercodes](/api/errors/)
# terms_required
> 403 · Für Live-Kalender fehlt deine Zustimmung zu den Zusatzbedingungen.
**Für Live-Kalender fehlt deine Zustimmung zu den Zusatzbedingungen.**
| | |
| ------------ | -------------------- |
| HTTP-Status | `403` |
| `code` | `terms_required` |
| Wiederholen? | Nein, erst zustimmen |
## Was das bedeutet
[Abschnitt betitelt „Was das bedeutet“](#was-das-bedeutet)
Bevor dein Konto den ersten Live-Kalender anlegt, stimmst du einmal den [Zusatzbedingungen für Abo-Kalender](https://kalender-sync.de/agb/#abo-kalender) (AGB Ziffer 14) und der [AVV-Ergänzung](https://kalender-sync.de/avv/) (Ziffer 17) zu. Das gilt für die API und für KI-Assistenten über MCP gleichermaßen. Sandbox-Kalender brauchen keine Zustimmung.
In den Einstellungen der App heißt derselbe Fall `TERMS_REQUIRED`: Ohne Haken lässt sich kein Live-Key erstellen.
## So behebst du es
[Abschnitt betitelt „So behebst du es“](#so-behebst-du-es)
Öffne in der App **Einstellungen › Entwickler / API**, setze den Haken bei den Zusatzbedingungen und erstelle dann den Live-Key. Der Link steht auch im Feld `detail`. Danach die Anfrage wiederholen. → [Tarife und Limits](/abo-kalender/tarife/)
## Beispiel
[Abschnitt betitelt „Beispiel“](#beispiel)
```json
{
"type": "https://docs.kalender-sync.de/en/api/errors/terms_required",
"title": "The API key is not allowed to do this",
"status": 403,
"code": "terms_required",
"detail": "Live calendars need consent to the subscribe-calendar terms (AGB section 14) and the AVV addendum (section 17). Accept them once in Kalender Sync under Settings › Developer / API: https://app.kalender-sync.de/settings/api",
"request_id": "req_…"
}
```
→ [Alle Fehlercodes](/api/errors/)
# unsupported_image_type
> 415 · Das Bild ist kein PNG, JPEG oder WebP.
**Das Bild ist kein PNG, JPEG oder WebP.**
| | |
| ------------ | ---------------------------------- |
| HTTP-Status | `415` |
| `code` | `unsupported_image_type` |
| Wiederholen? | Nein, erst die Anfrage korrigieren |
## Was das bedeutet
[Abschnitt betitelt „Was das bedeutet“](#was-das-bedeutet)
Wir prüfen das Format am Inhalt der Datei, nicht am Content-Type. SVG, GIF, HEIC und andere Formate werden abgelehnt. SVG kann Skripte enthalten.
## So behebst du es
[Abschnitt betitelt „So behebst du es“](#so-behebst-du-es)
Konvertiere das Bild in PNG, JPEG oder WebP.
## Beispiel
[Abschnitt betitelt „Beispiel“](#beispiel)
```json
{
"type": "https://docs.kalender-sync.de/en/api/errors/unsupported_image_type",
"title": "Unsupported media type",
"status": 415,
"code": "unsupported_image_type",
"detail": "Use PNG, JPEG or WebP. SVG is not accepted.",
"request_id": "req_…"
}
```
→ [Alle Fehlercodes](/api/errors/)
# unsupported_media_type
> 415 · Der Content-Type wird an diesem Endpunkt nicht angenommen.
**Der Content-Type wird an diesem Endpunkt nicht angenommen.**
| | |
| ------------ | ---------------------------------- |
| HTTP-Status | `415` |
| `code` | `unsupported_media_type` |
| Wiederholen? | Nein, erst die Anfrage korrigieren |
## Was das bedeutet
[Abschnitt betitelt „Was das bedeutet“](#was-das-bedeutet)
JSON-Endpunkte erwarten `Content-Type: application/json`. Bild-Uploads erwarten `image/png`, `image/jpeg`, `image/webp` oder `application/octet-stream`.
## So behebst du es
[Abschnitt betitelt „So behebst du es“](#so-behebst-du-es)
Setze den passenden Header. Mit curl: `-H "Content-Type: application/json"` für JSON.
## Beispiel
[Abschnitt betitelt „Beispiel“](#beispiel)
```json
{
"type": "https://docs.kalender-sync.de/en/api/errors/unsupported_media_type",
"title": "Unsupported media type",
"status": 415,
"code": "unsupported_media_type",
"request_id": "req_…"
}
```
→ [Alle Fehlercodes](/api/errors/)
# Termine und Wiederholungen
> Termine per PUT unter deiner eigenen ID schreiben. Alle Felder, Zeiten und Zeitzonen, ganztägige Termine, RRULE-Serien, Ausnahmen, geänderte Einzeltermine und Mapping-Beispiele für typische Plugin-Felder.
Ein Termin ist ein einzelner Termin oder eine ganze Serie. Du adressierst ihn mit deiner eigenen **`external_id`**, zum Beispiel der Post-ID aus WordPress. Eine ID von uns musst du nicht speichern.
## Termin anlegen oder ändern
[Abschnitt betitelt „Termin anlegen oder ändern“](#termin-anlegen-oder-ändern)
```plaintext
PUT /v1/publisher/calendars/{calendar_id}/events/{external_id}
```
```bash
curl -X PUT https://api.kalender-sync.de/v1/publisher/calendars/$KS_CAL/events/wp-1482 \
-H "Authorization: Bearer $KS_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Sunset Yoga im Park",
"description": "Bring eine Matte mit. Für Mitglieder kostenlos.
",
"location": "Riverside Park, Steg 2, Berlin",
"url": "https://example.org/kurse/sunset-yoga/",
"start": "2026-11-12T18:00:00",
"end": "2026-11-12T19:30:00",
"timezone": "Europe/Berlin",
"status": "confirmed",
"categories": ["Outdoor"],
"metadata": { "post_id": 1482 }
}'
```
`external_id` darf 1 bis 128 Zeichen lang sein: Buchstaben, Ziffern und `.` `_` `:` `-`. Bewährt hat sich ein Präfix, etwa `wp-1482`.
**Antwort:** `201 Created` beim ersten Schreiben, `200 OK` bei einer Änderung.
```json
{
"external_id": "wp-1482",
"calendar_id": "cal_XXXXXXXXXXXX",
"sequence": 0,
"created_at": "2026-11-03T14:05:40.000Z",
"updated_at": "2026-11-03T14:05:40.000Z",
"event": {
"title": "Sunset Yoga im Park",
"all_day": false,
"start": "2026-11-12T18:00:00",
"end": "2026-11-12T19:30:00",
"timezone": "Europe/Berlin",
"status": "confirmed",
"show_as": "free",
"categories": ["Outdoor"],
"description": "Bring eine Matte mit. Für Mitglieder kostenlos.",
"location": "Riverside Park, Steg 2, Berlin",
"url": "https://example.org/kurse/sunset-yoga/",
"metadata": { "post_id": 1482 }
},
"changed": true
}
```
* `event` ist der Termin so, wie wir ihn gespeichert haben: Zeiten als lokale Zeit in `timezone`, HTML als Text.
* `sequence` zählt jede echte Änderung hoch.
* Schickst du denselben Termin noch einmal, antwortet die API mit `200` und **`"changed": false`**. Es wird nichts geschrieben, der Feed bleibt unverändert. Du kannst also bei jedem Speichern in deinem System einfach `PUT` aufrufen.
* `PUT` ersetzt den ganzen Termin. Felder, die du weglässt, sind danach leer bzw. auf dem Standardwert.
### Optimistisches Sperren mit `If-Match`
[Abschnitt betitelt „Optimistisches Sperren mit If-Match“](#optimistisches-sperren-mit-if-match)
Optional schickst du die zuletzt gesehene `sequence` mit:
```plaintext
If-Match: "3"
```
Hat sich der Termin inzwischen geändert (oder gibt es ihn noch nicht), kommt `409` [`sequence_mismatch`](/api/errors/sequence_mismatch/) statt eines Überschreibens.
## Felder
[Abschnitt betitelt „Felder“](#felder)
| Feld | Regeln | Standard |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- |
| `title` | Pflicht, 1 bis 255 Zeichen | |
| `start` | Pflicht. Datum oder Datum mit Uhrzeit, siehe [Zeiten](#zeiten-und-zeitzonen) | |
| `end` | optional. Bei Terminen mit Uhrzeit nicht vor `start`; bei ganztägigen Terminen **exklusiv** | `start` + `default_duration` des Kalenders bzw. ein Tag |
| `timezone` | IANA-Name, z. B. `Europe/Berlin` | Zeitzone des Kalenders |
| `all_day` | `true` oder `false` | `true`, wenn `start` ein reines Datum ist |
| `description` | Text oder HTML, bis 65.536 Zeichen. HTML wird zu Text; Links bleiben als `Text (URL)` erhalten. Gespeichert werden höchstens 8.000 Zeichen. | |
| `location` | bis 500 Zeichen | |
| `url` | `https://`-URL, bis 2.000 Zeichen. Wird in Apps als Link gezeigt und zusätzlich an die Beschreibung angehängt. | |
| `status` | `confirmed`, `tentative` oder `cancelled` | `confirmed` |
| `show_as` | `free` oder `busy`: ob der Termin bei Abonnenten als belegt gilt | `free` |
| `categories` | bis 10 Einträge à 1 bis 50 Zeichen | `[]` |
| `recurrence` | Serie, siehe [Wiederholungen](#wiederholungen) | |
| `metadata` | Beliebiges JSON-Objekt bis 2 KB. Kommt in API-Antworten zurück, erscheint aber nie im Feed oder auf der Abo-Seite. | |
`show_as` steht standardmäßig auf `free`: Öffentliche Termine sollen den Kalender deiner Abonnenten nicht als belegt markieren.
Ein abgesagter Termin (`"status": "cancelled"`) bleibt im Feed und ist dort als abgesagt markiert; wie das aussieht, hängt von der App ab. Soll er ganz verschwinden, lösche ihn.
## Zeiten und Zeitzonen
[Abschnitt betitelt „Zeiten und Zeitzonen“](#zeiten-und-zeitzonen)
| `start` / `end` | Bedeutung |
| ----------------------------------------------------------- | ------------------------------------------------------------------------ |
| `"2026-11-12T18:00:00"` | Lokale Zeit in `timezone` (bzw. der Zeitzone des Kalenders). Empfohlen. |
| `"2026-11-12T17:00:00Z"` oder `"2026-11-12T18:00:00+01:00"` | Zeitpunkt mit Offset. Wird in `timezone` umgerechnet und so gespeichert. |
| `"2026-11-12"` | Reines Datum: ganztägiger Termin. |
Lokale Zeit plus IANA-Zeitzone ist der sicherste Weg: Sommer- und Winterzeit stimmen dann auch bei Serien über die Zeitumstellung hinweg.
**Ganztägige Termine:** `end` ist exklusiv. Ein Termin nur am 12. November hat `"start": "2026-11-12"` und `"end": "2026-11-13"` oder gar kein `end`. Ein dreitägiges Festival vom 12. bis 14. November hat `"end": "2026-11-15"`.
## Wiederholungen
[Abschnitt betitelt „Wiederholungen“](#wiederholungen)
```json
{
"title": "Morning Flow",
"start": "2026-11-03T07:30:00",
"end": "2026-11-03T08:30:00",
"timezone": "Europe/Berlin",
"recurrence": {
"rules": ["FREQ=WEEKLY;BYDAY=TU;UNTIL=20270330"],
"except_dates": ["2026-12-22", "2026-12-29"],
"overrides": [
{
"original_start": "2026-11-17T07:30:00",
"start": "2026-11-17T08:00:00",
"end": "2026-11-17T09:00:00",
"location": "Studio 2"
},
{ "original_start": "2026-12-01T07:30:00", "status": "cancelled" }
]
}
}
```
| Feld | Regeln |
| -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `rules` | 1 bis 5 RRULE-Strings nach RFC 5545, je bis 500 Zeichen. Das Präfix `RRULE:` ist optional. Mehrere Regeln werden im Feed zu getrennten Serien. |
| `except_dates` | bis 1.000 Termine, die ausfallen und spurlos verschwinden. Ein Datum genügt; bei Serien mit Uhrzeit ist damit der Termin an diesem Tag gemeint. |
| `overrides` | bis 500 geänderte Einzeltermine, siehe unten. |
**Erlaubte RRULE-Teile:** `FREQ` (`DAILY`, `WEEKLY`, `MONTHLY`, `YEARLY`), `INTERVAL` (1 bis 1.000), `COUNT` (1 bis 1.000), `UNTIL`, `BYDAY`, `BYMONTHDAY`, `BYMONTH`, `BYSETPOS`, `WKST`. `COUNT` und `UNTIL` schließen sich aus. Andere Teile wie `BYHOUR` oder `FREQ=HOURLY` werden mit `unsupported_rrule` abgelehnt.
**`UNTIL`** darf `YYYYMMDD`, `YYYYMMDDTHHMMSS` (lokale Zeit in der Zeitzone des Termins) oder `YYYYMMDDTHHMMSSZ` (UTC) sein. Wir rechnen es so um, wie RFC 5545 es verlangt. Ein reines Datum bei einem Termin mit Uhrzeit heißt „bis einschließlich diesen Tag“.
### Einzeltermine ändern: `overrides`
[Abschnitt betitelt „Einzeltermine ändern: overrides“](#einzeltermine-ändern-overrides)
* `original_start` bezeichnet den Termin so, wie die Regel ihn erzeugt, in der Zeitzone des Termins (bei ganztägigen Serien ein Datum).
* Ändern kannst du `start`, `end`, `title`, `description`, `location`, `url` und `status`. Weggelassene Felder übernehmen den Wert der Serie.
* `"status": "cancelled"` sagt nur diesen einen Termin ab. Soll er spurlos verschwinden, nimm stattdessen `except_dates`.
* Overrides sind Teil des Termins: Jedes `PUT` schickt die **vollständige** Liste. Ein Override, den du weglässt, fällt auf die Serie zurück.
* Jeder Termin der Serie darf nur einmal überschrieben werden (sonst `duplicate_override`).
## Mapping typischer Plugin-Felder
[Abschnitt betitelt „Mapping typischer Plugin-Felder“](#mapping-typischer-plugin-felder)
So bildest du übliche Felder eines Event-Plugins (WordPress und ähnliche) ab:
| Im Plugin | In der API |
| ------------------------------------------ | ------------------------------------------------------------------------- |
| Post-ID | `external_id`, z. B. `"wp-1482"` |
| Titel | `title` |
| Inhalt / Beschreibung (HTML) | `description`. HTML geht direkt; besser ist ein kurzer Auszug plus `url`. |
| Permalink der Veranstaltung | `url` |
| Veranstaltungsort, Adresse | `location`, z. B. `"Studio am Fluss, Hauptstraße 5, Berlin"` |
| Startdatum + Startzeit | `start`: `"2026-11-12T18:00:00"` |
| Enddatum + Endzeit | `end`: `"2026-11-12T19:30:00"` |
| Zeitzone der Website (`timezone_string`) | `timezone` am Kalender, nur bei Abweichung am Termin |
| „Ganztägig“ angehakt | `start`/`end` als reines Datum, `end` + 1 Tag |
| Kategorien, Schlagwörter | `categories` |
| Status „abgesagt“ | `"status": "cancelled"` |
| Status „vorläufig“ | `"status": "tentative"` |
| Beitrag in den Papierkorb, Entwurf, privat | `DELETE` auf den Termin |
| Eigene Felder (Preis, Ticket-ID …) | `metadata` (nur für dich) oder als Text in `description` (für Abonnenten) |
Wiederholungseinstellungen:
| Einstellung im Plugin | RRULE |
| -------------------------------------------- | ---------------------------------------------- |
| Täglich / wöchentlich / monatlich / jährlich | `FREQ=DAILY` / `WEEKLY` / `MONTHLY` / `YEARLY` |
| Alle 2 Wochen | `FREQ=WEEKLY;INTERVAL=2` |
| Dienstags und donnerstags | `FREQ=WEEKLY;BYDAY=TU,TH` |
| Jeden zweiten Montag im Monat | `FREQ=MONTHLY;BYDAY=2MO` |
| Letzter Freitag im Monat | `FREQ=MONTHLY;BYDAY=-1FR` |
| Am 15. jedes Monats | `FREQ=MONTHLY;BYMONTHDAY=15` |
| Endet nach 10 Terminen | `;COUNT=10` |
| Endet am 25. März 2027 | `;UNTIL=20270325` |
| Ausgenommene Tage (Ferien, Feiertage) | `recurrence.except_dates` |
| Einzelner Termin verschoben | `recurrence.overrides` |
Für PHP baut und prüft die MIT-lizenzierte Bibliothek [rlanvin/php-rrule](https://github.com/rlanvin/php-rrule) solche Regeln.
## Termin lesen
[Abschnitt betitelt „Termin lesen“](#termin-lesen)
```bash
curl https://api.kalender-sync.de/v1/publisher/calendars/$KS_CAL/events/wp-1482 -H "Authorization: Bearer $KS_KEY"
```
Gibt es den Termin nicht: `404` [`event_not_found`](/api/errors/event_not_found/).
## Termine auflisten
[Abschnitt betitelt „Termine auflisten“](#termine-auflisten)
```bash
curl "https://api.kalender-sync.de/v1/publisher/calendars/$KS_CAL/events?limit=100" -H "Authorization: Bearer $KS_KEY"
```
| Parameter | Bedeutung |
| --------------- | ----------------------------------------------------------------------------------------------- |
| `limit` | 1 bis 100, Standard 100 |
| `cursor` | `next_cursor` der vorigen Seite |
| `updated_since` | ISO-Zeitpunkt mit Offset, z. B. `2026-11-01T00:00:00Z`: nur Termine, die danach geändert wurden |
Die Antwort enthält `data` (Termine wie oben) und `next_cursor` (`null` auf der letzten Seite). Sortiert wird nach letzter Änderung, sodass `updated_since` plus Cursor jede Änderung genau einmal liefert. Ein ungültiger Cursor ergibt `400` [`invalid_cursor`](/api/errors/invalid_cursor/).
## Termin löschen
[Abschnitt betitelt „Termin löschen“](#termin-löschen)
```bash
curl -X DELETE https://api.kalender-sync.de/v1/publisher/calendars/$KS_CAL/events/wp-1482 -H "Authorization: Bearer $KS_KEY"
```
Antwort immer `204 No Content`, auch wenn der Termin schon weg war. Wiederholungen sind also unbedenklich.
## Validierungsfehler
[Abschnitt betitelt „Validierungsfehler“](#validierungsfehler)
Ungültige Termine werden komplett abgelehnt, mit `400` [`invalid_request`](/api/errors/invalid_request/) und **allen** Problemen auf einmal in `errors`:
```json
{
"type": "https://docs.kalender-sync.de/en/api/errors/invalid_request",
"title": "The request is invalid",
"status": 400,
"code": "invalid_request",
"request_id": "req_…",
"errors": [
{ "field": "end", "code": "end_before_start", "message": "end must not be before start." },
{ "field": "recurrence.rules[0]", "code": "unsupported_rrule", "message": "BYHOUR is not supported." }
]
}
```
| `errors[].code` | Bedeutung |
| -------------------- | ------------------------------------------------------------------- |
| `invalid_timezone` | Unbekannte Zeitzone |
| `invalid_date` | Datum unlesbar (ganztägige Termine, `except_dates`) |
| `invalid_datetime` | Datum mit Uhrzeit unlesbar, oder ein Override passt nicht zur Serie |
| `end_before_start` | `end` liegt vor `start` (ganztägig: nicht danach) |
| `invalid_rrule` | Regel syntaktisch falsch, z. B. `COUNT` und `UNTIL` zusammen |
| `unsupported_rrule` | Regelteil oder Frequenz wird nicht unterstützt |
| `duplicate_override` | Ein Einzeltermin wurde doppelt überschrieben |
| `too_large` | `metadata` größer als 2 KB |
Verstöße gegen das Schema (fehlendes Pflichtfeld, unbekanntes Feld, zu langer Text) tragen den Code des Validators, z. B. `invalid_type`, `too_big` oder `unrecognized_keys`.
Weitere mögliche Fehler beim Schreiben: [`event_limit_reached`](/api/errors/event_limit_reached/), [`calendar_not_found`](/api/errors/calendar_not_found/), [`plan_required`](/api/errors/plan_required/), [`calendar_blocked`](/api/errors/calendar_blocked/).
# Full Sync
> Den Abo-Kalender vollständig mit deinem System abgleichen. Sync starten, alle Termine per Batch schicken, abschließen. Was nicht bestätigt wurde, wird gelöscht, mit Schutz vor versehentlichem Leeren.
War dein Plugin eine Zeit lang aus oder ist eine Anfrage verloren gegangen, bringt ein **Full Sync** den Kalender wieder auf den Stand deines Systems. Empfehlung: beim ersten Verbinden und danach einmal täglich, zum Beispiel per WP-Cron.
## Ablauf
[Abschnitt betitelt „Ablauf“](#ablauf)
**1. Sync starten**
```bash
curl -X POST https://api.kalender-sync.de/v1/publisher/calendars/$KS_CAL/syncs \
-H "Authorization: Bearer $KS_KEY"
```
```json
{ "sync_id": "sync_XXXXXXXXXXXXXXXX", "expires_at": "2026-11-03T15:02:11.000Z" }
```
Ein Sync ist **eine Stunde** gültig.
**2. Alle aktuellen Termine schicken**
Schick jeden Termin, den es in deinem System gibt, per [Batch](/api/batch/) mit der `sync_id`:
```bash
curl https://api.kalender-sync.de/v1/publisher/calendars/$KS_CAL/events/batch \
-H "Authorization: Bearer $KS_KEY" \
-H "Content-Type: application/json" \
-d '{
"sync_id": "sync_XXXXXXXXXXXXXXXX",
"operations": [
{ "method": "PUT", "external_id": "wp-1482", "event": { "title": "Sunset Yoga", "start": "2026-11-12T18:00:00" } },
{ "method": "PUT", "external_id": "wp-1490", "event": { "title": "Yin Yoga", "start": "2026-11-13T18:30:00" } }
]
}'
```
Unveränderte Termine kosten dabei nichts: Sie werden nur als bestätigt markiert, nicht neu geschrieben. Die `sync_id` gibt es nur im Batch, nicht beim Einzel-PUT.
**3. Sync abschließen**
```bash
curl -X POST https://api.kalender-sync.de/v1/publisher/calendars/$KS_CAL/syncs/sync_XXXXXXXXXXXXXXXX/complete \
-H "Authorization: Bearer $KS_KEY"
```
```json
{ "sync_id": "sync_XXXXXXXXXXXXXXXX", "deleted": 3, "remaining": 42 }
```
Dabei werden alle Termine gelöscht, die während des Syncs **nicht** geschickt wurden. Termine, die du während des Syncs außerhalb davon geschrieben hast (zum Beispiel ein normales Speichern auf der Website), bleiben erhalten.
## Schutz vor versehentlichem Leeren
[Abschnitt betitelt „Schutz vor versehentlichem Leeren“](#schutz-vor-versehentlichem-leeren)
Würde das Abschließen **mehr als die Hälfte** der Termine löschen, lehnt die API mit `409` [`large_delete`](/api/errors/large_delete/) ab. Ein halb fertiger Export soll nie einen Kalender mit tausenden Abonnenten leeren.
Ist das Löschen gewollt, bestätige es:
```bash
curl -X POST https://api.kalender-sync.de/v1/publisher/calendars/$KS_CAL/syncs/sync_XXXXXXXXXXXXXXXX/complete \
-H "Authorization: Bearer $KS_KEY" \
-H "Content-Type: application/json" \
-d '{ "confirm_large_delete": true }'
```
## Fehler
[Abschnitt betitelt „Fehler“](#fehler)
| Code | Wann |
| ----------------------------------------------- | ---------------------------------------------- |
| [`sync_not_found`](/api/errors/sync_not_found/) | Die `sync_id` gehört nicht zu diesem Kalender. |
| [`sync_expired`](/api/errors/sync_expired/) | Die Stunde ist um. Starte einen neuen Sync. |
| [`sync_completed`](/api/errors/sync_completed/) | Der Sync wurde schon abgeschlossen. |
| [`large_delete`](/api/errors/large_delete/) | Mehr als die Hälfte würde gelöscht. |
# Idempotenz
> Anfragen sicher wiederholen. PUT und DELETE auf Termine sind idempotent, Kalender legst du mit Idempotency-Key an.
Netzwerke sind unzuverlässig. Bekommst du auf eine Anfrage keine Antwort, sollst du sie einfach wiederholen können, ohne doppelte Kalender oder Termine zu erzeugen.
## Termine: von Haus aus idempotent
[Abschnitt betitelt „Termine: von Haus aus idempotent“](#termine-von-haus-aus-idempotent)
* **`PUT` auf einen Termin** schreibt den Termin unter deiner `external_id`. Doppelt geschickt ergibt das denselben Termin. Ist nichts anders als vorher, kommt `"changed": false`, und nichts wird geschrieben.
* **`DELETE` auf einen Termin** antwortet immer `204`, auch wenn der Termin schon gelöscht war.
* **Batch** besteht aus `PUT` und `DELETE` und lässt sich deshalb ebenfalls komplett wiederholen.
## Kalender anlegen: `Idempotency-Key`
[Abschnitt betitelt „Kalender anlegen: Idempotency-Key“](#kalender-anlegen-idempotency-key)
`POST /v1/publisher/calendars` legt bei jedem Aufruf einen neuen Kalender an. Schick deshalb einen eindeutigen Header mit, zum Beispiel eine UUID:
```bash
curl https://api.kalender-sync.de/v1/publisher/calendars \
-H "Authorization: Bearer $KS_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 3b0f6a52-6a1e-4c55-9d1b-0a7f2c9e1d44" \
-d '{ "name": "Riverside Yoga", "timezone": "Europe/Berlin" }'
```
* Wiederholst du **dieselbe Anfrage mit demselben Key** innerhalb von 24 Stunden, bekommst du die gespeicherte Antwort des ersten Aufrufs zurück, mit dem Header `Idempotent-Replayed: true`. Es entsteht kein zweiter Kalender.
* Derselbe Key mit **einer anderen Anfrage** (anderer Body oder Pfad) ergibt `409` [`idempotency_key_reused`](/api/errors/idempotency_key_reused/).
* Läuft die erste Anfrage noch, ergibt eine Wiederholung `409` [`idempotency_in_progress`](/api/errors/idempotency_in_progress/). Warte kurz und versuche es erneut.
* Ist die erste Anfrage mit einem Fehler gescheitert, wird nichts gespeichert. Die Wiederholung läuft dann ganz normal.
* Der Key darf bis zu 255 Zeichen lang sein, sonst `400` [`invalid_idempotency_key`](/api/errors/invalid_idempotency_key/). Er gilt pro API-Key.
## Optimistisches Sperren
[Abschnitt betitelt „Optimistisches Sperren“](#optimistisches-sperren)
Willst du verhindern, dass zwei Systeme sich gegenseitig überschreiben, schick bei `PUT` auf einen Termin den Header `If-Match` mit der zuletzt gesehenen `sequence`. → [Termine: If-Match](/api/events/#optimistisches-sperren-mit-if-match)
# Bilder
> Logo und Banner der Abo-Seite per API hochladen und entfernen. PNG, JPEG oder WebP als Rohdaten, kein SVG.
Die [Abo-Seite](/abo-kalender/abo-seite/) zeigt ein **Logo** neben dem Namen und ein **Banner** oben. Beide lädst du als Rohbild hoch, also das Bild selbst als Request-Body, nicht als JSON oder Formular.
```plaintext
PUT /v1/publisher/calendars/{calendar_id}/images/logo
PUT /v1/publisher/calendars/{calendar_id}/images/banner
DELETE /v1/publisher/calendars/{calendar_id}/images/logo
DELETE /v1/publisher/calendars/{calendar_id}/images/banner
```
## Hochladen
[Abschnitt betitelt „Hochladen“](#hochladen)
```bash
curl -X PUT https://api.kalender-sync.de/v1/publisher/calendars/$KS_CAL/images/logo \
-H "Authorization: Bearer $KS_KEY" \
-H "Content-Type: image/png" \
--data-binary @logo.png
```
Wichtig ist `--data-binary`, damit curl das Bild unverändert schickt. Die Antwort ist `200 OK` mit dem vollständigen [Kalender](/api/calendars/#die-antwort), darin die neue `logo_url` bzw. `banner_url`. Ein neues Bild ersetzt das alte.
| | Logo | Banner |
| ---------- | ------------------------------------ | ---------------------------------- |
| Formate | PNG, JPEG, WebP | PNG, JPEG, WebP |
| Größe | bis 512 KB | bis 2 MB |
| Empfehlung | quadratisch, mindestens 192 × 192 px | etwa 3:1, mindestens 1200 px breit |
* **Content-Type:** `image/png`, `image/jpeg`, `image/webp` oder `application/octet-stream`. Ob es wirklich ein PNG, JPEG oder WebP ist, prüfen wir am Inhalt der Datei, nicht am Header.
* **Kein SVG.** SVG kann Skripte enthalten und wird deshalb abgelehnt.
* Die Seitenverhältnisse und Mindestgrößen sind Empfehlungen für eine gute Darstellung. Die API prüft nur Format und Dateigröße.
## Entfernen
[Abschnitt betitelt „Entfernen“](#entfernen)
```bash
curl -X DELETE https://api.kalender-sync.de/v1/publisher/calendars/$KS_CAL/images/banner \
-H "Authorization: Bearer $KS_KEY"
```
Antwort `204 No Content`.
## Bild-URLs
[Abschnitt betitelt „Bild-URLs“](#bild-urls)
`logo_url` und `banner_url` zeigen auf unsere eigene Domain, zum Beispiel
```plaintext
https://app.kalender-sync.de/api/public/subscribe/cal_XXXXXXXXXXXX/images/logo?v=…
```
Der Parameter `v` ändert sich mit jedem neuen Bild. So können Browser die Bilder lange zwischenspeichern und zeigen trotzdem nach einem Upload das neue. Besucher der Abo-Seite laden dabei nichts von fremden Servern.
## Fehler
[Abschnitt betitelt „Fehler“](#fehler)
| Code | Status | Wann |
| --------------------------------------------------------------- | ------ | ---------------------------------------------------- |
| [`invalid_image`](/api/errors/invalid_image/) | 400 | Leerer Body |
| [`image_too_large`](/api/errors/image_too_large/) | 413 | Logo über 512 KB, Banner über 2 MB |
| [`unsupported_image_type`](/api/errors/unsupported_image_type/) | 415 | Inhalt ist kein PNG, JPEG oder WebP (z. B. SVG, GIF) |
| [`unsupported_media_type`](/api/errors/unsupported_media_type/) | 415 | Content-Type wird nicht angenommen |
| [`payload_too_large`](/api/errors/payload_too_large/) | 413 | Body deutlich größer als 2 MB |
# Limits und Rate Limits
> 120 Anfragen pro Minute und Key, RateLimit-Header, Retry-After. Dazu alle Grenzen für Kalender, Termine, Batch, Bilder und Request-Größen.
## Rate Limit
[Abschnitt betitelt „Rate Limit“](#rate-limit)
Jeder Key darf **120 Anfragen pro Minute** senden. Gezählt wird in festen Fenstern von 60 Sekunden. Jede Antwort trägt den aktuellen Stand in Headern nach dem IETF-Entwurf für RateLimit-Header:
```plaintext
RateLimit-Policy: "default";q=120;w=60
RateLimit: "default";r=87;t=34
```
| Wert | Bedeutung |
| ---- | ------------------------------------------ |
| `q` | Anfragen pro Fenster |
| `w` | Fenstergröße in Sekunden |
| `r` | verbleibende Anfragen im aktuellen Fenster |
| `t` | Sekunden bis zum nächsten Fenster |
Ist das Limit erreicht, antwortet die API mit `429` [`rate_limited`](/api/errors/rate_limited/) und dem Header `Retry-After` (Sekunden). Warte so lange und wiederhole dann.
Zusätzlich gibt es eine großzügige Obergrenze **pro IP-Adresse** (600 Anfragen pro Minute), damit mehrere Websites auf einem gemeinsamen Webhosting sich nicht gegenseitig ausbremsen.
**Tipps:**
* Für viele Termine nimm [Batch](/api/batch/): 100 Operationen zählen als eine Anfrage.
* Schick Änderungen, wenn sie passieren, statt regelmäßig alles. Für den vollständigen Abgleich gibt es den [Full Sync](/api/full-sync/).
* Unveränderte Termine erkennt die API selbst (`changed: false`); du musst dir dafür nichts merken.
## Grenzen nach Tarif
[Abschnitt betitelt „Grenzen nach Tarif“](#grenzen-nach-tarif)
| | Sandbox (jeder Tarif) | Basic | Professional |
| ------------------------- | --------------------- | --------------- | ---------------- |
| Kalender | 3 Testkalender | 1 Live-Kalender | 10 Live-Kalender |
| Termine je Kalender | 500 | 5.000 | 5.000 |
| Aktive Abonnenten (Konto) | | 500 | 5.000 |
Eine Serie zählt als ein Termin. Mehr auf Anfrage. Was beim Erreichen passiert: [Tarife und Limits](/abo-kalender/tarife/#was-passiert-wenn-du-ein-limit-erreichst).
## Technische Grenzen
[Abschnitt betitelt „Technische Grenzen“](#technische-grenzen)
| | Grenze |
| -------------------------- | ---------------------------------------------------------- |
| Aktive Keys je Konto | 10 |
| JSON-Body | 1 MB |
| Batch | 100 Operationen |
| Logo / Banner | 512 KB / 2 MB |
| Kalendername | 100 Zeichen |
| Kalenderbeschreibung | 1.000 Zeichen |
| `external_id` | 1 bis 128 Zeichen: `A-Z a-z 0-9 . _ : -` |
| Termintitel | 255 Zeichen |
| Terminbeschreibung | 65.536 Zeichen Eingabe, gespeichert bis 8.000 Zeichen Text |
| Ort | 500 Zeichen |
| URLs | 2.000 Zeichen, nur `https://` |
| `categories` | 10 Einträge à 50 Zeichen |
| `metadata` | 2 KB JSON |
| `recurrence.rules` | 5 Regeln à 500 Zeichen |
| `recurrence.except_dates` | 1.000 |
| `recurrence.overrides` | 500 |
| `COUNT`, `INTERVAL` | 1 bis 1.000 |
| `default_duration` | bis `PT24H` |
| Seitengröße beim Auflisten | 100 |
| Gültigkeit eines Full Sync | 1 Stunde |
| `Idempotency-Key` | 255 Zeichen, 24 Stunden gespeichert |
# Schnellstart
> In fünf curl-Aufrufen vom Sandbox-Key zum abonnierbaren Kalender. Key anlegen, prüfen, Kalender anlegen, Termin schreiben, abonnieren.
Für den Schnellstart reicht ein kostenloses Konto. Du arbeitest mit einem **Sandbox-Key**: Er legt Testkalender an, die in echten Kalender-Apps funktionieren, aber als Test gekennzeichnet sind.
## 1. Sandbox-Key anlegen
[Abschnitt betitelt „1. Sandbox-Key anlegen“](#1-sandbox-key-anlegen)
1. Melde dich in der [Kalender Sync App](https://app.kalender-sync.de/) an oder lege ein kostenloses Konto an.
2. Öffne **Einstellungen › Entwickler / API**.
3. Gib dem Key einen Namen und klicke **Sandbox-Key erstellen**.
4. Kopiere den Key. Er wird **genau einmal** angezeigt.
Leg ihn für die folgenden Aufrufe in eine Umgebungsvariable:
```bash
export KS_KEY="ks_test_…"
```
## 2. Key prüfen
[Abschnitt betitelt „2. Key prüfen“](#2-key-prüfen)
```bash
curl https://api.kalender-sync.de/v1/me \
-H "Authorization: Bearer $KS_KEY"
```
```json
{
"account_id": "…",
"key": {
"id": "…",
"name": "Meine Website",
"mode": "test",
"scopes": ["publisher:read", "publisher:write", "publisher:stats"],
"calendar_ids": null
}
}
```
`mode: "test"` heißt: Dieser Key sieht nur Testkalender.
## 3. Kalender anlegen
[Abschnitt betitelt „3. Kalender anlegen“](#3-kalender-anlegen)
```bash
curl https://api.kalender-sync.de/v1/publisher/calendars \
-H "Authorization: Bearer $KS_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"name": "Riverside Yoga",
"description": "Kurse und Workshops im Studio am Fluss.",
"timezone": "Europe/Berlin",
"language": "de",
"site_url": "https://example.org",
"brand_color": "#0f766e"
}'
```
Die Antwort (`201 Created`) enthält alles, was du für die nächsten Schritte brauchst:
```json
{
"id": "cal_XXXXXXXXXXXX",
"mode": "test",
"name": "Riverside Yoga",
"timezone": "Europe/Berlin",
"default_duration": "PT1H",
"show_events": true,
"subscribe_page_url": "https://app.kalender-sync.de/subscribe/cal_XXXXXXXXXXXX",
"feed_url": "https://feeds.kalender-sync.de/f_….ics",
"subscribe_links": { "google": "…", "outlook": "…", "office365": "…", "apple": "webcal://…" },
"event_count": 0,
"…": "…"
}
```
Merk dir die `id`:
```bash
export KS_CAL="cal_XXXXXXXXXXXX"
```
## 4. Termin schreiben
[Abschnitt betitelt „4. Termin schreiben“](#4-termin-schreiben)
Termine legst du per `PUT` unter deiner eigenen ID an, hier `wp-101`. Derselbe Aufruf ändert den Termin später.
```bash
curl -X PUT https://api.kalender-sync.de/v1/publisher/calendars/$KS_CAL/events/wp-101 \
-H "Authorization: Bearer $KS_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Sunset Yoga",
"start": "2026-11-12T18:00:00",
"end": "2026-11-12T19:15:00",
"location": "Dachterrasse, Hauptstraße 5, Berlin",
"description": "Bring eine Matte mit.",
"url": "https://example.org/kurse/sunset-yoga"
}'
```
Ohne `timezone` im Termin gilt die Zeitzone des Kalenders. Die Antwort ist `201 Created` beim ersten Mal und `200 OK` bei jeder Änderung. Schickst du denselben Termin noch einmal, kommt `"changed": false`.
Eine wöchentliche Serie sieht so aus:
```bash
curl -X PUT https://api.kalender-sync.de/v1/publisher/calendars/$KS_CAL/events/wp-102 \
-H "Authorization: Bearer $KS_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Morning Flow",
"start": "2026-11-03T07:30:00",
"end": "2026-11-03T08:30:00",
"recurrence": { "rules": ["FREQ=WEEKLY;BYDAY=TU;COUNT=8"] }
}'
```
## 5. Abonnieren
[Abschnitt betitelt „5. Abonnieren“](#5-abonnieren)
Öffne die `subscribe_page_url` aus Schritt 3 im Browser. Dort siehst du deine Termine, den Hinweis „Testkalender“ und den Button mit der App-Auswahl. Abonniere den Kalender testweise in deiner eigenen Kalender-App.
Für deine Website brauchst du nur noch den Button:
```html
```
→ [Button und ks:subscribe](/api/button/)
## Und dann?
[Abschnitt betitelt „Und dann?“](#und-dann)
* **Live gehen:** Lege unter **Einstellungen › Entwickler / API** einen Live-Key an (ab Basic) und wiederhole Schritt 3 damit. Sandbox- und Live-Kalender sind getrennt; Testkalender werden nicht zu Live-Kalendern. → [Tarife und Limits](/abo-kalender/tarife/)
* **Viele Termine auf einmal:** [Batch](/api/batch/)
* **Regelmäßig abgleichen:** [Full Sync](/api/full-sync/)
* **Logo und Banner:** [Bilder](/api/images/)
# Statistik
> Aktive Abonnenten je App, Klicks der letzten 30 Tage und der Stand deines Kontos gegenüber dem Tarif. Ohne Personenbezug gezählt.
```plaintext
GET /v1/publisher/calendars/{calendar_id}/stats
```
Braucht den Scope `publisher:stats`.
```bash
curl https://api.kalender-sync.de/v1/publisher/calendars/$KS_CAL/stats -H "Authorization: Bearer $KS_KEY"
```
```json
{
"as_of": "2026-11-20T08:00:00.000Z",
"subscribers": {
"total": 97,
"feed": { "total": 97, "by_app": { "google": 51, "apple": 30, "outlook": 12, "other": 4 } },
"live": { "total": 0, "by_provider": { "google": 0, "microsoft": 0, "icloud": 0 } }
},
"direct_feed_clients_7d": null,
"subscribe_clicks_30d": { "total": 160, "by_app": { "google": 70, "apple": 55, "outlook": 25, "other": 10 } },
"plan": {
"plan": "basic",
"live_calendars": { "used": 1, "limit": 1 },
"active_subscribers": { "used": 97, "limit": 500 },
"over_calendar_limit": false,
"over_subscriber_limit": false
}
}
```
| Feld | Bedeutung |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `subscribers.feed.total` | Aktive Abonnenten dieses Kalenders: Kalender-Apps, die den Feed in den letzten **14 Tagen** abgerufen haben. |
| `subscribers.feed.by_app` | Aufgeteilt nach `google`, `apple`, `outlook` (Outlook.com, Microsoft 365 und Outlook Desktop zusammen) und `other`. |
| `subscribers.live` | Für eine spätere Funktion reserviert, derzeit immer `0`. |
| `subscribers.total` | Summe; derzeit gleich `feed.total`. |
| `direct_feed_clients_7d` | Für eine spätere Schätzung reserviert, derzeit immer `null`. |
| `subscribe_clicks_30d` | Jede App-Auswahl auf der Abo-Seite und im Button in den letzten 30 Tagen, egal ob danach abonniert wurde. |
| `plan` | Dein **Konto** im Vergleich zum Tarif (über alle Live-Kalender). `plan.plan` ist `free`, `basic` oder `business` (auf der Website: Professional). |
## Was gezählt wird und was nicht
[Abschnitt betitelt „Was gezählt wird und was nicht“](#was-gezählt-wird-und-was-nicht)
* Gezählt werden Abos über die **Abo-Seite** und den **Button**. Jedes bekommt einen eigenen Feed-Link, dessen Abrufe wir zählen.
* Nicht gezählt werden Abos über die allgemeine `feed_url` oder die `subscribe_links`, wenn du sie selbst einbaust. Diese funktionieren genauso, lassen sich aber nicht einzeln zählen.
* Wir speichern keine IP-Adressen, keine User-Agents und nichts über die Personen hinter einem Abo.
* Sandbox-Kalender haben eine eigene Statistik, zählen aber nicht für `plan.active_subscribers`.
## Limit erreicht
[Abschnitt betitelt „Limit erreicht“](#limit-erreicht)
`over_subscriber_limit: true` heißt: Dein Konto hat mehr aktive Abonnenten, als dein Tarif umfasst. **Es läuft trotzdem alles weiter.** Du bekommst zusätzlich eine E-Mail (höchstens alle 30 Tage). → [Tarife und Limits](/abo-kalender/tarife/)
`over_calendar_limit: true` heißt: Dein Konto hat mehr Live-Kalender, als der Tarif umfasst, etwa nach einem Downgrade. Feeds laufen weiter, Schreibzugriffe antworten mit [`plan_required`](/api/errors/plan_required/).
# AVV & Unterauftragnehmer
> Auftragsverarbeitungsvertrag nach Art. 28 DSGVO und wo die maßgebliche Liste der Unterauftragnehmer steht.
## Auftragsverarbeitungsvertrag (AVV)
[Abschnitt betitelt „Auftragsverarbeitungsvertrag (AVV)“](#auftragsverarbeitungsvertrag-avv)
**AVV für alle Tarife bei geschäftlicher Nutzung inklusive – Bestandteil der AGB.** Setzt du Kalender Sync als Unternehmer ein (§ 14 BGB, auch als Freiberufler oder Einzelunternehmer), gilt der [AVV nach Art. 28 DSGVO](https://kalender-sync.de/avv/) mit Annahme der AGB – in Free, Basic und Professional, ohne Unterschrift und ohne Antrag. Über die Druckansicht kannst du ihn als PDF speichern.
* Brauchst du für eure Unterlagen ein **unterzeichnetes Exemplar**, schreib an – der Inhalt ist identisch mit der Online-Fassung.
* Für Verträge, die **vor dem 17. Oktober 2026** geschlossen wurden, gilt der AVV, sobald du ihn in Textform annimmst (eine kurze E-Mail genügt) oder er über eine AGB-Änderung einbezogen wird; bis dahin bekommst du ihn auf Anfrage.
## Unterauftragnehmer
[Abschnitt betitelt „Unterauftragnehmer“](#unterauftragnehmer)
Maßgeblich ist die **[Liste der Unterauftragnehmer](https://kalender-sync.de/unterauftragnehmer/)** auf kalender-sync.de. Sie ist Vertragsanlage zum AVV und nennt je Anbieter Zweck, Verarbeitungsort und Garantien. Neue oder ersetzte Unterauftragnehmer kündigen wir mindestens 30 Tage vorab per E-Mail an; du kannst innerhalb von 30 Tagen widersprechen (Ziffer 7 des AVV).
Kurz zusammengefasst:
* **Hetzner** (Deutschland) – Hosting von App und Datenbank in Nürnberg, verschlüsselte Backups in Falkenstein.
* **Lettermint** (Niederlande) – Anmeldecodes und transaktionale E-Mails.
* **Customer.io** (USA, EU-Datenregion, Standardvertragsklauseln) – Service-, Onboarding- und Testphasen-Mails; keine Kalenderinhalte oder Zugangsdaten.
* **Brevo** (Frankreich) – nur noch historische Nachweise, aktiver Versand abgeschaltet.
**Keine Unterauftragnehmer** sind die Kalenderdienste, die du selbst verbindest (Google, Microsoft, Apple iCloud, CalDAV-Anbieter): Kalenderdaten fließen nur zwischen deinen eigenen Konten. Ebenso wenig ein KI-Assistent, den du per MCP verbindest. Die Zahlungsabwicklung über Stripe erfolgt in unserer eigenen Verantwortlichkeit und ist in der [Datenschutzerklärung](https://kalender-sync.de/datenschutz/) beschrieben.
## Verbindliche Quellen
[Abschnitt betitelt „Verbindliche Quellen“](#verbindliche-quellen)
* [Auftragsverarbeitungsvertrag](https://kalender-sync.de/avv/) und [Liste der Unterauftragnehmer](https://kalender-sync.de/unterauftragnehmer/) – Vertragstexte
* [AGB](https://kalender-sync.de/agb/) – Ziffer 10 bezieht den AVV ein
* [IT-Admin-Seite](https://kalender-sync.de/it-admin/) – kompakte Übersicht für Compliance-Reviews (Scopes, Admin-Consent, Hosting)
# DSGVO-Rechte umsetzen
> Auskunft, Datenübertragbarkeit, Löschung und Widerruf — fast alles in Selbstbedienung.
Die meisten DSGVO-Rechte kannst du bei Kalender Sync **direkt selbst ausüben** — ohne Anfrage und Wartefrist.
## Auskunft & Datenübertragbarkeit (Art. 15 & 20)
[Abschnitt betitelt „Auskunft & Datenübertragbarkeit (Art. 15 & 20)“](#auskunft--datenübertragbarkeit-art-15--20)
Der [Datenexport](/account-billing/export-delete/) in den Einstellungen lädt alle über dich gespeicherten Daten als JSON-Archiv — sofort, so oft du willst. Was drinsteckt (und warum keine Termininhalte), steht dort beschrieben.
## Berichtigung (Art. 16)
[Abschnitt betitelt „Berichtigung (Art. 16)“](#berichtigung-art-16)
Name, Branche und Sprache änderst du im [Profil](/account-billing/profile-notifications/). Für die E-Mail-Adresse (aktuell nicht selbst änderbar) hilft der [Support](/troubleshooting/contact-support/).
## Löschung (Art. 17)
[Abschnitt betitelt „Löschung (Art. 17)“](#löschung-art-17)
Die [Konto-Löschung](/account-billing/export-delete/) in den Einstellungen entfernt sofort und endgültig alle Daten — inklusive der Blocker in Zielkalendern und der Zugriffe auf deine Kalenderkonten.
## Widerruf von Einwilligungen (Art. 7)
[Abschnitt betitelt „Widerruf von Einwilligungen (Art. 7)“](#widerruf-von-einwilligungen-art-7)
* **Newsletter & Produkt-Updates**: Abmeldelink in jeder Mail oder Häkchen in den Einstellungen entfernen.
* **Cookies/Statistik** auf der Website: über „Cookie-Einstellungen” im Footer jederzeit anpassbar.
* **Kalender-Zugriffe**: Kalender jederzeit [entfernen](/connect-calendar/disconnect/) — den Konto-Zugriff widerrufst du direkt beim Anbieter.
## Beschwerde & Kontakt
[Abschnitt betitelt „Beschwerde & Kontakt“](#beschwerde--kontakt)
Verantwortlicher und Kontakt für Datenschutzanfragen stehen in der [Datenschutzerklärung](https://kalender-sync.de/datenschutz/) und im [Impressum](https://kalender-sync.de/impressum/). Unabhängig davon hast du das Recht, dich bei einer Datenschutz-Aufsichtsbehörde zu beschweren.
Für alles, was hier nicht abgedeckt ist: — Datenschutzanfragen beantworten wir bevorzugt.
# Kalender Sync in der Organisation freigeben
> Für IT-Admins — Microsoft Admin-Consent in zwei Minuten erteilen, Google Workspace freischalten, Compliance-Fakten fürs Review.
Diese Seite ist zum **Weiterleiten an die IT** gedacht: alles, was ein Admin für die einmalige Freigabe von Kalender Sync braucht. Die kompakte Übersicht mit dem klickbaren Admin-Consent-Link steht auf **[kalender-sync.de/it-admin](https://kalender-sync.de/it-admin/)**.
## Microsoft 365 / Entra ID
[Abschnitt betitelt „Microsoft 365 / Entra ID“](#microsoft-365--entra-id)
**Der schnelle Weg (\~2 Minuten):**
1. Als **Global Admin** den Admin-Consent-Link öffnen:
→ **[Admin-Consent für Kalender-Sync erteilen](https://login.microsoftonline.com/common/adminconsent?client_id=f656be6d-e0c1-43a4-a4a8-e1452eaf78f3\&redirect_uri=https%3A%2F%2Fkalender-sync.de%2Fadmin-consent-erteilt%2F)**
(Client-ID zum Verifizieren: `f656be6d-e0c1-43a4-a4a8-e1452eaf78f3` — nach der Bestätigung leitet Microsoft auf unsere Bestätigungsseite weiter.)
2. Die angefragten Berechtigungen prüfen (`User.Read`, `Calendars.ReadWrite`, `offline_access` — [Details](/privacy-it/permissions/)) und bestätigen.
3. Fertig — die Zustimmung gilt tenant-weit, Nutzer:innen verbinden sich ab sofort ohne Rückfrage.
Alternativ über das Entra-Portal: **Enterprise Applications → Kalender-Sync → Permissions → Grant admin consent**. Die Berechtigungen sind delegiert (delegated) — Kalender Sync agiert nur im Kontext des jeweils angemeldeten Nutzers, nie mit Anwendungsrechten auf fremde Postfächer.
## Google Workspace
[Abschnitt betitelt „Google Workspace“](#google-workspace)
1. [Admin-Konsole](https://admin.google.com/) öffnen → **Sicherheit → Zugriffs- und Datenkontrolle → API-Steuerung → App-Zugriffssteuerung**.
2. **„App konfigurieren”** (bzw. „Apps verwalten” → „App hinzufügen”) → Suche nach **OAuth-App-Name oder Client-ID**:
```text
799110401428-vpauqp9v2ksno7vc6k2404pgg956tjit.apps.googleusercontent.com
```
Alternativ nach dem Namen **„Kalender Sync”** suchen.
3. Die App auswählen, den Geltungsbereich festlegen (gesamte Organisation oder einzelne Organisationseinheiten) und den Zugriff auf **„Vertrauenswürdig”** setzen → bestätigen.
4. Ab sofort können sich Nutzer:innen ohne Blockierung verbinden — die Zustimmung zu den Scopes erteilt weiterhin jede:r selbst im Google-Login.
In der App-Detailansicht der Admin-Konsole sieht die IT dabei genau, welche Dienste angefragt werden (Google Log-in, Kalender) und welche Bereiche Nutzer:innen gewährt haben. Die angefragten Scopes (`calendar.events`, `calendar.calendarlist.readonly` + Identität) stehen auch unter [Berechtigungen im Detail](/privacy-it/permissions/).
## Fakten fürs Compliance-Review
[Abschnitt betitelt „Fakten fürs Compliance-Review“](#fakten-fürs-compliance-review)
* **Hosting & Datenbank in Deutschland** (Hetzner, Nürnberg; verschlüsselte Backups in Falkenstein) — [Sicherheits-Überblick](/privacy-it/security-overview/)
* **Keine Speicherung von Termininhalten**, keine Übertragung von Teilnehmerdaten
* Zugangsdaten **verschlüsselt at rest**, TLS in transit
* **AVV nach Art. 28 DSGVO** — für alle Tarife bei geschäftlicher Nutzung inklusive, Bestandteil der AGB: [kalender-sync.de/avv](https://kalender-sync.de/avv/) · [AVV & Unterauftragnehmer](/privacy-it/dpa-subprocessors/)
* Zustimmung jederzeit **widerrufbar** (tenant-weit oder pro Nutzer:in), Konten und Daten von Nutzer:innen [selbst löschbar](/account-billing/export-delete/)
## Wenn die Freigabe nicht infrage kommt
[Abschnitt betitelt „Wenn die Freigabe nicht infrage kommt“](#wenn-die-freigabe-nicht-infrage-kommt)
Nutzer:innen können den eigenen Kalender auch ohne OAuth-Freigabe als [iCal-Feed-Quelle](/connect-calendar/ical-feed/) einbinden — schreibgeschützt und ohne Admin-Beteiligung. Die Optionen im Vergleich: [Meine Organisation blockiert die Verbindung](/connect-calendar/org-blocked/).
# Benötigte Berechtigungen im Detail
> Welche Berechtigungen Kalender Sync bei Google, Microsoft und CalDAV anfragt — Scope für Scope erklärt.
Kalender Sync fragt nur an, was für den Sync nötig ist — und nichts davon erlaubt Zugriff auf E-Mails, Dateien oder Kontakte. Hier die vollständige Aufschlüsselung, z. B. für IT-Reviews.
## Google Calendar
[Abschnitt betitelt „Google Calendar“](#google-calendar)
| Scope | Zweck |
| -------------------------------- | -------------------------------------------------------------- |
| `openid`, `profile`, `email` | Authentifizierung — wer ist eingeloggt |
| `calendar.events` | Lesen + Schreiben von Kalendereinträgen (für die Busy-Blocker) |
| `calendar.calendarlist.readonly` | Liste der verfügbaren Kalender abrufen |
Google nutzt inkrementelle Zustimmung — die Häkchen im Consent-Dialog sollten gesetzt bleiben, sonst kann der Sync keine Blocker anlegen.
## Microsoft 365 / Outlook
[Abschnitt betitelt „Microsoft 365 / Outlook“](#microsoft-365--outlook)
| Scope | Zweck |
| --------------------- | ---------------------------------------------------------------- |
| `User.Read` | Authentifizierung — wer ist eingeloggt |
| `Calendars.ReadWrite` | Lesen + Schreiben von Kalendereinträgen (für die Busy-Blocker) |
| `offline_access` | Refresh-Token, damit der Sync im Hintergrund ohne Re-Login läuft |
Kein Admin-Consent erforderlich — außer in strikt konfigurierten Tenants ([was dann?](/connect-calendar/org-blocked/)).
## Apple iCloud / KSuite (CalDAV)
[Abschnitt betitelt „Apple iCloud / KSuite (CalDAV)“](#apple-icloud--ksuite-caldav)
| Mechanismus | Zweck |
| ---------------------------- | ------------------------------------------------------------------------------ |
| App-spezifisches Passwort | Pro Verbindung ein eigenes Passwort, getrennt von der iCloud-/KSuite-Identität |
| CalDAV `REPORT` / `PROPFIND` | Standard-CalDAV-Operationen zum Lesen + Schreiben |
Kein OAuth — die App-Passwörter sind jederzeit beim Anbieter widerrufbar und geben keinen Zugriff auf andere Dienste des Kontos.
## iCal-Feeds
[Abschnitt betitelt „iCal-Feeds“](#ical-feeds)
Die Feed-URL (inkl. enthaltenem Token) wird wie ein Passwort behandelt und **verschlüsselt gespeichert**. Feeds sind rein lesend.
## Warum Schreibzugriff?
[Abschnitt betitelt „Warum Schreibzugriff?“](#warum-schreibzugriff)
Kalender Sync legt im Zielkalender eigene Blocker-Termine an, aktualisiert sie und räumt sie beim Beenden wieder auf — dafür braucht es Schreibrechte. Deine **Originaltermine werden nie verändert**; es werden ausschließlich die selbst erstellten Blocker angefasst.
## Zugriff beenden
[Abschnitt betitelt „Zugriff beenden“](#zugriff-beenden)
Einzelne Kalender lassen sich in Kalender Sync [entfernen](/connect-calendar/disconnect/), der Zugriff zusätzlich direkt beim Anbieter widerrufen — die Links stehen dort in der Übersichtstabelle.
# Sicherheit & Datenschutz im Überblick
> Hosting in Deutschland, Verschlüsselung und Datensparsamkeit — was Kalender Sync speichert und was nicht.
Diese Sektion richtet sich an IT-Verantwortliche, Datenschutzbeauftragte — und alle, die genau wissen wollen, was mit ihren Daten passiert. Rechtsverbindlich ist die [Datenschutzerklärung](https://kalender-sync.de/datenschutz/); hier steht die verständliche Fassung.
## Das Wichtigste in Kürze
[Abschnitt betitelt „Das Wichtigste in Kürze“](#das-wichtigste-in-kürze)
* **Hosting in Deutschland**: Server und Datenbank laufen bei Hetzner in Nürnberg, verschlüsselte Backups in einer Hetzner Storage Box in Falkenstein (anderes Rechenzentrum) — keine US-Cloud als Unterbau.
* **Termininhalte werden nicht gespeichert**: Kalender Sync persistiert nur Termin-**IDs** und **Prüfsummen** zur Änderungserkennung. Titel, Beschreibungen und Orte fließen nur während des Syncs durch.
* **Daten Dritter bleiben außen vor**: Teilnehmerlisten, E-Mail-Adressen von Gästen, Organisator:innen und Zu-/Absagen werden [nie übertragen](/sync/visibility-levels/) — bei keiner Sichtbarkeitsstufe.
* **Zugangsdaten verschlüsselt**: OAuth-Tokens, App-Passwörter und Feed-URLs liegen verschlüsselt in der Datenbank (ChaCha20-Poly1305); die Übertragung läuft durchgehend über TLS.
* **Datensparsamkeit als Architektur**: Synchronisiert wird nur das [Zeitfenster](/sync/sync-window/) von −3 bis +6 Monaten (Professional: +18), und standardmäßig nur „belegt/frei”.
## Was gespeichert wird
[Abschnitt betitelt „Was gespeichert wird“](#was-gespeichert-wird)
| Kategorie | Inhalt |
| ------------------ | --------------------------------------------------------------------------------------- |
| Konto | E-Mail-Adresse, Name (optional), Spracheinstellung, Plan, Einwilligungs-Zeitstempel |
| Kalender-Metadaten | Kalendername, Farbe, Schreibrechte — keine Inhalte |
| Sync-Konfiguration | Syncs mit Sichtbarkeitsstufe, Platzhalter-Titel, Quell-/Zielkalender |
| Sync-Zuordnungen | Termin-IDs (Quelle ↔ Blocker) und Prüfsummen — keine Inhalte |
| Zugangsdaten | OAuth-Tokens / App-Passwörter / Feed-URLs, verschlüsselt |
| Sitzungen | Browser, IP-Adresse, letzte Aktivität ([einsehbar](/account-billing/sessions-devices/)) |
## Was nicht gespeichert wird
[Abschnitt betitelt „Was nicht gespeichert wird“](#was-nicht-gespeichert-wird)
* Termininhalte (Titel, Beschreibung, Ort) — nur Durchfluss während des Syncs
* Teilnehmerlisten und deren E-Mail-Adressen
* Anhänge
* E-Mails, Dateien oder Kontakte aus deinen Konten — darauf hat Kalender Sync [keine Berechtigung](/privacy-it/permissions/)
## Weiterführend
[Abschnitt betitelt „Weiterführend“](#weiterführend)
* [Benötigte Berechtigungen im Detail](/privacy-it/permissions/)
* [AVV & Unterauftragnehmer](/privacy-it/dpa-subprocessors/)
* [DSGVO-Rechte umsetzen](/privacy-it/gdpr-rights/)
* Für IT-Abteilungen: [Kalender Sync in der Organisation freigeben](/privacy-it/org-approval/)
# Mehrere Quellkalender in einem Sync
> Mehrere Kalender gebündelt in ein Ziel synchronisieren — und wann getrennte Syncs besser sind.
Ein Sync kann aus **mehreren Quellkalendern** gespeist werden — auch quer über deine verbundenen Konten hinweg. Alle Belegungen landen gebündelt im Zielkalender.
## So funktioniert’s
[Abschnitt betitelt „So funktioniert’s“](#so-funktionierts)
Im Schritt **„Kalender”** beim Erstellen einfach mehrere Kalender anhaken — z. B. Privat, Verein und Familie. Jede Belegung aus jedem dieser Kalender erzeugt einen Blocker im Ziel:
```text
Privat ──┐
Verein ──┼──→ Arbeitskalender
Familie ─┘
```
Fehlt ein Kalender in der Liste, kannst du direkt aus dem Schritt heraus ein weiteres Konto verbinden — dein Zwischenstand bleibt erhalten.
## Ein Sync oder mehrere?
[Abschnitt betitelt „Ein Sync oder mehrere?“](#ein-sync-oder-mehrere)
**Ein Sync mit mehreren Quellen**, wenn …
* alle Quellen dieselbe [Sichtbarkeitsstufe](/sync/visibility-levels/) und denselben [Platzhalter-Titel](/sync/placeholder-title/) haben sollen,
* du es schlicht einfach halten willst (ein Sync = ein Eintrag im Dashboard).
**Getrennte Syncs**, wenn …
* die Empfängerseite unterscheiden soll, *was* sie blockt („Privat” vs. „Nebenprojekt” statt zweimal „Geblockt”),
* Quellen unterschiedliche Sichtbarkeit brauchen (z. B. Familie „Nur belegt”, Nebenprojekt „Titel + Zeit”),
* du einzelne Quellen später unabhängig [pausieren oder beenden](/sharings/pause-end/) willst.
Getrennte Syncs zählen einzeln gegen dein [Plan-Limit](/account-billing/plans-limits/) — die gebündelte Variante ist also auch die sparsamere.
## Quellen nachträglich ändern
[Abschnitt betitelt „Quellen nachträglich ändern“](#quellen-nachträglich-ändern)
Quellen lassen sich jederzeit **nachträglich ändern**: Drei-Punkte-Menü der Freigabe → **„Bearbeiten”** — neue Quellen werden vollständig nachsynchronisiert, entfernte räumen ihre Kopien im Zielkalender automatisch ab → [Freigabe bearbeiten](/sync/freigabe-bearbeiten/).
# Sync pausieren oder beenden
> Sync anhalten oder dauerhaft beenden — und was dabei mit den Blocker-Terminen passiert.
Beides geht jederzeit direkt im Dashboard beim jeweiligen Sync. Der Unterschied liegt darin, was mit den Blocker-Terminen passiert.
## Pausieren — Blocker bleiben stehen
[Abschnitt betitelt „Pausieren — Blocker bleiben stehen“](#pausieren--blocker-bleiben-stehen)
* Der Sync stoppt, die vorhandenen Blocker im Ziel **bleiben erhalten**. Praktisch, wenn du den Sync nur vorübergehend nicht brauchst.
* Beim **Fortsetzen** gleicht Kalender Sync den Stand komplett ab — alles, was sich während der Pause geändert hat, wird nachgezogen.
* Bei einem Zwei-Wege-Sync ([eigene Kalender synchronisieren](/sharings/self-sync/)) werden immer **beide Richtungen** gemeinsam pausiert und fortgesetzt.
* Vor dem Pausieren fragt ein kurzer Dialog nach dem Grund — das hilft uns, das Produkt zu verbessern.
Automatisch pausiert?
Syncs können auch ohne dein Zutun pausiert werden: am **Ende der Testphase** oder nach einer **Kündigung**, wenn sie über das Limit des Free-Plans hinausgehen. Nach einer **Kündigung** bleiben die kopierten Einträge erhalten; am **Ende der Testphase** werden die Kopien von Syncs eigener Kalender nach 14 Tagen **entfernt** (deine Originaltermine bleiben unberührt). In beiden Fällen wird nach einem Upgrade alles automatisch aus deinen Originalkalendern **wiederhergestellt**. Details: [Testphase](/account-billing/trial/) und [Pläne & Limits](/account-billing/plans-limits/).
Beim manuellen Fortsetzen gilt das Plan-Limit ebenfalls: Auf Free kannst du z. B. nicht zwei Syncs gleichzeitig aktiv haben, indem du abwechselnd pausierst.
## Beenden — Blocker werden aufgeräumt
[Abschnitt betitelt „Beenden — Blocker werden aufgeräumt“](#beenden--blocker-werden-aufgeräumt)
* Der Sync endet **dauerhaft**; alle von Kalender Sync erstellten Blocker im Ziel werden **automatisch entfernt**. Deine Originaltermine bleiben selbstverständlich unberührt.
* Das Aufräumen läuft im Hintergrund: Bis die Blocker in allen Kalendern verschwunden sind, kann es **ein paar Minuten bis Stunden** dauern — je nach Anzahl der Termine und Tempo des Kalender-Anbieters.
* Bei Freigaben (geteilten Syncs) kann **jede Seite** beenden: du als Absender:in im Dashboard, die Empfängerseite unter „Geteilt mit mir” → **„Beenden”**.
* Ein Beenden lässt sich nicht rückgängig machen — aber ein neuer Sync ist in unter einer Minute angelegt. (Einstellungen wie Sichtbarkeit, Quellen oder Präfix änderst du übrigens ohne Beenden über „Bearbeiten” → [Freigabe bearbeiten](/sync/freigabe-bearbeiten/).)
## Kurz verglichen
[Abschnitt betitelt „Kurz verglichen“](#kurz-verglichen)
| | Pausieren | Beenden |
| ------------------ | ------------------------------------------ | ------------------ |
| Blocker im Ziel | bleiben stehen | werden aufgeräumt |
| Wieder aktivierbar | ja, jederzeit (Abgleich läuft automatisch) | nein — neu anlegen |
| Wer kann es | Absender:in | beide Seiten |
# Eigene Kalender synchronisieren
> Zwei eigene Kalender synchronisieren — in eine Richtung oder beide, mit Einstellungen pro Richtung.
BasicVerfügbar ab Basic·[Pläne vergleichen](https://kalender-sync.de/preise/)
Dieser Sync-Typ hält deine eigenen Kalender im Gleichklang — z. B. Arbeit und privat: Termine aus dem einen blocken automatisch den anderen. Kein Einladungslink nötig, läuft sofort nach dem Einrichten.
## Video: Eigene Kalender synchronisieren
[Abschnitt betitelt „Video: Eigene Kalender synchronisieren“](#video-eigene-kalender-synchronisieren)

Mit Klick auf Play wird YouTube geladen. Daten werden an Google übertragen.Cookie-Einstellungen öffnen
## Eine Richtung oder beide?
[Abschnitt betitelt „Eine Richtung oder beide?“](#eine-richtung-oder-beide)
* **Eine Richtung** (A → B): Ein Kalender blockt den anderen, nicht umgekehrt. Typisch: Der private Kalender blockt den Arbeitskalender — die Arbeit bleibt privat unsichtbar.
* **Beide Richtungen** (A ⇄ B), der **Zwei-Wege-Sync**: Beide blocken sich gegenseitig. Typisch: zwei gleichberechtigte Kalender (zwei Jobs, Arbeit ⇄ privat). Zählt fürs Plan-Limit als **ein** Sync.
## Einrichten
[Abschnitt betitelt „Einrichten“](#einrichten)
1. **„Neuer Sync”** → **„Kalender synchronisieren”**.
2. **Richtung** wählen: „Eine Richtung” oder „Beide Richtungen”.
3. **Kalender** wählen — beim Zwei-Wege-Sync genau **zwei beschreibbare** Kalender (iCal-Feeds sind nur lesbar und gehen daher nicht als Zwei-Wege-Partner).
4. **Sichtbarkeit** festlegen — beim Zwei-Wege-Sync auf Wunsch **pro Richtung unterschiedlich**: Stufe, [Platzhalter-Titel](/sync/placeholder-title/) und [Ganztags-Verhalten](/sync/all-day-events/) lassen sich je Richtung einstellen („Pro Richtung →”).
5. Bei „Eine Richtung” noch das **Ziel** wählen — fertig. Die erste Synchronisation läuft im Hintergrund an.
## Gut zu wissen
[Abschnitt betitelt „Gut zu wissen“](#gut-zu-wissen)
* **Keine Schleifen**: Blocker werden nie zurück-synchronisiert — auch in beide Richtungen entsteht kein Ping-Pong ([so funktioniert der Sync](/sync/how-it-works/)).
* **Pausieren pausiert beide Richtungen** — ein Zwei-Wege-Sync wird immer als Ganzes pausiert und fortgesetzt ([Pausieren & Beenden](/sharings/pause-end/)).
* **Drei und mehr Kalender** verbindest du mit mehreren Syncs — Beispiele unter [Mehrere Konten & Ketten-Setups](/sync/multi-account-setups/).
* Einstellungen nachträglich ändern: über das Drei-Punkte-Menü → **„Bearbeiten“** — Quellen, Zielkalender, Sichtbarkeit, Präfix und mehr ([Freigabe bearbeiten](/sync/freigabe-bearbeiten/)).
# Kalender mit anderen teilen
> Eine Freigabe an eine andere Person senden — Einladung, Status und Verwaltung im Detail.
Mit einer geteilten Freigabe sieht eine andere Person deine Verfügbarkeiten — ohne dass sie Zugriff auf deinen Kalender bekommt. Sie erhält eine Einladung, wählt selbst den Zielkalender und kann die Freigabe jederzeit auf ihrer Seite beenden.
## Video: Teilen ohne private Termine zu zeigen
[Abschnitt betitelt „Video: Teilen ohne private Termine zu zeigen“](#video-teilen-ohne-private-termine-zu-zeigen)

Mit Klick auf Play wird YouTube geladen. Daten werden an Google übertragen.Cookie-Einstellungen öffnen
## Freigabe erstellen und verschicken
[Abschnitt betitelt „Freigabe erstellen und verschicken“](#freigabe-erstellen-und-verschicken)
Den kompletten Weg durch die Einrichtung zeigt [Erste Freigabe einrichten](/getting-started/first-sharing/) — die Kurzfassung:
1. **„Neuer Sync”** → **„Kalender teilen”** → Quellkalender und [Sichtbarkeitsstufe](/sync/visibility-levels/) wählen.
2. Im letzten Schritt die Einladung verschicken: **Link kopieren** und selbst senden (Messenger, Mail) — oder die E-Mail-Adresse eintragen, dann verschickt Kalender Sync die Einladung direkt.
Die Empfängerseite bekommt **genau eine E-Mail** — keine weiteren, solange sie sich nicht registriert.
## Die Einladung
[Abschnitt betitelt „Die Einladung“](#die-einladung)
* Der Link ist **7 Tage gültig** und **einmal** verwendbar.
* Solange die Annahme aussteht, zeigt das Dashboard die Freigabe als **„Ausstehend”** — dort kannst du den Einladungslink jederzeit **erneut kopieren** und nochmal verschicken.
* **Link abgelaufen?** Freigabe beenden und neu anlegen — das erzeugt einen frischen Link und dauert unter einer Minute.
Was die Empfängerseite beim Annehmen sieht und entscheidet (Zielkalender wählen oder neu anlegen lassen), steht aus ihrer Sicht unter [Ich habe eine Einladung erhalten](/getting-started/received-invite/) — der Link eignet sich auch zum Weiterschicken.
## Nach der Annahme
[Abschnitt betitelt „Nach der Annahme“](#nach-der-annahme)
* Der Status wechselt auf **„Aktiv”**, die erste Synchronisation läuft an (E-Mail, sobald fertig).
* Ab dann fließen Änderungen automatisch — [so funktioniert der Sync](/sync/how-it-works/).
* Die Empfängerseite sieht nur, was deine [Sichtbarkeitsstufe](/sync/visibility-levels/) erlaubt — Teilnehmerdaten nie.
## Verwalten
[Abschnitt betitelt „Verwalten“](#verwalten)
* **Pausieren / Beenden** kannst du jederzeit im Dashboard — beim Beenden werden alle Blocker bei der Empfängerseite aufgeräumt ([Details](/sharings/pause-end/)).
* Auch die **Empfängerseite** kann die Freigabe jederzeit für sich beenden (unter „Geteilt mit mir”).
* Sichtbarkeit, Platzhalter-Titel oder Quellen ändern: über das Drei-Punkte-Menü → **„Bearbeiten“** ([Freigabe bearbeiten](/sync/freigabe-bearbeiten/)). Nur der Zielkalender bleibt fest — der gehört der Empfängerseite.
# Ganztägige Termine
> Warum Geburtstage und Feiertage standardmäßig nicht den ganzen Tag blocken — und wie du das änderst.
Ganztägige Termine sind meistens **Merker, keine Belegung**: Geburtstage, Feiertage, „Messe-Woche”, „Peter im Homeoffice”. Würden sie als belegt übertragen, wäre der ganze Tag im Zielkalender geblockt — und niemand könnte dich buchen, obwohl du frei bist.
## Standard: als frei behandeln
[Abschnitt betitelt „Standard: als frei behandeln“](#standard-als-frei-behandeln)
Deshalb werden ganztägige Termine standardmäßig **als frei** übertragen: Sie erscheinen im Ziel, blockieren aber keine Zeit. So bleibt z. B. ein Feiertagskalender als Quelle völlig unproblematisch.
## Alternative: den ganzen Tag blockieren
[Abschnitt betitelt „Alternative: den ganzen Tag blockieren“](#alternative-den-ganzen-tag-blockieren)

Die Einstellung im Sichtbarkeits-Schritt: „Frei“ (Standard) oder „Blockiert“ — mit Live-Vorschau.
Soll ein ganztägiger Termin wirklich blocken (z. B. Urlaub), hast du zwei Möglichkeiten:
1. **Pro Sync umstellen**: Beim Erstellen im Schritt „Sichtbarkeit” die Karte **„Ganztägige Ereignisse”** aufklappen und statt „Frei” (Standard) die Variante **„Blockiert”** wählen. Gilt dann für *alle* ganztägigen Termine dieses Syncs; beim Zwei-Wege-Sync auch pro Richtung einstellbar.
2. **Pro Termin**: Den Urlaub als normalen Termin mit Uhrzeit anlegen (z. B. 0–24 Uhr oder 8–18 Uhr) — der wird immer als belegt übertragen, unabhängig von der Option.
Tipp: Wenn nur *einzelne* ganztägige Termine blocken sollen, ist Weg 2 meist der bessere — sonst blocken plötzlich auch alle Geburtstage.
## Nachträglich ändern
[Abschnitt betitelt „Nachträglich ändern“](#nachträglich-ändern)
Die Option lässt sich jederzeit nachträglich ändern: im Dashboard über das Drei-Punkte-Menü der Freigabe → **„Bearbeiten“** → „Erweiterte Einstellungen“. Die bestehenden Kopien im Zielkalender werden automatisch angepasst → [Freigabe bearbeiten](/sync/freigabe-bearbeiten/).
# Terminfarben übernehmen
> Farben in den synchronisierten Terminen: wie in der Quelle (Google-Farben, Outlook-Kategorien, CalDAV) oder eine Farbe je Quellkalender.
Viele färben Termine nach Art oder Person ein, z. B. Montage grün, Kundentermine rot. Andere wollen im Zielkalender einfach sehen, aus welchem Kalender ein Termin stammt. Beides geht mit **„Terminfarben übernehmen“**.
Die Option gibt es ab dem Tarif **Basic**, für eigene Syncs und für Freigaben an andere Personen, in jede Richtung und bei jeder Sichtbarkeit.
## Die drei Einstellungen
[Abschnitt betitelt „Die drei Einstellungen“](#die-drei-einstellungen)
| Einstellung | Was im Zielkalender passiert |
| -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| **Aus** | Alle Kopien in der Farbe des Zielkalenders. |
| **Wie in der Quelle** | Jede Kopie behält ihre Farbe und deren Namen, z. B. „Rene Termin“ in Rot. |
| **Eine Farbe je Kalender** | Jede Kopie bekommt die Farbe ihres Quellkalenders, z. B. alles aus „Arbeit“ blau, alles aus „Verein“ grün. Die Farbe heißt wie der Kalender. |
## So funktioniert’s
[Abschnitt betitelt „So funktioniert’s“](#so-funktionierts)
1. Beim Einrichten des Syncs (oder später über **„Bearbeiten“**) die Karte **„Terminfarben übernehmen“** aufklappen.
2. Eine der drei Einstellungen wählen. Bei neuen eigenen Syncs ist **„Wie in der Quelle“** schon gewählt, außer bei der Sichtbarkeit **„Nur belegt“**. Bei Freigaben an andere Personen ist die Option zunächst aus.
3. **Wie in der Quelle:** Die Karte zeigt die Farben, die in den nächsten vier Monaten vorkommen. Ein Klick auf eine Farbe benennt sie im Zielkalender um.
4. **Eine Farbe je Kalender:** Ein Klick auf einen Kalender wählt seine Farbe aus den 24 Google-Farben und, falls gewünscht, einen anderen Namen.
Bereits synchronisierte Termine werden danach automatisch neu geschrieben.

„Wie in der Quelle“: Die Karte zeigt, welche Farben in deinen Kalendern vorkommen. Fehlende Kategorien legt Kalender Sync in Outlook an (+), ein Klick auf eine Farbe benennt sie um.

„Eine Farbe je Kalender“: Jeder Quellkalender bekommt eine Farbe, die wie der Kalender heißt. Ein Klick auf einen Kalender ändert Farbe oder Name.
## Wie die Farbe übertragen wird
[Abschnitt betitelt „Wie die Farbe übertragen wird“](#wie-die-farbe-übertragen-wird)
Eine Farbe kommt **mit ihrem Namen** an. Fehlt der Name, nehmen wir den Google-Farbnamen, z. B. „Basilikum“ oder „Kakao“.
| Kalender | So kommt die Farbe an |
| ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Google** | als Google-Farbe (Label) mit demselben Namen. Fehlt sie im Zielkalender, legen wir sie an: alle 24 Google-Farben und eigene Farben. |
| **Outlook / Microsoft 365** | als **Kategorie** mit demselben Namen. Outlook kennt 25 Kategoriefarben; wir nehmen die ähnlichste. |
| **CalDAV** (z. B. Disroot, GMX, WEB.DE, mailbox.org) | als Farbangabe des Termins (`COLOR`) |
| **Apple iCloud** | nicht möglich: Apple Kalender kennt nur Kalenderfarben, keine Farben pro Termin. Für iCloud-Zielkalender wird die Option deshalb nicht angeboten. |
Bei CalDAV entscheidet das Kalenderprogramm, ob es die Farbe anzeigt. Nextcloud und Evolution zeigen sie an, DAVx5 nach dem Einschalten in den Einstellungen.
## Outlook: Kategorien
[Abschnitt betitelt „Outlook: Kategorien“](#outlook-kategorien)
* **Gibt es die Kategorie schon**, weisen wir sie nur zu. Deine Farbe dafür bleibt.
* **Fehlt sie**, legen wir sie mit der passenden Farbe an. Outlook zeigt neu angelegte Kategorien manchmal erst nach einigen Stunden farbig an, bis dahin erscheinen sie grau.
* **Umbenennen bitte in Kalender Sync**, nicht in Outlook. Benennst du eine Kategorie in Outlook um, legen wir den alten Namen beim nächsten Abgleich wieder an. Die **Farbe** einer Kategorie kannst du dagegen jederzeit in Outlook ändern (Einstellungen › Konto › Kategorien).
* **Deine eigenen Kategorien bleiben:** Setzt du selbst eine Kategorie an einen synchronisierten Termin, entfernen wir sie nicht.
* **Von Outlook zu Google:** In Outlook gibst du einem Termin über „Kategorisieren“ eine Kategorie. In Google kommt sie als Farbe mit demselben Namen an.
### Erlaubnis für Outlook-Kategorien
[Abschnitt betitelt „Erlaubnis für Outlook-Kategorien“](#erlaubnis-für-outlook-kategorien)
Meist legt Kalender Sync Kategorien ohne weitere Schritte an. Verlangt Microsoft eine zusätzliche Erlaubnis, erscheint der Button **„Erlaubnis erteilen“**:
* bei eigenen Syncs in **„Bearbeiten“**, bei einem Outlook-zu-Outlook-Sync für beide Postfächer,
* bei Freigaben an dich **im Dashboard**: Nur du kannst die Erlaubnis für dein Postfach erteilen.
Andere Postfacheinstellungen lesen oder ändern wir nicht. Ohne Erlaubnis läuft der Sync ganz normal weiter, nur ohne Farben. Verlangt deine Organisation die Zustimmung der IT, findet deine IT-Abteilung die Details unter [Für IT-Admins](https://kalender-sync.de/it-admin/).
### Google-Farben im Zielkalender
[Abschnitt betitelt „Google-Farben im Zielkalender“](#google-farben-im-zielkalender)
Neue Google-Farben (Labels) darf nur anlegen, wem der Zielkalender gehört. Ist er nur für dich freigegeben, verwenden wir die ähnlichste der 11 klassischen Google-Farben.
## Freigaben an andere Personen
[Abschnitt betitelt „Freigaben an andere Personen“](#freigaben-an-andere-personen)
Teilst du deinen Kalender mit jemandem, entscheidest du, ob Farben mitkommen. Bei **„Wie in der Quelle“** sieht die andere Person auch die Farbnamen, z. B. „Arzt“. Bei **„Eine Farbe je Kalender“** sieht sie nur, aus welchem deiner Kalender ein Termin stammt. Die andere Person erfährt schon in der Einladung, dass Farben mitkommen.
## Gut zu wissen
[Abschnitt betitelt „Gut zu wissen“](#gut-zu-wissen)
* **Ausschalten:** Bereits übertragene Farben bleiben an den Kopien stehen.
* **In beide Richtungen gleich:** Bei einem Zwei-Wege-Sync kommt eine Farbe mit demselben Namen zurück.
* **Per KI-Assistent:** `create_sync` übernimmt Farben mit derselben Voreinstellung wie die App, `list_syncs` zeigt die Einstellung an. Ändern geht in der App → [Syncs per Assistent](/ki-assistent/syncs/).
# Freigabe bearbeiten
> Bestehende Syncs nachträglich ändern: Quellkalender, Zielkalender, Sichtbarkeit, Platzhalter-Titel und Präfix — ohne den Sync neu anzulegen.
Bestehende Syncs lassen sich **nachträglich bearbeiten** — du musst nichts mehr beenden und neu anlegen. Öffne im Dashboard das **Drei-Punkte-Menü** der Freigabe und wähle **„Bearbeiten”**.
## Was du ändern kannst
[Abschnitt betitelt „Was du ändern kannst“](#was-du-ändern-kannst)
| Einstellung | Beschreibung |
| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Quellkalender** | Kalender hinzufügen oder entfernen. Neue Quellen werden vollständig nachsynchronisiert (auch bestehende Termine), entfernte Quellen räumen ihre Kopien im Zielkalender automatisch ab. |
| **Zielkalender** | Bei eigenen Syncs den Zielkalender wechseln. Die Kopien werden aus dem alten Ziel entfernt und in den neuen Kalender übertragen. |
| **Sichtbarkeit** | Zwischen „Nur belegt”, „Titel + Zeit” und „Alle Details” wechseln — siehe [Sichtbarkeits-Stufen](/sync/visibility-levels/). |
| **Platzhalter-Titel** | Den Text ändern, der bei „Nur belegt” statt „Geblockt” angezeigt wird — siehe [Platzhalter-Titel](/sync/placeholder-title/). |
| **Präfix** | Pro Quellkalender ein Titel-Präfix setzen, ändern oder entfernen — siehe [Präfix im Zielkalender](/sync/source-prefix/). |
| **Ganztägige Termine** | Unter „Erweiterte Einstellungen”: ob ganztägige Termine den Tag blockieren — siehe [Ganztägige Termine](/sync/all-day-events/). |
| **Terminfarben** | Aus, wie in der Quelle oder eine Farbe je Kalender; einzelne Farben im Ziel umbenennen. Bei Zwei-Wege-Syncs gilt eine Einstellung für beide Richtungen — siehe [Terminfarben übernehmen](/sync/event-colors/). |
Die **Sync-Vorschau** rechts im Dialog zeigt live, wie die Termine mit den neuen Einstellungen im Zielkalender aussehen werden.
## Was nach dem Speichern passiert
[Abschnitt betitelt „Was nach dem Speichern passiert“](#was-nach-dem-speichern-passiert)
Nach dem Speichern zeigt die Freigabe kurz **„Wird aktualisiert…”**: Kalender-Sync schreibt alle bereits synchronisierten Kopien im Hintergrund mit den neuen Einstellungen neu. Je nach Kalendergröße dauert das ein paar Sekunden bis wenige Minuten — du musst nichts weiter tun.
* Deine **Originaltermine bleiben immer unverändert** — es werden nur die synchronisierten Kopien im Zielkalender angepasst.
* Wechselst du auf eine **striktere Sichtbarkeit** (z. B. von „Alle Details” auf „Nur belegt”), werden auch ältere Kopien außerhalb des [Sync-Zeitfensters](/sync/sync-window/) entfernt, damit nirgendwo mehr Details stehen als gewünscht.
* Beim **Zielkalender-Wechsel** ist die Freigabe während des Umzugs kurz pausiert und kommt automatisch zurück.
## Besonderheiten
[Abschnitt betitelt „Besonderheiten“](#besonderheiten)
* **Zwei-Wege-Sync**: Sichtbarkeit, Platzhalter, Präfix und Ganztags-Option lassen sich **pro Richtung** einstellen. Die beiden Kalender selbst sind beim Zwei-Wege-Sync fest — dafür beenden und neu anlegen.
* **Freigaben an andere Personen**: Die Quellen und alle Darstellungs-Optionen kannst du bearbeiten; der Zielkalender gehört der Empfängerseite und bleibt fest.
* **Nicht erreichbare Quellkalender** (z. B. beim Anbieter gelöscht) erscheinen in der Liste mit dem Hinweis „nicht erreichbar” und lassen sich abwählen — so tauschst du eine tote Quelle gegen eine neue, ohne den Sync zu verlieren.
# So funktioniert der Sync
> Richtung, Geschwindigkeit und Sicherheitsnetz — was im Hintergrund passiert, wenn sich ein Termin ändert.
Jeder Sync arbeitet nach demselben Prinzip: Aus einem oder mehreren **Quellkalendern** fließen Belegungen in einen **Zielkalender**. Dort legt Kalender Sync eigene **Blocker-Termine** an — und verwaltet ausschließlich diese.

Das Dashboard: verbundene Kalender oben, die aktiven Syncs darunter.
## Immer in eine Richtung
[Abschnitt betitelt „Immer in eine Richtung“](#immer-in-eine-richtung)
* Jeder Sync überträgt von **Quelle → Ziel**. Sollen sich zwei Kalender **gegenseitig** blocken, richtest du ihn [in beide Richtungen](/sharings/self-sync/) ein.
* Deine **Originaltermine werden nie verändert** — egal was passiert. Kalender Sync fasst nur die eigenen Blocker an.
* Termin in der Quelle **verschoben**? Der Blocker zieht mit. **Gelöscht**? Der Blocker verschwindet.
## Wie schnell ist der Sync?
[Abschnitt betitelt „Wie schnell ist der Sync?“](#wie-schnell-ist-der-sync)
| Quelle | Mechanismus | Tempo |
| ----------------------------------------------------------------------------------- | ------------------------------------------- | ---------------------------------------------------------------- |
| Google, Microsoft | Anbieter meldet Änderungen aktiv (Webhooks) | **nahezu sofort** (in allen Plänen) — typisch unter einer Minute |
| Apple iCloud, GMX, WEB.DE, mailbox.org, Posteo, STRATO, Disroot, KSuite, iCal-Feeds | Regelmäßiger Abruf (Polling) | **alle 5 Minuten** |
Hinweis
Die Echtzeit-Übertragung per Webhook für Google und Microsoft ist in **allen Plänen** aktiv – auch im Free-Plan. Apple iCloud, GMX, WEB.DE, mailbox.org, Posteo, STRATO, Disroot, KSuite und iCal-Feeds (ab Basic) werden alle 5 Minuten abgefragt.
Dazu kommt ein **Sicherheitsnetz**: Alle paar Stunden gleicht Kalender Sync jeden Sync komplett ab und fängt so auch verpasste Änderungen ein (z. B. wenn eine Anbieter-Benachrichtigung verloren ging). Fehlt ein Termin also scheinbar — oft löst sich das von selbst beim nächsten Abgleich. Wenn nicht: [Termin fehlt, doppelt oder verspätet](/troubleshooting/event-missing-or-duplicate/).
Die **erste Synchronisation** nach dem Einrichten arbeitet den Bestand auf und kann je nach Terminanzahl einige Minuten dauern (bei großen Kalendern bis zu einer halben Stunde) — du bekommst eine E-Mail, sobald sie fertig ist.
## Was synchronisiert wird — und was nicht
[Abschnitt betitelt „Was synchronisiert wird — und was nicht“](#was-synchronisiert-wird--und-was-nicht)
* Synchronisiert werden Termine im [Zeitfenster](/sync/sync-window/): **3 Monate in die Vergangenheit; in die Zukunft abhängig vom Plan: 6 Monate (Free & Basic) bzw. 18 Monate (Professional)**.
* Wie viel Inhalt ankommt, bestimmt die [Sichtbarkeitsstufe](/sync/visibility-levels/) — von „Nur belegt” bis volle Details.
* **Nie übertragen**: Teilnehmerlisten, E-Mail-Adressen, Organisator:innen, Zu-/Absagen. [Ganztägige Termine](/sync/all-day-events/) werden standardmäßig als frei behandelt.
## Schutz vor Schleifen und Duplikaten
[Abschnitt betitelt „Schutz vor Schleifen und Duplikaten“](#schutz-vor-schleifen-und-duplikaten)
Kalender Sync markiert jeden selbst erstellten Blocker und synchronisiert ihn **nie weiter** — es entsteht kein Ping-Pong zwischen gekoppelten Kalendern und keine Duplikate, auch nicht in [Ketten-Setups](/sync/multi-account-setups/) über drei und mehr Kalender.
## Beim Pausieren und Beenden
[Abschnitt betitelt „Beim Pausieren und Beenden“](#beim-pausieren-und-beenden)
* **Pausiert**: Der Sync stoppt, bestehende Blocker bleiben stehen. Beim Fortsetzen wird der Stand abgeglichen.
* **Beendet**: Alle von Kalender Sync erstellten Blocker im Ziel werden **automatisch aufgeräumt**. Details: [Sync pausieren oder beenden](/sharings/pause-end/).
# Mehrere Konten & Ketten-Setups
> Stern, Kette oder Kreuz — wie komplexe Setups über mehrere Kalender sauber funktionieren.
Mit mehreren verbundenen Konten kannst du Syncs beliebig kombinieren — Kalender Sync sorgt dafür, dass dabei keine Schleifen oder Duplikate entstehen.
## Typische Setups
[Abschnitt betitelt „Typische Setups“](#typische-setups)
**Stern — einer blockt viele:**
```text
Privat ──→ Arbeitskalender A
Privat ──→ Arbeitskalender B
```
Ein Sync pro Ziel.
**Bündel — mehrere Quellen blocken ein Ziel:**
```text
Privat ──┐
Verein ──┼──→ Arbeitskalender
Familie ─┘
```
Dafür reicht **ein** Sync mit [mehreren Quellkalendern](/sharings/multiple-sources/) — alle Belegungen landen gebündelt im Ziel.
**Kreuz — zwei Kalender blocken sich gegenseitig:**
```text
Arbeit ⇄ Privat
```
Das ist ein [Zwei-Wege-Sync](/sharings/self-sync/) — er zählt fürs Plan-Limit als **ein** Sync.
**Kette / Hub — alles läuft in einem Kalender zusammen:**
```text
iCloud ──→ Outlook ──→ Google
```
Outlook ist hier der „Hub”: Er empfängt aus iCloud und speist gleichzeitig Google. Auch solche Ketten sind ausdrücklich erlaubt.
## Warum das sicher ist
[Abschnitt betitelt „Warum das sicher ist“](#warum-das-sicher-ist)
Kalender Sync markiert jeden selbst erstellten Blocker und **synchronisiert ihn nie weiter**:
* Kein Ping-Pong: Beim Kreuz-Setup wandert ein Termin von A nach B — aber der Blocker in B wird nicht zurück nach A gespiegelt.
* Keine Lawinen: In der Kette erzeugt der iCloud-Termin einen Blocker in Outlook, aber dieser Blocker fließt **nicht** weiter nach Google. Soll der Termin auch Google blocken, lege einen direkten Sync iCloud → Google an.
* **Nicht möglich** ist nur ein Kalender als Quelle *und* Ziel desselben Syncs (A → A).
## Tipps für die Planung
[Abschnitt betitelt „Tipps für die Planung“](#tipps-für-die-planung)
* Skizziere zuerst, **wer wen blocken soll** — pro Pfeil ein Sync (ein Doppelpfeil = ein Zwei-Wege-Sync).
* Blocker sollen nicht weitergereicht werden (siehe oben) — plane also **direkte** Syncs von jeder Quelle zu jedem Ziel, statt auf Ketten-Weiterleitung zu hoffen.
* Die Anzahl an Konten und Syncs hängt von deinem Plan ab → [Pläne & Limits](/account-billing/plans-limits/).
* Für Zwei-Wege-Syncs brauchst du **genau zwei beschreibbare** Kalender (iCal-Feeds sind z. B. nur lesbar und können kein Ziel sein).
# Platzhalter-Titel anpassen
> Den Standard-Titel der Blocker-Termine durch einen eigenen Text ersetzen.
Bei der Sichtbarkeitsstufe **„Nur belegt”** tragen die Blocker im Zielkalender einen neutralen Standard-Titel („Geblockt”). Wenn dir das zu generisch ist, setzt du pro Sync einen eigenen **Platzhalter-Titel**.
## So funktioniert’s
[Abschnitt betitelt „So funktioniert’s“](#so-funktionierts)
1. Beim Einrichten des Syncs im Schritt **„Sichtbarkeit”** die Stufe **„Nur belegt”** wählen.
2. Darunter erscheint das Feld **„Platzhalter-Titel”** (optional) — z. B. „Termin”, „Privat” oder „Extern” eintragen.
3. Alle Blocker dieses Syncs tragen künftig diesen Titel.
Bei anderen Sichtbarkeitsstufen gibt es kein Platzhalter-Feld — dort wird ja der echte Terminname übertragen.
## Wofür ein eigener Titel nützlich ist
[Abschnitt betitelt „Wofür ein eigener Titel nützlich ist“](#wofür-ein-eigener-titel-nützlich-ist)
* **Mehrere Syncs in denselben Zielkalender**: „Privat” und „Nebenprojekt” lassen sich unterscheiden, „Geblockt” und „Geblockt” nicht.
* **Kontext für die Empfängerseite**, ohne Details preiszugeben: „Extern gebucht” sagt genug.
* **Beim Zwei-Wege-Sync** kannst du den Titel pro Richtung anders setzen.
## Nachträglich ändern
[Abschnitt betitelt „Nachträglich ändern“](#nachträglich-ändern)
Der Platzhalter-Titel lässt sich jederzeit **nachträglich ändern**: Drei-Punkte-Menü der Freigabe → **„Bearbeiten”** — die Blocker im Zielkalender werden automatisch mit dem neuen Titel neu geschrieben → [Freigabe bearbeiten](/sync/freigabe-bearbeiten/).
# Wiederkehrende Termine
> Wie Serientermine synchronisiert werden — inklusive Ausnahmen, Verschiebungen und Serienende.
Serientermine (täglich, wöchentlich, monatlich …) werden vollständig synchronisiert — jede Wiederholung blockt die richtige Zeit im Ziel, und Änderungen an der Serie ziehen automatisch nach.
## Was zuverlässig funktioniert
[Abschnitt betitelt „Was zuverlässig funktioniert“](#was-zuverlässig-funktioniert)
* **Jede Wiederholung blockt korrekt** — mit Titel und Details gemäß deiner [Sichtbarkeitsstufe](/sync/visibility-levels/).
* **Ausnahmen**: Fällt eine einzelne Instanz aus oder wird verschoben, spiegelt sich das im Ziel wider.
* **Serienänderungen**: Änderst du die ganze Serie in der Quelle (z. B. neuer Wochentag), werden die Blocker entsprechend aktualisiert.
* **Serienende**: Endet oder löschst du die Serie, verschwinden die Blocker.
## Wiederholungen in der fernen Zukunft
[Abschnitt betitelt „Wiederholungen in der fernen Zukunft“](#wiederholungen-in-der-fernen-zukunft)
Blocker existieren für Wiederholungen innerhalb des [Sync-Zeitfensters](/sync/sync-window/) (bis 6 Monate voraus, im Professional-Plan 18 Monate). Weitere Wiederholungen erscheinen **automatisch**, sobald sie ins Fenster rücken — eine endlose Wochenserie füllt das Ziel also nie bis ins Jahr 2030.
## Eine Wiederholung fehlt?
[Abschnitt betitelt „Eine Wiederholung fehlt?“](#eine-wiederholung-fehlt)
Meist eine Frage des Zeitfensters oder der Sync-Latenz → [Termin fehlt, doppelt oder verspätet](/troubleshooting/event-missing-or-duplicate/). Bleibt es dabei, [melde dich](/troubleshooting/contact-support/) mit einem Beispieltermin.
# Präfix im Zielkalender
> Synchronisierte Termine mit einem Titel-Präfix kennzeichnen, z. B. „Arbeit: Besprechung".
Wenn mehrere Kalender in denselben Zielkalender synchronisieren, sieht man einem Termin nicht an, woher er stammt. Mit dem **Präfix im Zielkalender** bekommt jeder synchronisierte Termin einen kurzen Zusatz vor dem Titel — aus „Besprechung” wird z. B. **„Arbeit: Besprechung”**.
## So funktioniert’s
[Abschnitt betitelt „So funktioniert’s“](#so-funktionierts)
1. Beim Einrichten des Syncs im Schritt **„Sichtbarkeit”** die Stufe **„Titel + Zeit”** oder **„Alle Details”** wählen.
2. Die Option **„Präfix im Zielkalender anzeigen”** aktivieren.
3. Ein kurzes Präfix eintragen — z. B. „Arbeit”, „Privat” oder den Namen der Kanzlei. Bei mehreren Quellkalendern kannst du pro Kalender ein eigenes Präfix setzen.
4. Die Sync-Vorschau rechts zeigt sofort, wie die Termine im Zielkalender aussehen werden.

Ein-Wege-Sync: Präfix „Arbeit“ aktiviert — die Sync-Vorschau rechts zeigt „Arbeit: Mandantentermin“ im Zielkalender.
Beim **Zwei-Wege-Sync** setzt du das Präfix pro Richtung — z. B. „Arbeit” für Termine, die in den Privatkalender geschrieben werden, und „Privat” für die Gegenrichtung.

Zwei-Wege-Sync: eigenes Präfix pro Richtung — im Privat-Kalender landet „Arbeit: Mandantentermin“, im Arbeits-Kalender „Privat: Teammeeting“.
## Regeln im Detail
[Abschnitt betitelt „Regeln im Detail“](#regeln-im-detail)
* **Format**: `Präfix: Terminname`, das Präfix darf bis zu **30 Zeichen** lang sein.
* **Länge**: Wird der kombinierte Titel länger als **250 Zeichen**, kürzen wir ihn am Ende mit „…” — sonst lehnen manche Kalender (v. a. Outlook) den Termin ab.
* **Sichtbarkeit**: Das Präfix steht im Termintitel und ist damit für **alle sichtbar**, die den Zielkalender sehen können.
* **Bei „Nur belegt” gibt es kein Präfix** — dort übernimmt der [Platzhalter-Titel](/sync/placeholder-title/) diese Rolle.
* **Fester Text**: Das Präfix ist ein eigener Text, kein Live-Verweis auf den Kalendernamen. Wenn du den Quellkalender später umbenennst, bleibt das Präfix unverändert — so sehen alle Termine einheitlich aus.
* Funktioniert mit allen Anbietern (Google, Microsoft, Apple/CalDAV, iCal-Feeds als Quelle).
## Nachträglich ändern
[Abschnitt betitelt „Nachträglich ändern“](#nachträglich-ändern)
Das Präfix lässt sich jederzeit nachträglich setzen, ändern oder entfernen: im Dashboard über das Drei-Punkte-Menü der Freigabe → **„Bearbeiten“**. Die bereits synchronisierten Termine im Zielkalender werden automatisch mit dem neuen Präfix neu geschrieben → [Freigabe bearbeiten](/sync/freigabe-bearbeiten/).
# Sync-Zeitfenster
> Warum Termine in einem Zeitfenster synchronisiert werden — 3 Monate zurück für alle, voraus je nach Plan 6 oder 18 Monate.
Kalender Sync synchronisiert Termine in einem Zeitfenster: **3 Monate in die Vergangenheit** für alle — **in die Zukunft abhängig vom Plan: 6 Monate (Free & Basic) bzw. 18 Monate (Professional)**. Beim Einrichten eines Syncs wird dir das als Zeitstrahl angezeigt. Das Fenster wandert täglich mit.
## Warum ein Zeitfenster?
[Abschnitt betitelt „Warum ein Zeitfenster?“](#warum-ein-zeitfenster)
* **Datensparsamkeit**: Termine von vor zwei Jahren blocken niemanden mehr — sie zu übertragen wäre unnötige Datenverarbeitung.
* **Performance**: Auch sehr volle Kalender (tausende Termine) bleiben flott synchronisiert.
## Was das praktisch bedeutet
[Abschnitt betitelt „Was das praktisch bedeutet“](#was-das-praktisch-bedeutet)
* Ein Termin **in 8 Monaten**: Im Free- und Basic-Plan fehlt er zunächst im Ziel — das ist normal. Sobald er in das 6-Monats-Fenster rückt, erscheint er **automatisch**, du musst nichts tun. Im Professional-Plan ist er bereits synchronisiert, weil er im 18-Monats-Fenster liegt.
* **Alte Termine** (älter als 3 Monate) werden nicht übertragen — beim Erstsync wundert das manchmal („wo ist letztes Jahr?”), ist aber gewollt.
* Bei [Serienterminen](/sync/recurring-events/) existieren im Ziel die Wiederholungen innerhalb des Fensters; weitere kommen automatisch nach.
## Lässt sich das Fenster ändern?
[Abschnitt betitelt „Lässt sich das Fenster ändern?“](#lässt-sich-das-fenster-ändern)
Der Professional-Plan erweitert das Fenster in die Zukunft bereits auf **18 Monate** — für Buchungen weit im Voraus (z. B. 9 Monate) ist das der direkte Weg. Ein frei konfigurierbares Zeitfenster pro Sync bleibt darüber hinaus geplant ([Bekannte Einschränkungen](/troubleshooting/known-limitations/)). Wenn dich ein konkreter Fall blockiert, [schreib uns](/troubleshooting/contact-support/) — das hilft uns beim Priorisieren.
# Sichtbarkeitsstufen
> Nur belegt, Titel + Zeit oder volle Details — was beim Sync übertragen wird und was nie.
Pro Sync legst du fest, wie viel die Empfängerseite von deinen Terminen sieht. Das ist das Herzstück des Datenschutz-Konzepts: Du teilst **Verfügbarkeit**, nicht zwangsläufig Inhalte.

Die Auswahl beim Erstellen — die Vorschau rechts zeigt live, was ankommt.
## Die drei Stufen
[Abschnitt betitelt „Die drei Stufen“](#die-drei-stufen)
| Stufe | Was im Ziel ankommt | Typischer Einsatz |
| ------------------------- | --------------------------------------------------------------------------------------------- | ----------------------------------------------------------- |
| **Nur belegt** (Standard) | Nur der Zeitraum, als Titel „Geblockt” oder dein [Platzhalter-Text](/sync/placeholder-title/) | Privates blockt den Arbeitskalender — maximale Privatsphäre |
| **Titel + Zeit** | Terminname sowie Start- und Endzeit | Eigene Kalender koppeln, enge Team-Koordination |
| **Alle Details** | Inkl. Ort, Beschreibung, Notizen und Links | Assistenz, gemeinsame Terminverwaltung |
Beim [Zwei-Wege-Sync](/sharings/self-sync/) kannst du die Stufe **pro Richtung** unterschiedlich wählen.
## Was nie übertragen wird
[Abschnitt betitelt „Was nie übertragen wird“](#was-nie-übertragen-wird)
Unabhängig von der Stufe bleiben außen vor:
* **Teilnehmerlisten und deren E-Mail-Adressen** — das sind Daten Dritter
* **Organisator:innen** und **Zu-/Absage-Status**
* Anhänge
Mehr zum Datenschutz-Konzept: [Sicherheit & Datenschutz im Überblick](/privacy-it/security-overview/).
## Festlegen und ändern
[Abschnitt betitelt „Festlegen und ändern“](#festlegen-und-ändern)
Die Stufe wählst du **beim Einrichten** des Syncs im Schritt „Sichtbarkeit” — und kannst sie jederzeit **nachträglich ändern**: Drei-Punkte-Menü der Freigabe → **„Bearbeiten”**. Die Kopien im Zielkalender werden automatisch mit der neuen Stufe neu geschrieben → [Freigabe bearbeiten](/sync/freigabe-bearbeiten/).
## Welche Stufe für welchen Fall?
[Abschnitt betitelt „Welche Stufe für welchen Fall?“](#welche-stufe-für-welchen-fall)
* **Im Zweifel: „Nur belegt”.** Es erfüllt den Hauptzweck — keine Doppelbuchungen — ohne irgendetwas preiszugeben. Hochstufen kannst du immer noch.
* **„Titel + Zeit”**, wenn die Gegenseite wissen soll, *was* dich blockt (z. B. deine eigenen zwei Kalender oder ein enges Team).
* **„Alle Details”** nur, wenn die Empfängerseite mit deinen Terminen *arbeiten* muss (Assistenz, Co-Founder).
# Verbindung schlägt fehl
> Ein Kalender lässt sich nicht verbinden — schnelle Triage der häufigsten Ursachen.
Das Verbinden eines Kalenderkontos bricht ab oder endet mit einer Fehlermeldung? Hier die schnelle Triage.
## Nach Fehlerbild
[Abschnitt betitelt „Nach Fehlerbild“](#nach-fehlerbild)
| Du siehst … | Ursache & Lösung |
| --------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| „Zustimmung des Administrators erforderlich” / „Need admin approval” (Microsoft) | Deine Organisation blockiert Dritt-Apps — der häufigste Fall → [drei Auswege](/connect-calendar/org-blocked/) |
| „App blockiert” / „nicht vom Administrator überprüft” (Google Workspace) | Gleiches Thema auf Google-Seite → [drei Auswege](/connect-calendar/org-blocked/) |
| „Anmeldung fehlgeschlagen” (Apple / KSuite) | Fast immer das falsche Passwort: Es braucht ein **app-spezifisches Passwort**, nicht dein normales → [Apple](/connect-calendar/apple-icloud/), [KSuite](/connect-calendar/ksuite/) |
| „Feed konnte nicht hinzugefügt werden” (iCal) | URL prüfen: erreichbar? Wirklich eine `.ics`-/`webcal`-Adresse? Nur HTTPS wird akzeptiert → [iCal-Feed](/connect-calendar/ical-feed/) |
| „Der Kalender konnte bei deinem Anbieter nicht angelegt werden” (beim Einrichten eines Syncs) | Der Anbieter — praktisch immer Infomaniak/KSuite — hat den neuen Zielkalender nicht übernommen. Kalender direkt beim Anbieter anlegen und im Assistenten als vorhandenen Kalender wählen → [KSuite-Anleitung](/connect-calendar/ksuite/) |
| „Der Kalender ‚…‘ existiert bei deinem Anbieter nicht mehr” (beim Einrichten eines Syncs) | Der gewählte Kalender wurde beim Anbieter gelöscht, war aber noch in der Auswahl gelistet. Kalenderliste aktualisieren und einen anderen Kalender wählen |
| Limit-Hinweis im Verbinden-Dialog | Konten-Limit deines Plans erreicht → [Pläne & Limits](/account-billing/plans-limits/) |
## Wenn der Login einfach „nicht durchgeht”
[Abschnitt betitelt „Wenn der Login einfach „nicht durchgeht”“](#wenn-der-login-einfach-nicht-durchgeht)
* **Falsches Konto erwischt**: Bei mehreren Google-/Microsoft-Konten im Browser genau auf die Kontoauswahl achten — im Zweifel privates Fenster.
* **Berechtigung abgelehnt**: Wenn du im Consent-Dialog Häkchen entfernst oder ablehnst, bricht die Verbindung ab — Vorgang wiederholen und alles bestätigen ([warum die Berechtigungen nötig sind](/privacy-it/permissions/)).
* **Pop-up-Blocker**: Das Anbieter-Fenster wird teils als Pop-up geöffnet — kurz erlauben und erneut versuchen.
## Verbindung steht, aber nichts passiert?
[Abschnitt betitelt „Verbindung steht, aber nichts passiert?“](#verbindung-steht-aber-nichts-passiert)
Dann ist es kein Verbindungs-, sondern ein Sync-Thema → [Sync funktioniert nicht — Checkliste](/troubleshooting/sync-not-working/)
# Support kontaktieren
> So erreichst du uns — und welche Angaben uns helfen, dir schnell zu helfen.
Du kommst mit der Doku nicht weiter? Dann melde dich — wir sind ein kleines Team, dafür liest deine Nachricht direkt der Gründer.
## Kontaktwege
[Abschnitt betitelt „Kontaktwege“](#kontaktwege)
* **E-Mail**:
* **Kontaktformular**: [kalender-sync.de/kontakt](https://kalender-sync.de/kontakt/)
* **In der App**: Der **Feedback**-Button in der Seitenleiste — ideal für Bugs und Feature-Wünsche, die Nachricht landet direkt bei uns.
## Diese Angaben beschleunigen die Lösung
[Abschnitt betitelt „Diese Angaben beschleunigen die Lösung“](#diese-angaben-beschleunigen-die-lösung)
Je konkreter, desto schneller können wir helfen:
* Die **E-Mail-Adresse deines Kontos**
* Welcher **Sync** betroffen ist (Quelle → Ziel, Anbieter)
* Ein **Beispieltermin**: Titel + Zeitpunkt, was du erwartet und was du beobachtet hast
* **Seit wann** das Problem besteht; gern ein Screenshot der Fehlermeldung
Achtung
Bitte **niemals Passwörter oder App-Passwörter** mitschicken — wir fragen nie danach und brauchen sie nicht.
## Vorher kurz prüfen
[Abschnitt betitelt „Vorher kurz prüfen“](#vorher-kurz-prüfen)
Die zwei schnellsten Selbsthilfen:
* [Sync funktioniert nicht — Checkliste](/troubleshooting/sync-not-working/)
* [Bekannte Einschränkungen](/troubleshooting/known-limitations/) — vielleicht ist es schon dokumentiert (und geplant)
# Termin fehlt, doppelt oder verspätet
> Einzelne Termine verhalten sich unerwartet — Symptome und ihre Ursachen.
Der Sync läuft grundsätzlich, aber einzelne Termine machen nicht mit? Hier die Symptome und ihre häufigsten Ursachen. (Kommt **gar nichts** an, starte mit der [Checkliste](/troubleshooting/sync-not-working/).)
## Ein Termin fehlt im Ziel
[Abschnitt betitelt „Ein Termin fehlt im Ziel“](#ein-termin-fehlt-im-ziel)
* **Außerhalb des Zeitfensters**: weiter in der Zukunft als dein Plan abdeckt (6 Monate bei Free & Basic, 18 Monate bei Professional) oder älter als 3 Monate → erscheint automatisch, sobald er ins [Fenster](/sync/sync-window/) rückt.
* **Ganztägiger Termin**: wird standardmäßig als frei übertragen → [Ganztägige Termine](/sync/all-day-events/).
* **Quelle nicht im Sync**: Liegt der Termin wirklich in einem der gewählten [Quellkalender](/sharings/multiple-sources/)?
* **Polling-Verzögerung**: Bei Apple/KSuite/iCal-Quellen bis zu 5 Minuten warten.
* **Wiederholung einer Serie**: erscheint erst, wenn sie ins Zeitfenster rückt → [Wiederkehrende Termine](/sync/recurring-events/).
Tipp: Das [Sicherheitsnetz](/sync/how-it-works/#wie-schnell-ist-der-sync) gleicht alle paar Stunden komplett ab — vieles löst sich dadurch von selbst.
## Ein Termin kommt verspätet
[Abschnitt betitelt „Ein Termin kommt verspätet“](#ein-termin-kommt-verspätet)
* Google/Microsoft-Quellen: typisch unter einer Minute (in allen Plänen). Apple/KSuite/iCal: bis zu 5 Minuten plus ggf. Anbieter-Caching (Outlook-Feeds sind träge).
* Dauerhaft langsamer? [Melde dich](/troubleshooting/contact-support/) mit einem konkreten Beispiel.
## Ein Termin erscheint doppelt
[Abschnitt betitelt „Ein Termin erscheint doppelt“](#ein-termin-erscheint-doppelt)
* **Zwei Syncs, ein Ziel**: Schreiben zwei Syncs denselben Quellkalender in denselben Zielkalender? Dann erzeugt jeder seinen eigenen Blocker — einen davon beenden.
* **Alt-Blocker eines beendeten Syncs**: Das Aufräumen läuft im Hintergrund und kann Minuten bis Stunden dauern → [Beenden](/sharings/pause-end/).
* Reproduzierbare echte Duplikate aus **einem** Sync sind ein Bug → [Support](/troubleshooting/contact-support/) mit Beispiel, wir schauen direkt nach.
## Ein Blocker bleibt stehen, obwohl der Quelltermin weg ist
[Abschnitt betitelt „Ein Blocker bleibt stehen, obwohl der Quelltermin weg ist“](#ein-blocker-bleibt-stehen-obwohl-der-quelltermin-weg-ist)
* Kurz warten: Löschungen kommen mit der nächsten Sync-Runde bzw. spätestens mit dem Sicherheitsnetz-Abgleich.
* **Blocker von Hand gelöscht/verschoben?** Andersherum gilt: Von Kalender Sync erstellte Blocker werden beim nächsten Abgleich wiederhergestellt — sie gehören der Quelle. Termin loswerden → in der **Quelle** löschen.
* Bleibt der Geister-Blocker dauerhaft: [Support](/troubleshooting/contact-support/) mit Titel + Zeitpunkt.
# Häufige Fragen (FAQ)
> Kurzantworten auf die häufigsten Fragen — mit Links zu den ausführlichen Artikeln.
## Sync & Termine
[Abschnitt betitelt „Sync & Termine“](#sync--termine)
**Wie schnell synchronisiert Kalender Sync?** In allen Plänen: Google/Microsoft nahezu sofort (Echtzeit-Webhook). Apple/KSuite/iCal (ab Basic): alle 5 Minuten. Dazu ein Sicherheitsnetz alle paar Stunden. → [Wie schnell ist der Sync?](/sync/how-it-works/#wie-schnell-ist-der-sync)
**Werden meine Originaltermine verändert?** Nein, nie. Kalender Sync legt nur eigene Blocker im Zielkalender an und verwaltet ausschließlich diese.
**Sehen andere meine Termindetails?** Nur was du erlaubst: „Nur belegt” (Standard), „Titel + Zeit” oder „Alle Details”. Teilnehmerdaten nie. → [Sichtbarkeitsstufen](/sync/visibility-levels/)
**Warum fehlt ein Termin aus dem nächsten Jahr?** Synchronisiert wird −3 Monate bis +6 Monate (Free & Basic) bzw. +18 Monate (Professional); er erscheint automatisch, sobald er ins Fenster rückt. → [Sync-Zeitfenster](/sync/sync-window/)
**Warum blockt mein Urlaub (ganztägig) nichts?** Ganztägige Termine werden standardmäßig als frei behandelt — umstellbar. → [Ganztägige Termine](/sync/all-day-events/)
**Warum sind meine Terminfarben grau oder kommen nicht an?** Prüf zuerst, ob **„Terminfarben übernehmen“** im Sync eingeschaltet ist (ab Basic; bei „Nur belegt“ und bei Freigaben an andere ist es zunächst aus). Outlook zeigt neu angelegte Kategorien manchmal erst nach einigen Stunden farbig an. Verlangt Microsoft eine zusätzliche Erlaubnis, steht unter **„Bearbeiten“** der Button **„Erlaubnis erteilen“**. In iCloud-Zielkalendern gibt es keine Farben pro Termin, bei CalDAV entscheidet dein Kalenderprogramm, ob es die Farbe anzeigt. Ist ein Google-Zielkalender nur für dich freigegeben, kommt die ähnlichste der 11 klassischen Google-Farben an. → [Terminfarben übernehmen](/sync/event-colors/)
## Konten & Anbieter
[Abschnitt betitelt „Konten & Anbieter“](#konten--anbieter)
**Welche Kalender werden unterstützt?** Google, Microsoft/Outlook, Apple iCloud, GMX, WEB.DE, mailbox.org, Posteo, STRATO, Disroot, Infomaniak KSuite und iCal-Feeds (als Quelle). → [Kalender verbinden](/getting-started/connect-first-calendar/)
**Meine Firma blockiert die Verbindung — was nun?** Drei Auswege: iCal-Feed (ab Basic), IT-Freigabe in 2 Minuten, oder App-Passwort/CalDAV bei iCloud, GMX, WEB.DE, mailbox.org, Posteo, STRATO, Disroot & KSuite. → [Organisation blockiert](/connect-calendar/org-blocked/)
**Apple fragt nach einem Passwort — mein normales geht nicht?** Richtig: Es braucht ein app-spezifisches Passwort (2 Minuten erstellt). → [Apple iCloud](/connect-calendar/apple-icloud/)
**Kann ich die Sichtbarkeit eines bestehenden Syncs ändern?** Über das Drei-Punkte-Menü der Freigabe → **„Bearbeiten“**: Quellen, Zielkalender, Sichtbarkeit, Platzhalter-Titel und Präfix lassen sich nachträglich ändern; die Kopien im Zielkalender werden automatisch neu geschrieben. → [Freigabe bearbeiten](/sync/freigabe-bearbeiten/)
## Konto & Bezahlung
[Abschnitt betitelt „Konto & Bezahlung“](#konto--bezahlung)
**Was passiert nach der Testphase?** Automatisch Free; überzählige Syncs werden pausiert. Bei Syncs eigener Kalender werden die kopierten Einträge nach 14 Tagen entfernt (deine Originale bleiben unberührt) — nach einem Upgrade wird alles aus deinen Originalkalendern wiederhergestellt. → [Testphase](/account-billing/trial/)
**Wie kündige ich?** Selbst, unter Einstellungen → Abrechnung — wirksam zum Periodenende, vorher widerrufbar. → [Kündigung](/account-billing/upgrade-cancel/)
**Wie lösche ich mein Konto samt Daten?** Selbst, unter Einstellungen → Daten — sofort und endgültig, inkl. Blocker-Aufräumen. → [Konto löschen](/account-billing/export-delete/)
## Datenschutz
[Abschnitt betitelt „Datenschutz“](#datenschutz)
**Wo werden meine Daten gespeichert?** In Deutschland (Hetzner) — und Termininhalte gar nicht. → [Sicherheit & Datenschutz](/privacy-it/security-overview/)
**Gibt es einen AVV?** Ja, nach Art. 28 DSGVO — für alle Tarife bei geschäftlicher Nutzung inklusive, Bestandteil der AGB: [kalender-sync.de/avv](https://kalender-sync.de/avv/). → [AVV & Unterauftragnehmer](/privacy-it/dpa-subprocessors/)
Deine Frage ist nicht dabei? Nutze die **Suche** oben — oder [frag uns direkt](/troubleshooting/contact-support/).
# Bekannte Einschränkungen
> Was Kalender Sync (noch) nicht kann — transparent dokumentiert, mit Status.
Wir dokumentieren Einschränkungen lieber offen, als dass du sie im Support erfragen musst. Was dich davon konkret blockiert, [sag uns gern](/troubleshooting/contact-support/) — das fließt direkt in die Priorisierung. *(Stand: Juli 2026)*
## Aktuelle Einschränkungen
[Abschnitt betitelt „Aktuelle Einschränkungen“](#aktuelle-einschränkungen)
| Einschränkung | Details | Status |
| -------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- |
| **Zwei-Wege-Sync: Kalender-Paar fest** | Optionen (Sichtbarkeit, Präfix, …) sind pro Richtung [bearbeitbar](/sync/freigabe-bearbeiten/); die beiden Kalender selbst lassen sich nicht tauschen — dafür beenden + neu anlegen | — |
| **Sync-Zeitfenster nicht frei wählbar** | −3 Monate zurück für alle; voraus +6 Monate (Free & Basic) bzw. +18 Monate (Professional) → [Details](/sync/sync-window/) | Frei konfigurierbar geplant |
| **Kein iCal-Export** | Kalender Sync kann Feeds **lesen**, aber noch keine eigene Feed-URL zum Abonnieren erzeugen — relevant für [blockierte Organisationen](/connect-calendar/org-blocked/) | Geplant |
| **E-Mail-Adresse nicht änderbar** | Die Adresse ist der Konto-Anker → [Workaround über den Support](/account-billing/profile-notifications/) | Geplant |
| **5-Minuten-Rhythmus bei Apple/KSuite/iCal** | Technische Grenze dieser Anbieter (kein Push) — Google/Microsoft laufen in allen Plänen nahezu sofort | Bleibt vorerst |
| **Keine Team-/Organisationskonten** | Jede:r Nutzer:in hat ein eigenes Konto; zentrale Verwaltung und Sammelabrechnung gibt es noch nicht | Auf der Roadmap |
## Feature-Wünsche
[Abschnitt betitelt „Feature-Wünsche“](#feature-wünsche)
Was als Nächstes kommt, steht auf der öffentlichen [Roadmap](https://kalender-sync.de/roadmap/) — dort kannst du auch abstimmen und Wünsche einreichen.
# Anmeldeprobleme
> Code kommt nicht an, Code ungültig, kein Zugriff mehr aufs Postfach — die Lösungen.
Der Login läuft über deine E-Mail-Adresse — per 6-stelligem Code, Passwort oder Google/Microsoft ([alle Wege erklärt](/getting-started/create-account/)). Hier die häufigsten Hänger.
## „Die Code-E-Mail kommt nicht an”
[Abschnitt betitelt „„Die Code-E-Mail kommt nicht an”“](#die-code-e-mail-kommt-nicht-an)
* **Spam-/Junk-Ordner** prüfen — gerade beim ersten Mal landet die Mail dort gern.
* **1–2 Minuten Geduld**: Manche Firmen-Postfächer (Sicherheits-Gateways, Quarantäne) stellen verzögert zu.
* **Tippfehler** in der E-Mail-Adresse? Einfach neu anfordern.
* Kommt dauerhaft nichts an: mit einer privaten Adresse testen — klappt es dort, hängt es am Firmen-Mailserver (IT fragen oder [Support kontaktieren](/troubleshooting/contact-support/)).
## „Code ungültig” oder „Code abgelaufen”
[Abschnitt betitelt „„Code ungültig” oder „Code abgelaufen”“](#code-ungültig-oder-code-abgelaufen)
* Codes sind **15 Minuten** gültig — danach einfach einen neuen anfordern.
* Mehrere Mails bekommen? Es zählt immer der Code aus der **neuesten**.
* Nach **5 falschen Eingaben** wird der Code entwertet („Zu viele Versuche”) — auch hier: neuen Code anfordern, kurz warten, falls das Anfordern selbst gebremst wird.
## „Passwort vergessen”
[Abschnitt betitelt „„Passwort vergessen”“](#passwort-vergessen)
Auf der Login-Seite **„Passwort vergessen?”** wählen — du setzt es per E-Mail-Code neu. Oder melde dich einfach gleich **„Lieber per Code”** an, ganz ohne Passwort.
## „Mit Google/Microsoft anmelden geht nicht”
[Abschnitt betitelt „„Mit Google/Microsoft anmelden geht nicht”“](#mit-googlemicrosoft-anmelden-geht-nicht)
* Gleiche E-Mail-Adresse wie bei der Registrierung? Die Anmeldewege führen nur dann ins selbe Konto.
* Fehlermeldung im Anbieter-Login (Org-Richtlinie)? Dann nutze den E-Mail-Code-Login — der funktioniert immer.
## „Ich komme nicht mehr an mein Postfach”
[Abschnitt betitelt „„Ich komme nicht mehr an mein Postfach”“](#ich-komme-nicht-mehr-an-mein-postfach)
Ohne Zugriff auf deine E-Mail-Adresse können wir dich nicht automatisch verifizieren — [kontaktiere den Support](/troubleshooting/contact-support/), wir finden gemeinsam einen Weg.
## Kein Passwortfeld beim Verbinden eines Assistenten
[Abschnitt betitelt „Kein Passwortfeld beim Verbinden eines Assistenten“](#kein-passwortfeld-beim-verbinden-eines-assistenten)
Im vereinfachten OAuth-Test meldest du dich mit Google, Microsoft oder einem E-Mail-Code an. Das gilt auch, wenn du bereits ein Passwort hast. Beim normalen App-Login bleibt dein Passwort gültig. Wenn kein Code ankommt, prüfe die E-Mail-Adresse und den Spam-Ordner; fordere nach Ablauf der Wartezeit einen neuen Code an.
# „Bitte neu verbinden" — Verbindung abgelaufen
> Warum eine Kalender-Verbindung abläuft und wie du sie in einer Minute erneuerst.
Zeigt ein Kalenderkonto im Dashboard **„Bitte neu verbinden”** (du bekommst dazu auch eine E-Mail), ist der Zugriff auf den Anbieter abgelaufen oder wurde widerrufen. Der Sync pausiert so lange — **es geht nichts verloren.**
## So verbindest du neu
[Abschnitt betitelt „So verbindest du neu“](#so-verbindest-du-neu)
1. Im Dashboard beim betroffenen Konto auf **„Erneut verbinden”** klicken.
2. Den Anbieter-Login durchlaufen (bzw. bei Apple/KSuite das App-Passwort neu eingeben — ggf. vorher ein [neues erstellen](/connect-calendar/apple-icloud/)).
3. Fertig — der Sync holt automatisch alles nach, was sich zwischenzeitlich geändert hat.
**Externe Freigabe?** Liegt der Zielkalender im Konto des Empfängers, muss **der Empfänger** sein Konto in seinem eigenen Kalender-Sync-Zugang neu verbinden. Der Absender sieht an der Freigabe den Status **„Reauth nötig”**, kann das Konto aber nicht selbst reparieren.
## Warum passiert das?
[Abschnitt betitelt „Warum passiert das?“](#warum-passiert-das)
* Du hast beim Anbieter das **Passwort geändert** oder den Zugriff **manuell widerrufen**.
* Eine **Sicherheitsrichtlinie deiner Organisation** hat die Zugriffe zurückgesetzt.
* Das **App-Passwort** (Apple/KSuite) wurde gelöscht oder ist abgelaufen.
## Es klappt trotzdem nicht?
[Abschnitt betitelt „Es klappt trotzdem nicht?“](#es-klappt-trotzdem-nicht)
* Fehlermeldung **im Anbieter-Login** („Zustimmung des Administrators erforderlich” o. Ä.) → [Meine Organisation blockiert die Verbindung](/connect-calendar/org-blocked/)
* Andere Verbindungsfehler → [Verbindung schlägt fehl](/troubleshooting/connection-fails/)
# Sync funktioniert nicht — Checkliste
> Schritt für Schritt zur Ursache, wenn keine Termine ankommen — nach Häufigkeit sortiert.
Es kommt nichts an? Geh diese Punkte der Reihe nach durch — sie sind nach Häufigkeit sortiert, meist ist es einer der ersten drei.
## Die Checkliste
[Abschnitt betitelt „Die Checkliste“](#die-checkliste)
1. **Erstsync noch nicht fertig?** Die erste Synchronisation kann je nach Terminanzahl einige Minuten bis zu einer halben Stunde dauern — du bekommst eine E-Mail, sobald sie durch ist.
2. **Verbindung in Ordnung?** Zeigt ein Kalenderkonto im Dashboard „Bitte neu verbinden”? Dann pausiert der Sync, bis du neu verbindest → [Verbindung abgelaufen](/troubleshooting/reconnect/)
3. **Sync pausiert?** Status im Dashboard prüfen — auch automatische Pausen durch [Trial-Ende oder Plan-Limit](/account-billing/trial/) (erkennbar am Schloss-Symbol).
4. **Einladung noch nicht angenommen?** Status „Ausstehend” heißt: Die Empfängerseite hat noch nicht angenommen — es wird noch nichts synchronisiert. Den Einladungslink kannst du im Dashboard erneut kopieren.
5. **Termin außerhalb des Zeitfensters?** Synchronisiert wird nur **3 Monate in die Vergangenheit; in die Zukunft abhängig vom Plan: 6 Monate (Free & Basic) bzw. 18 Monate (Professional)** → [Sync-Zeitfenster](/sync/sync-window/)
6. **Nur Geduld nötig?** Apple, KSuite und iCal-Feeds syncen **alle 5 Minuten**, nicht sekundenschnell → [Wie schnell ist der Sync?](/sync/how-it-works/#wie-schnell-ist-der-sync)
7. **Im richtigen Kalender nachgeschaut?** Gerade bei mehreren Konten: Ist das Ziel wirklich der Kalender, in den du gerade schaust? Wurde beim Annehmen ein **neuer** Kalender erstellt, muss der in deiner Kalender-App ggf. erst eingeblendet werden.
8. **Ganztägiger Termin?** Die werden standardmäßig **als frei** übertragen — und blocken nichts → [Ganztägige Termine](/sync/all-day-events/)
## Einzelne Termine fehlen oder doppelt?
[Abschnitt betitelt „Einzelne Termine fehlen oder doppelt?“](#einzelne-termine-fehlen-oder-doppelt)
Wenn der Sync grundsätzlich läuft, aber sich einzelne Termine seltsam verhalten → [Termin fehlt, doppelt oder verspätet](/troubleshooting/event-missing-or-duplicate/).
## Immer noch nichts?
[Abschnitt betitelt „Immer noch nichts?“](#immer-noch-nichts)
[Schreib uns](/troubleshooting/contact-support/) — am schnellsten geht’s mit Angabe des betroffenen Syncs, einem Beispieltermin (Titel + Zeitpunkt) und seit wann das Problem besteht.