# 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 .name → Kreisname ``` ### `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) – Nebeneffekt, nicht verwendet a01.r.r.updatedCreated[] → taskcategorysync (Einkaufskategorien/Abteilungen) .sortingIndexByTaskList → dict, Keys = Listen-IDs (z.B. "taskList/23431854_29740942") → Quelle der Listen-IDs (Namen/Zähler noch unbekannt) a02.r.r.updatedCreated[] → tasksync (Tasks) .metaId → eindeutige Task-ID .text → Aufgabentext .description → optionale Beschreibung .taskListId → Zugehörigkeit zur Liste (= Listen-ID aus sortingIndexByTaskList) .complete → "true" / "false" (String, nicht Boolean!) ``` ## 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) ## 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 | **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 `text` oder `description` erforderlich) | | `description` | nein | Neue Beschreibung | Hinweis: `taskListId` ist **nicht** erforderlich (verifiziert – Update ohne `taskListId` funktioniert). **Response-Struktur:** kein spezifischer Rückgabewert – Erfolg = kein `ex`/`un`-Key auf Top-Level. ### `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. ### `wallmood` – Wall-Post liken / unliken POST https://api.familywall.com/api/wallmood Content-Type: application/x-www-form-urlencoded **Body-Parameter (zu verifizieren):** | Parameter | Pflicht | Wert | |---|---|---| | `wallId` | ja | Post-ID aus `get_activities` (Format `wall/23431854_31119189`) | | `moodType` | vermutlich ja | `"LIKE"` zum Liken, `"NONE"` zum Unliken (zu verifizieren) | **Verhalten:** Gleicher Endpoint für Like und Unlike. Mechanismus (Toggle vs. explizit) und genaue Parameter-Namen sind noch zu verifizieren via `FW_DEBUG=1`. Ein Like erzeugt serverseitig einen neuen Wall-Eintrag (Nebeneffekt). **Response-Struktur:** zu verifizieren beim ersten echten Call ## 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-Namen (`wallId`?, `moodType`?), Toggle vs. explizit, Response-Struktur