Zum Inhalt springen

API: Arbeitsbereiche

GET /api/workspaces

Liefert alle Arbeitsbereiche, in denen du Mitglied bist, jeweils mit deiner Rolle.

[
{
"id": "019f7462-ac2a-73e3-ab40-be2e43f943f9",
"name": null,
"personal": true,
"ownerFirstName": "Greta",
"role": "OWNER"
},
{
"id": "019f7464-1617-7464-b8ef-7f34b631bdfa",
"name": "Lengl Family",
"personal": false,
"ownerFirstName": "Greta",
"role": "OWNER"
}
]
  • name ist bei persönlichen Arbeitsbereichen null — Clients bauen aus ownerFirstName eine lokalisierte Beschriftung.
POST /api/workspaces
{ "name": "Renovation" }

Liefert 201 mit { "id": "…" }. Fehler: 409, wenn dir bereits ein Arbeitsbereich mit diesem Namen gehört (Groß-/Kleinschreibung wird ignoriert), 403, wenn du dein Limit für geteilte Arbeitsbereiche erreicht hast.

DELETE /api/workspaces/{workspaceId}

Nur für Eigentümer. Liefert 204. Löscht dauerhaft alle Aufgaben, Listen, Mitgliedschaften und Anhänge. Persönliche Arbeitsbereiche können nicht gelöscht werden.

Jeder Arbeitsbereich hat ein Mitgliederlimit, das alle Mitglieder einschließlich des Eigentümers zählt; es ist eine Berechtigung des Eigentümers des Arbeitsbereichs (Standard-Plan: 5).

GET /api/workspaces/{workspaceId}/members
[
{
"userId": "019f…",
"firstName": "Greta",
"lastName": "Lengl",
"avatarUrl": "/api/avatars/019f…?v=3",
"role": "OWNER"
}
]

Neue Mitglieder kommen ausschließlich über E-Mail-Einladungen hinzu.

PUT /api/workspaces/{workspaceId}/members/{memberId}
{ "role": "ADMIN" }

Liefert 204. Rollen: ADMIN oder MEMBER — Eigentümerschaft lässt sich über diesen Endpunkt nicht übertragen.

DELETE /api/workspaces/{workspaceId}/members/{memberId}

Liefert 204. Eigentümer können nicht entfernt werden.

POST /api/workspaces/{workspaceId}/leave

Liefert 204. Verlässt einen geteilten Arbeitsbereich, dem du beigetreten bist: Die von dir erstellten Aufgaben werden einem reservierten „Inaktiver Nutzer“ neu zugewiesen und deine Zuweisungen werden entfernt. Der Eigentümer kann nicht verlassen (400) — übertrage zuerst die Eigentümerschaft. Nicht-Mitglieder erhalten 404.

POST /api/workspaces/{workspaceId}/transfer-ownership
{ "newOwnerId": "019f…" }

Nur für Eigentümer. Liefert 204: Der Empfänger wird Eigentümer und der Aufrufer bleibt als Administrator dabei; die Speicher- und Mitgliederlimits des Arbeitsbereichs richten sich von da an nach dem Tarif des neuen Eigentümers. Fehler: 404, wenn der Empfänger kein Mitglied ist, 400 bei einem persönlichen Arbeitsbereich oder einer Übertragung an dich selbst, 403, wenn der Empfänger sein Limit für eigene geteilte Arbeitsbereiche erreicht hat, 409, wenn dem Empfänger bereits ein Arbeitsbereich mit demselben Namen gehört.

Einladungen sind persönlich: Jede ist an genau eine E-Mail-Adresse gebunden, 7 Tage gültig und nur einmal verwendbar. Abgelaufene Einladungen werden außerdem von einem täglichen Aufräum-Job entfernt.

POST /api/workspaces/{workspaceId}/invites
{ "emails": ["person@example.com", "other@example.com"] }

