# Family Wall API – Spezifikation Erarbeitet durch Browser-Traffic-Analyse (April 2026). Es gibt keine offizielle API-Dokumentation. ## Base URL https://api.familywall.com/api ## Authentifizierung ### Login POST https://api.familywall.com/api/log2in Content-Type: application/x-www-form-urlencoded **Request-Parameter:** | Parameter | Wert | |---|---| | `identifier` | E-Mail-Adresse | | `password` | Passwort | | `type` | nicht senden — wird als `undefined` ignoriert (verifiziert per JS-Analyse) | | `clientId` | weglassen | | `clientSecret` | weglassen | | `generateAutologinToken` | weglassen | | `countryCode` | weglassen | **Response (Erfolg):** ```json { "a00": { "r": { "r": }, "cn": "log2in" } } ``` `SessionObject` enthält u.a. `tokenCsrf` und `webApiUrl`. `tokenCsrf` ist die Session-ID – identisch zur `JSESSIONID` im Cookie. **Response (Fehler):** ```json { "ex": { "ex": } } { "un": { "un": } } ``` Der Server setzt nach erfolgreichem Login ein Session-Cookie: Set-Cookie: JSESSIONID= (= tokenCsrf) ### Folgecalls (nach Login) Alle API-Calls nach dem Login benötigen: | | | |---|---| | **Cookie** | `JSESSIONID=` | | **Header** | `Tokencsrf: ` (identisch zur JSESSIONID) | | **Content-Type** | `application/x-www-form-urlencoded` | ### Logout POST https://api.familywall.com/api/log2out Content-Type: application/x-www-form-urlencoded Keine Parameter. Session wird serverseitig invalidiert. ### Session-Strategie Kein Session-Caching. Jeder MCP-Tool-Call führt folgende Sequenz aus: POST /api/log2in → Session-ID POST /api/ → Nutzdaten POST /api/log2out → Session invalidieren Credentials (E-Mail + Passwort) werden einmalig via `mcp-familywall setup` im OS Keyring gespeichert (Keys: `email`, `password`). Kein Keyring-Eintrag für `session_id`. ## Bekannte Endpoints ### `famlistfamily` – Kreise abrufen POST https://api.familywall.com/api/famlistfamily Content-Type: application/x-www-form-urlencoded **Body-Parameter:** keine (verifiziert) **Response-Struktur (verifiziert):** ``` a00.r.r[] → Kreise .metaId → eindeutige Kreis-ID (Format family/) .name → Kreisname .family_id → numerische Kreis-ID .members[] → Mitglieder des Kreises .accountId → numerische Account-ID .metaId → Mitglieds-ID (Format familymember/_) .firstName → Vorname (Display-Name; bevorzugen gegenüber .name) .name → E-Mail-Adresse (Family Wall Default wenn kein Anzeigename) .role → Familienrolle (z.B. "Unknown", "Parent", "Child") .right → Berechtigung (z.B. "SuperAdmin", "Admin", "Member") .color → Profilfarbe als Hex-String (z.B. "#FF8086") .medias[0].pictureUrl → Avatar-URL (generierter Default wenn pictureDefault=true) .identifiers[] → Kontaktdaten .type → Typ (z.B. "Email") .value → Wert (z.B. E-Mail-Adresse) .familyId → Zugehöriger Kreis (= metaId des Kreises) .isloggedaccount → "true" wenn das der angemeldete Account ist .joinDate → Beitrittsdatum (ISO 8601) .lastLoginDate → Letzter Login (ISO 8601) .locale → Spracheinstellung (z.B. "de_DE") .timeZone → Zeitzone (z.B. "Europe/Berlin") .invitations[] → Offene Einladungen (leer wenn keine) .coverUri → Cover-Bild URL ``` ### `taskgettasklists` – Listen abrufen POST https://api.familywall.com/api/taskgettasklists Content-Type: application/x-www-form-urlencoded **Body-Parameter:** keine **Response-Struktur:** zu verifizieren beim ersten echten Call ### `accgetallfamily` – Listen + Tasks abrufen POST https://api.familywall.com/api/accgetallfamily Content-Type: application/x-www-form-urlencoded **Body-Parameter:** | Parameter | Wert | |---|---| | `a01call` | `"taskcategorysync"` | | `a02call` | `"tasksync"` | Hinweis: `a03call=tasklistsync` ist **kein gültiger Endpoint** — API antwortet mit "The call tasklistsync is not registered". Nicht verwenden. `partnerScope`, `a03id`, `withStateBean` werden weggelassen. **Response-Struktur (verifiziert):** ``` a00 → famlistfamily-Daten (Kreise inkl. members[]) – Nebeneffekt a01.r.r.updatedCreated[] → taskcategorysync (Kategorien/Abteilungen pro Liste) .metaId → Kategorie-ID (Format taskCategory/_) .name → Kategoriename (sprachabhängig, z.B. "Beverages") .emoji → Emoji-Symbol der Kategorie .systemCategoryId → numerische System-ID (sprach-unabhängig) .taskListType → Listentyp der Kategorie (z.B. "SHOPPING_LIST") **Wichtig:** Alle 171 Kategorien sind SHOPPING_LIST — es gibt keine TODO-Kategorien in der API .sortingIndexByTaskList → dict: Listen-ID → Sortierposition **Achtung:** enthält ALLE Listen-IDs unabhängig vom Typ → NICHT für Typ-Filterung verwenden! Stattdessen: taskListType der Kategorie mit taskListType der Liste (aus taskgettasklists) vergleichen .locale → Sprache des Namens (z.B. "de", "en", "ru", "fr", "es", "it", "nl", "pt", "sv", "ko", "ja") Jede Sprache = eigener Eintrag mit eigenem metaId/systemCategoryId **Wichtig:** Custom-Kategorien (rights.canDelete='true') haben kein locale-Feld gesetzt — sie werden sprachunabhängig zurückgegeben und dürfen nie über locale gefiltert werden. .hiddenByTaskList → Liste von Listen-IDs, in denen die Kat. versteckt ist a02.r.r.updatedCreated[] → tasksync (Tasks) .metaId → eindeutige Task-ID .taskId → identisch zu metaId (zweiter Alias) .text → Aufgabentext .description → optionale Beschreibung .taskListId → Zugehörigkeit zur Liste .complete → "true" / "false" (String, nicht Boolean!) .categories[] → Listen-Level-Systemkategorie (z.B. SYS-CAT-SHOPPINGLIST); NICHT die spezifische Task-Kategorie — immer identisch für alle Tasks einer Liste .system → "true" (immer System-Kategorie) .name → Listen-Systemkategorien (z.B. "SYS-CAT-SHOPPINGLIST", "SYS-CAT-TODOS") .taskCategoryId → spezifische Task-Kategorie (verifiziert): metaId-Format (z.B. "taskCategory/23431854_200"), null wenn nicht gesetzt .assignee[] → zugewiesene Mitglieder: [{accountId: "..."}] .assigneeIds[] → zugewiesene Member-IDs als String-Array (z.B. ["23431898"]) .dueDate → Fälligkeitsdatum (ISO 8601, z.B. "2026-04-30T18:00:00.000Z"; null wenn nicht gesetzt) .reminder → Erinnerungsregel (Objekt mit reminderUnit, reminderType, reminderValue — nicht das Fälligkeitsdatum!) .recurrency → Wiederholungsregel (optional) .sortingIndex → Anzeigereihenfolge ``` **Kategorie-Zuweisung bei taskcreate2 / taskupdate2 (verifiziert):** | Parameter | Pflicht | Wert | |---|---|---| | `taskCategoryId` | nein | Kategorie-MetaId aus `get_categories` (z.B. `taskCategory/23431854_200`) | Hinweise: - Wert muss das vollständige metaId-Format `taskCategory/_` sein. Nur der numerische `systemCategoryId`-Teil (z.B. `200`) führt zu API-Fehler `"cannot find task category id=200"`. - Das `categories[]`-Feld in der Response zeigt immer `SYS-CAT-SHOPPINGLIST` (Listen-Level-Systemkategorie, unabhängig vom gesetzten `taskCategoryId`). Die tatsächliche Task-Kategorie ist im Feld `taskCategoryId` der Task gespeichert. - Nur für Einkaufslisten (`taskListType=SHOPPING_LIST`) relevant; TODO-Listen haben keine Kategorien. ## Systembezeichnungen für Listen-Namen Bekannte Systembezeichnungen werden deutsch übersetzt: | Systembezeichnung | Deutsch | |---|---| | `SYS-CAT-SHOPPINGLIST` | `Einkaufsliste` | Unbekannte Bezeichnungen werden unverändert zurückgegeben. Mapping-Tabelle bei Bedarf erweitern. ### `wallget` – Aktivitäten (Wall) abrufen POST https://api.familywall.com/api/wallget Content-Type: application/x-www-form-urlencoded **Body-Parameter:** | Parameter | Wert | |---|---| | `nb` | Anzahl Einträge (z.B. `"20"`) | | `date` | optional, für Paginierung (Datum des letzten Eintrags) | | `accountId` | optional | | `type` | optional | | `nested` | optional | | `masterNested` | optional | | `sortBy` | optional | **Response-Struktur (verifiziert):** ``` a00.r.r[] .metaId → ID der Aktivität (= wallMessageId) .refType → Aktivitätstyp (z.B. STATUS, FAMILY_CREATED) .text → Text (optional, fehlt bei System-Events) .creationDate → Datum (ISO 8601) .accountId → Autor-ID ``` **Response-Struktur:** zu verifizieren beim ersten echten Call ### `wallactivityget` – Einzelne Aktivität abrufen POST https://api.familywall.com/api/wallactivityget Content-Type: application/x-www-form-urlencoded **Body-Parameter:** | Parameter | Wert | |---|---| | `accountId` | optional | | `masterNested` | optional | **Response-Struktur:** zu verifizieren beim ersten echten Call (Endpoint noch nicht implementiert — für spätere Versionen) ## Fehlerstruktur-Varianten Die Family Wall API gibt Fehler in zwei verschiedenen Strukturen zurück: | Struktur | Beispiel | Erkennungsregel | |---|---|---| | Top-Level `ex` | `{"ex": {"ex": {...}}}` | `"ex" in body` | | Top-Level `un` | `{"un": {"un": {...}}}` | `"un" in body` | | Verschachtelt `a00.un` | `{"a00": {"un": {"un": {...}}}}` | `"un" in body["a00"]` | Ab v0.4.15 erkennt `fw_client.py` alle drei Varianten und wirft `FamilyWallError`. Zuvor wurden `a00.un`-Fehler still ignoriert (silent fail), was zu irreführenden `{"updated": True}`-Antworten bei fehlgeschlagenen Updates führte. **Bekannte Endpoints mit `a00.un`-Fehlern:** - `taskupdate2` mit ungültigem `dueDate`-Wert - `taskcategorydelete` mit falschem Parameter-Namen (obsolet nach v0.4.x-Fix) ## Debug-Logging Wenn die Umgebungsvariable `FW_DEBUG=1` gesetzt ist, loggt `fw_client.py` vollständige Request-Bodies und Responses nach stderr. Dient zur Verifikation offener Punkte (z.B. `type`-Parameter beim Login, Kreis-Felder in Response). **Wichtig:** Keine Secrets in Debug-Ausgaben (Passwort maskieren). ### `taskcreate2` – Task erstellen POST https://api.familywall.com/api/taskcreate2 Content-Type: application/x-www-form-urlencoded **Body-Parameter (verifiziert):** | Parameter | Pflicht | Wert | |---|---|---| | `taskListId` | ja | Listen-ID aus `get_lists` (z.B. `taskList/123_456`) | | `text` | ja | Aufgabentitel | | `description` | nein | Optionale Beschreibung | | `taskCategoryId` | nein | Kategorie-MetaId aus `get_categories` (z.B. `taskCategory/23431854_200`) | | `dueDate` | nein | Fälligkeitsdatum ISO 8601 (z.B. `"2026-04-30T18:00:00"`); gespeichert als `dueDate` im Task-Objekt | | `assignee` | nein | Member-ID aus `get_members` (z.B. `"23431898"`); für mehrere Zuweisungen: mehrfach senden (`assignee=id1&assignee=id2`); gespeichert als `assigneeIds[]` im Task-Objekt | **Response-Struktur (verifiziert):** ``` a00.r.r → vollständiges Task-Objekt der neu erstellten Task .metaId → eindeutige Task-ID (z.B. "task/23431854_726362809") .taskListId → Listen-ID .text → Titel .complete → "false" (immer, direkt nach Erstellung) ``` ### `taskupdate2` – Task aktualisieren POST https://api.familywall.com/api/taskupdate2 Content-Type: application/x-www-form-urlencoded **Body-Parameter (verifiziert):** | Parameter | Pflicht | Wert | |---|---|---| | `metaId` | ja | Task-ID aus `get_tasks` | | `text` | nein | Neuer Titel (mindestens eines der optionalen Felder erforderlich) | | `description` | nein | Neue Beschreibung | | `taskCategoryId` | nein | Kategorie-MetaId aus `get_categories` (z.B. `taskCategory/23431854_200`) | | `dueDate` | nein | Fälligkeitsdatum ISO 8601 (z.B. `"2026-04-30T18:00:00"`); gespeichert als `dueDate` im Task-Objekt | | `assignee` | nein | Member-ID aus `get_members` (z.B. `"23431898"`); für mehrere Zuweisungen: mehrfach senden (`assignee=id1&assignee=id2`); leerer String (`""`) entfernt alle Zuweisungen (nicht verifiziert); gespeichert als `assigneeIds[]` im Task-Objekt | | `taskListId` | nein | Ziel-Listen-ID zum Verschieben des Tasks (verifiziert – ändert `taskListId` im Task-Objekt) | Hinweis: `taskListId` ist optional – ohne diesen Parameter bleibt der Task in seiner aktuellen Liste. **Response-Struktur:** kein spezifischer Rückgabewert – Erfolg = kein `ex`/`un`-Key auf Top-Level. **dueDate Clearing – `"$empty"` Sentinel (verifiziert April 2026, v0.4.16):** Der FiZ-Framework verwendet den Sentinel-Wert `"$empty"` um optionale Felder zu leeren. ``` POST taskupdate2 metaId=task/23431854_726333919&dueDate=$empty → dueDate wird auf null gesetzt ✓ ``` `update_task(clear_due_date=True)` sendet intern `dueDate=$empty`. **Getestete Werte die fehlschlugen (vor der Lösung):** | Wert | API-Response | |---|---| | `""` (leerer String) | `a00.un: " is not a valid Date"` | | `"null"` | `a00.un: "Cannot parse date val=null"` | | `"undefined"` | `a00.un: "Cannot parse date val=undefined"` | | `"0"`, `"-1"` | `a00.un: "... is not a valid Date"` | | `"remove"` / `"clear"` | `a00.un: "Cannot parse date val=..."` | | `"1970-01-01T00:00:00"` | Erfolgreich – setzt dueDate auf Unix-Epoch (kein Clearing!) | | Feld weglassen | dueDate bleibt unverändert | | `removeDueDate=1`, `clearDueDate=1` | werden ignoriert | **Wichtig:** Die Fehler werden als `a00.un` zurückgegeben (nicht Top-Level `un`). Ab v0.4.15 erkennt `fw_client` diese und wirft `FamilyWallError`. ### `taskmark` – Task als erledigt/offen markieren POST https://api.familywall.com/api/taskmark Content-Type: application/x-www-form-urlencoded **Body-Parameter (verifiziert):** | Parameter | Pflicht | Wert | |---|---|---| | `taskId` | ja | Task-ID aus `get_tasks` (**WICHTIG: `taskId`, nicht `metaId`!**) | | `complete` | ja | `"true"` oder `"false"` (String, nicht Boolean!) | **Achtung:** Der Endpoint heißt intern `taskId`, nicht `metaId`. Falsche Parameter (`metaId`, `id`, `taskMetaId`) werden serverseitig ignoriert – die API antwortet dann mit einem Fehler in `a00.un.un` (nicht Top-Level!), der vom Standard-Error-Check im fw_client übersehen wird. **Response-Struktur (verifiziert):** ``` a00.r.r → vollständiges Task-Objekt mit aktuellem Stand (inkl. lastAction: "MARK_COMPLETED") ``` ### `metadelete` – Objekt löschen POST https://api.familywall.com/api/metadelete Content-Type: application/x-www-form-urlencoded **Body-Parameter (verifiziert):** | Parameter | Pflicht | Wert | |---|---|---| | `id` | ja | Task-ID aus `get_tasks` (**WICHTIG: `id`, nicht `metaId`!**) | Hinweis: `metadelete` ist ein generischer Lösch-Endpoint für beliebige Objekte (Tasks, etc.). Entsprechend vorsichtig verwenden. **Response-Struktur (verifiziert):** ``` a00.r.r → "true" (String) ``` **Fehlerverhalten:** Bei falschem Parameter-Namen (`metaId`, `taskId` etc.) antwortet die API mit `{"a00": {"un": {"un": {"message": "missing value in: id"}}}}` auf Top-Level ohne `un`-Key → wird vom fw_client fälschlich als Erfolg interpretiert. Daher ist der korrekte Parameter-Name kritisch. ### `taskcategoryput` – Kategorie erstellen POST https://api.familywall.com/api/taskcategoryput Content-Type: application/x-www-form-urlencoded **Body-Parameter (verifiziert via FW_DEBUG=1):** | Parameter | Pflicht | Wert | |---|---|---| | `name` | ja | Kategorie-Name (beliebiger String) | | `emoji` | nein | Icon: Unicode-Emoji-Zeichen (z.B. `🌿`) oder beliebiger String-Code (z.B. `"FOOD"`) — wird as-is gespeichert | Hinweise: - Die neue Kategorie wird **allen** Listen der Familie zugeordnet — es gibt keine per-Liste-Einschränkung. - Benutzerdefinierte Kategorien haben `systemCategoryId=null` und `rights.canDelete='true'`. - System-Kategorien haben `rights.canDelete=null` — API erlaubt Löschen, aber `delete_category` Tool verweigert es. **Response-Struktur (verifiziert):** ``` a00.r.r → vollständiges Kategorie-Objekt .metaId → neue Kategorie-ID (z.B. "taskCategory/23431854_4956637") .name → Kategorie-Name .taskListType → "SHOPPING_LIST" (automatisch gesetzt) .familyId → Familien-ID .accountId → Account-ID des Erstellers .rights.canDelete → "true" (custom Kategorien) .rights.canUpdate → "true" (custom Kategorien) .emoji → gespeicherter Icon-Wert (falls übergeben) ``` **Fehlerverhalten:** Ohne `name`-Parameter: ```json {"a00": {"un": {"un": {"FiZClassId": "502", "message": "cat without a name ..."}}}} ``` ### `taskcategorydelete` – Kategorie löschen POST https://api.familywall.com/api/taskcategorydelete Content-Type: application/x-www-form-urlencoded **Body-Parameter (verifiziert via FW_DEBUG=1):** | Parameter | Pflicht | Wert | |---|---|---| | `id` | ja | Kategorie-MetaId aus `get_categories` (**WICHTIG: `id`, nicht `metaId`!**) | **Achtung:** Falscher Parameter-Name `metaId` führt zu: ```json {"a00": {"un": {"un": {"FiZClassId": "502", "message": "In request, missing value in : id"}}}} ``` **Response-Struktur (verifiziert):** ``` a00.r.r → "true" (String) ``` **Wichtig – System-Kategorien:** Die API erlaubt technisch das Löschen von System-Kategorien (`taskCategory/_200` etc.), entfernt sie aber nur aus der Familie — nicht global. Das `delete_category`-MCP-Tool verweigert dies (Schutz via `rights.canDelete`-Check). Erkennung: custom Kategorien haben `rights.canDelete='true'`; System-Kategorien haben `rights.canDelete=null`. ### `wallmood` – Wall-Post liken POST https://api.familywall.com/api/wallmood Content-Type: application/x-www-form-urlencoded **Body-Parameter (verifiziert via FW_DEBUG=1):** | Parameter | Pflicht | Wert | |---|---|---| | `wall_message_id` | ja | Post-ID aus `get_activities` (z.B. `wall/23431854_31119189`) | | `moodType` | ja | `"STAR"` (einziger bekannter Wert — entspricht dem Like-Button in der App) | **Verhalten (verifiziert):** - `wallmood` mit `moodType: "STAR"` ist eine **idempotente SET-Operation** — kein Toggle! - Mehrfaches Aufrufen mit denselben Parametern hinterlässt denselben Zustand - `moodType: "LIKE"` wurde serverseitig als `"STAR"` gespeichert → korrekter Wert ist `"STAR"` - Nur für Post-Typ `STATUS` wirksam; `FAMILY_CREATED` und vermutlich System-Posts ignorieren den Call **Unlike – nicht implementierbar (Stand: April 2026):** Ausgiebig getestete Ansätze, die alle fehlschlugen: | Ansatz | Ergebnis | |---|---| | `moodType: "NONE"` / `"REMOVE"` / `"DELETE"` / `""` | moodMap unverändert | | `moodType` ganz weglassen | moodMap unverändert | | `moodStarShortcut: "false"` als Parameter | moodMap unverändert | | Alternative Endpoints: `wallmooddelete`, `wallmoodremove`, `wallmoodelete`, `wallunmood`, `wallcommentdelete`, `wallmoodstar`, `wallstar`, `wallreact`, `wallreactdelete` | alle: `"The call X is not registered"` (502) | | `metadelete` auf Mood-Comment-ID | löscht den Comment, aber `moodStarShortcut` bleibt gesetzt | Die Web-App nutzt einen Service Worker, der Requests abfängt — der echte Unlike-Payload ist dadurch nicht per Browser-DevTools inspizierbar. Unlike bleibt bis zur weiteren Analyse nicht unterstützt. **Response-Struktur (verifiziert):** ``` a00.r.r → vollständiges Wall-Message-Objekt .metaId → Post-ID (= wallMessageId) .wallMessageId → Post-ID (identisch zu metaId) .refType → Aktivitätstyp (z.B. "STATUS") .refAction → Letzte Aktion (z.B. "MOOD_STAR") .text → Post-Text .postAccountId → Account-ID des Post-Autors .accountId → Account-ID (identisch) .moodMap → dict: accountId → ["STAR"] wenn geliked .moodStarShortcut → "true" wenn Like-Shortcut aktiv .comments[] → Liste von Kommentaren/Moods .commentId → Kommentar-ID (Format wallComment/...) .accountId → Account-ID des Kommentators .mood → Mood-Typ (z.B. "STAR") .text → Kommentartext (falls vorhanden) .creationDate → Erstelldatum (ISO 8601) .creationDate → Erstelldatum des Posts (ISO 8601) .modifDate → Letztes Änderungsdatum (ISO 8601) .familyId → Kreis-ID (Format family/...) .rights.canUpdate → "true"/"false" .rights.canDelete → "true"/"false" ``` **Like-Zustand bestimmen (zwei Indikatoren, beide auswerten):** | Feld | Typ | Bedeutung | |---|---|---| | `moodStarShortcut` | `"true"` / `"false"` | Primär: direktes User-Like-Flag für den anfragenden Account | | `moodMap[accountId]` | `["STAR"]` | Sekundär: accountId → Mood-Liste; enthält `"STAR"` wenn geliked | Beide Indikatoren können den Like-Zustand korrekt abbilden — je nach API-internem Speicherpfad ist nur einer gesetzt. Immer beide prüfen. **Silent-Fail-Szenarien (API antwortet 200, aber Like wird nicht gesetzt):** - **Self-Like-Restriction**: Eigener Post kann nicht geliked werden (verifiziert: Account 23431898 kann Post `wall/23431854_31119189` nicht liken, obwohl API regulär antwortet — `modifDate` bleibt eingefroren) - **Unsupported Post-Typ**: `FAMILY_CREATED`-Posts ignorieren wallmood-Calls - **Rate-Limit**: Nach vielen Calls kann die API Still-Fails zurückgeben Erkennungsmerkmal für Silent-Fail: `modifDate` im Response identisch zum Vorherigen AND `moodStarShortcut: false` AND `moodMap: {}`. ## Noch zu verifizieren - ~~Exakter Wert für `type`-Parameter beim Login~~ → nicht senden (verifiziert per JS-Analyse) - ~~Response-Struktur von `famlistfamily` (Kreise)~~ → a00.r.r[], metaId + name (verifiziert) - ~~Ob `a03call=tasklistsync` benötigt wird~~ → **nein**, kein gültiger Endpoint (verifiziert) - Listen-IDs aus `a01.r.r.updatedCreated[].sortingIndexByTaskList`-Keys (verifiziert) - Listen-Namen und Zähler (remainingTaskNumber, totalTaskNumber) → noch unbekannt - Kreis-Zuordnung in `accgetallfamily`-Response → noch offen - ~~Ob `partnerScope` / `withStateBean` benötigt werden~~ → nein (verifiziert) - Session-Lebensdauer (irrelevant da kein Caching) - ~~`taskcreate2`: Response-Struktur~~ → `a00.r.r` = vollständiges Task-Objekt (verifiziert) - ~~`taskupdate2`: ob `taskListId` Pflichtfeld ist~~ → **nein**, nicht erforderlich (verifiziert) - ~~`taskmark`: korrekter Parameter-Name~~ → **`taskId`** (nicht `metaId`!) (verifiziert) - ~~`metadelete`: korrekter Parameter-Name + Response-Struktur~~ → **`id`**, Response `"true"` (verifiziert) - ~~`wallmood`: Parameter-Name `wallId`~~ → **`wall_message_id`** (verifiziert via API-Fehlermeldung) - ~~`wallmood`: `moodType`-Werte, Toggle vs. explizit, Response-Struktur~~ → verifiziert: idempotentes SET mit `"STAR"`, kein Toggle (siehe oben) - `wallmood` Unlike: Mechanismus unbekannt — Service Worker verhindert Browser-Inspektion; alle getesteten Ansätze fehlgeschlagen (siehe oben) - ~~`taskcreate2` / `taskupdate2`: Kategorie-Paramter-Name~~ → **`taskCategoryId`**, Wert = vollständige metaId (verifiziert) - ~~`taskcategoryput`: Body-Parameter, Response-Struktur~~ → `name` (Pflicht), `emoji` (optional), Response = neues Kategorie-Objekt (verifiziert) - ~~`taskcategorydelete`: Body-Parameter~~ → **`id`** (nicht `metaId`!), Response = `"true"` (verifiziert) - ~~`taskcreate2` / `taskupdate2`: Fälligkeitsdatum-Parameter~~ → **`dueDate`**, ISO 8601 String, gespeichert als `dueDate` im Task-Objekt (verifiziert) - ~~`taskcreate2` / `taskupdate2`: Zuweisung-Parameter~~ → **`assignee`** (Member-ID String; mehrere Werte = mehrfach senden); gespeichert als `assigneeIds[]` (verifiziert) - ~~`taskupdate2`: Task verschieben~~ → **`taskListId`** als optionaler Parameter setzt neue Liste (verifiziert) - `taskupdate2`: Alle Zuweisungen entfernen (leere `assignee`-Liste) → noch nicht verifiziert - ~~`taskupdate2`: `dueDate` entfernen (Clearing)~~ → **`dueDate=$empty`** (FiZ-Sentinel, verifiziert April 2026, v0.4.16)