Nur für Eigentümer/Admins, nur für geteilte Arbeitsbereiche, höchstens 20 Adressen pro Anfrage. Jede erfolgreich eingeladene Adresse erhält eine E-Mail mit einem persönlichen Einladungslink (tdminv_…-Token). Wird eine Adresse erneut eingeladen, wird ein frischer Link ausgestellt und der vorherige ungültig. Die Antwort meldet das Ergebnis pro Adresse:

{
"results": [
{ "email": "person@example.com", "outcome": "INVITED" },
{ "email": "other@example.com", "outcome": "ALREADY_MEMBER" }
]
}

Ergebnisse: INVITED, ALREADY_MEMBER, INVALID_ADDRESS. Fehler: 400 bei einem leeren oder zu großen Stapel, 403 für einfache Mitglieder oder wenn der Arbeitsbereich sein Mitgliederlimit bereits erreicht hat, 404 für Nicht-Mitglieder.

GET /api/workspaces/invites/{token}

Erfordert Authentifizierung, und die Einladung muss an die E-Mail-Adresse des angemeldeten Kontos gerichtet sein. Liefert, wer dich eingeladen hat:

{
"workspaceName": "Lengl Family",
"personal": false,
"ownerFirstName": "Greta",
"ownerLastName": "Lengl",
"ownerAvatarUrl": null
}

Unbekannte, abgelaufene und fremde Tokens sind nicht unterscheidbar: alle liefern 404.

POST /api/workspaces/join
{ "token": "tdminv_…" }
{ "workspaceId": "019f…", "newlyJoined": true }

newlyJoined ist false, wenn du bereits Mitglied warst.

Es gilt dieselbe persönliche Regel: Das Token funktioniert nur für das Konto mit der eingeladenen E-Mail-Adresse und wird bei Erfolg verbraucht. Unbekannte, abgelaufene und fremde Tokens liefern alle 404. Liefert 403, wenn der Arbeitsbereich sein Mitgliederlimit erreicht hat — die Einladung bleibt bestehen und kann erneut versucht werden, solange sie gültig ist.

GET /api/workspaces/{workspaceId}/sync?since={cursor}

Holt alles, was sich nach dem Cursor des Clients geändert hat — für offlinefähige Clients: geänderte Entitäten als vollständige Objekte im aktuellen Zustand, Löschungen als Id-Listen und den nächsten Cursor. since=0 liefert den kompletten Arbeitsbereich (die initiale Spiegelung). Das Anwenden eines Batches ist ein idempotentes Upsert, wiederholte oder überlappende Abrufe sind daher harmlos.

{
"cursor": 812,
"tasks": [ { "id": "019f…", "title": "…", "subtasks": [], "attachments": [] } ],
"deletedTaskIds": ["019f…"],
"lists": [],
"deletedListIds": [],
"members": [],
"deletedMemberIds": []
}
  • Aufgaben-Objekte haben dieselbe Form wie GET /api/workspaces/{id}/tasks; Änderungen an Unteraufgaben und Anhängen erscheinen als Änderungen ihrer übergeordneten Aufgabe.
  • Wird eine Liste gelöscht, werden ihre Aufgaben nicht erneut gesendet: Clients leeren diese listId lokal, passend zum Verhalten des Servers.
  • Änderungen, die jünger als etwa eine Sekunde sind, sind im Batch bereits enthalten, aber der Cursor bleibt vor ihnen stehen — der nächste Abruf liefert sie erneut, und der idempotente Upsert schluckt die Wiederholung. Ein Client, der direkt nach seinem eigenen Schreibvorgang abruft, sieht diesen daher immer.
GET /api/workspaces/{workspaceId}/events

Ein Server-Sent-Events-Stream, der signalisiert, wenn sich der Inhalt des Arbeitsbereichs geändert hat — eine Türklingel, kein Daten-Feed: Lade bei einem Signal neu, was du brauchst.