{"openapi":"3.1.0","info":{"title":"Content API","description":"API for managing posts, media, annotations, and content blocks","version":"1.0.0"},"paths":{"/api/v1/posts/":{"get":{"tags":["posts"],"summary":"List Posts","description":"List posts.\n\nPhase-B tenant filtering:\n- Anonymous: only published posts (Share-Links keep working).\n- Superadmin / legacy X-API-KEY: no filter.\n- Authenticated user/agent: posts where partner_id IN their tenants\n  OR partner_id IS NULL (untenanted posts visible to everyone authed).\n\nAuthenticated agents (or users) with **zero** content tenant memberships\nused to get an empty list silently — now they get a clear 403 with a\npointer to the auth-api fix path. Anonymous still works as before.","operationId":"list_posts_api_v1_posts__get","parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^(draft|published|archived)$"},{"type":"null"}],"title":"Status"}},{"name":"doc_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by doc_type: beitrag, angebot, rechnung, honorarnote, story, survey, docu, agent","title":"Doc Type"},"description":"Filter by doc_type: beitrag, angebot, rechnung, honorarnote, story, survey, docu, agent"},{"name":"author_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Author Id"}},{"name":"partner_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Partner Id"}},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Search in title and content","title":"Search"},"description":"Search in title and content"},{"name":"tags","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comma-separated tags to filter by","title":"Tags"},"description":"Comma-separated tags to filter by"},{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by category","title":"Category"},"description":"Filter by category"},{"name":"language","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by language code (e.g. de, en, sl)","title":"Language"},"description":"Filter by language code (e.g. de, en, sl)"},{"name":"collab_enabled","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Filter by collab_enabled flag","title":"Collab Enabled"},"description":"Filter by collab_enabled flag"},{"name":"notify_author","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter to posts where this name appears in metadata_json.notify_authors (server-side JSONB-contains query). Pass the display-name without 'agent:' prefix, e.g. 'CloudV2'.","title":"Notify Author"},"description":"Filter to posts where this name appears in metadata_json.notify_authors (server-side JSONB-contains query). Pass the display-name without 'agent:' prefix, e.g. 'CloudV2'."},{"name":"order_by","in":"query","required":false,"schema":{"type":"string","pattern":"^(created_at|updated_at)$","description":"Sort field — created_at (default) or updated_at","default":"created_at","title":"Order By"},"description":"Sort field — created_at (default) or updated_at"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":20,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["posts"],"summary":"Create Post","description":"Create a new post.\n\nPhase-B tenant rule:\n- If partner_id provided: must be one of caller's tenants (or caller is\n  superadmin/legacy).\n- If not provided: auto-fill with caller's first tenant. Untenanted posts\n  are only allowed for superadmin/legacy (otherwise we'd accidentally\n  orphan posts that nobody can later filter for).","operationId":"create_post_api_v1_posts__post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostDetailResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}":{"get":{"tags":["posts"],"summary":"Get Post","description":"Get a post with all related data.\n\nPhase-B tenant gate:\n- Anonymous: published posts only (Share-Links keep working).\n- Superadmin / legacy: any post.\n- Authed user/agent: only posts whose partner_id is in their tenants,\n  or untenanted (partner_id IS NULL).\n\nAuthenticated callers with zero content tenant memberships get an explicit\n403 with the auth-api fix path (was a silent 404 — frische Agents had no\nway to debug).","operationId":"get_post_api_v1_posts__post_id__get","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostDetailResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["posts"],"summary":"Update Post","description":"Update a post. Supports both PUT and PATCH.\n\nPhase-B: caller must have access to the post's current tenant. If the\nupdate changes partner_id, the new tenant must also be in caller's set.\n\nOptimistic locking: pass `If-Match: <version>` header or set\n`expected_version` in the body. On mismatch the server returns 409\nConflict with the current server version + current content.","operationId":"update_post_api_v1_posts__post_id__patch","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"If-Match","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"If-Match"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostDetailResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["posts"],"summary":"Update Post","description":"Update a post. Supports both PUT and PATCH.\n\nPhase-B: caller must have access to the post's current tenant. If the\nupdate changes partner_id, the new tenant must also be in caller's set.\n\nOptimistic locking: pass `If-Match: <version>` header or set\n`expected_version` in the body. On mismatch the server returns 409\nConflict with the current server version + current content.","operationId":"update_post_api_v1_posts__post_id__put","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"If-Match","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"If-Match"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostDetailResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["posts"],"summary":"Delete Post","description":"Delete a post and all related data.\n\nBug fix 2026-06-02 (Alex' \"neuer Post zeigt alten Content\"):\na plain `db.delete(post)` leaves the live Y.Doc session and the\ncrdt_documents/crdt_updates rows behind. On SQLite, the next\nINSERT into `posts` can reuse the freed ROWID; the WS server\nthen cold-loads the surviving CRDT state for that id and the\n\"new\" post renders with the deleted post's content.\n\nCleanup order:\n  1. Evict the in-memory session (close any lingering WS,\n     drop the Y.Doc).\n  2. Explicit DELETE on crdt_documents + crdt_updates — the\n     FK CASCADE is declared but SQLite only honours it when\n     `PRAGMA foreign_keys = ON`, which isn't guaranteed.\n  3. Delete the post row.","operationId":"delete_post_api_v1_posts__post_id__delete","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/export.pdf":{"get":{"tags":["posts"],"summary":"Export Post Pdf","description":"Export a post as PDF.\n\nRenders title, metadata, content (markdown/json/txt) and optional media gallery\nvia WeasyPrint. Returns application/pdf.\n\nAuthentication: Published posts are publicly downloadable (so the URL can\nbe shared via Telegram/email/etc.). Draft & archived posts require a valid\nX-API-KEY header.","operationId":"export_post_pdf_api_v1_posts__post_id__export_pdf_get","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"include_media","in":"query","required":false,"schema":{"type":"boolean","description":"Append media gallery","default":true,"title":"Include Media"},"description":"Append media gallery"},{"name":"download","in":"query","required":false,"schema":{"type":"boolean","description":"Force download instead of inline","default":false,"title":"Download"},"description":"Force download instead of inline"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/export-themed.pdf":{"get":{"tags":["posts"],"summary":"Export Post Themed Pdf","description":"Export a post as PDF via markdown-api with selectable theme.\n\nUses the external markdown-api for rendering, which supports\nmultiple visual themes. Falls back to the built-in export on error.\n\n**Optionale Abhängigkeit.** Ist `MARKDOWN_API_BASE` nicht gesetzt, gibt\nes diesen Export auf der Instanz nicht — der übrige Dienst inklusive\n`/export.pdf` (rendert lokal mit WeasyPrint) läuft davon unberührt.\nOhne die Prüfung unten liefe der Aufruf in einen Verbindungsfehler und\nmeldete 502 „markdown-api error\", was wie eine Störung aussieht statt\nwie eine bewusst nicht eingerichtete Funktion.","operationId":"export_post_themed_pdf_api_v1_posts__post_id__export_themed_pdf_get","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"theme","in":"query","required":false,"schema":{"type":"string","description":"Theme: default, minimal, technical, business, arkturian","default":"default","title":"Theme"},"description":"Theme: default, minimal, technical, business, arkturian"},{"name":"logo_url","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Logo URL for branding (overrides post.logo_url)","title":"Logo Url"},"description":"Logo URL for branding (overrides post.logo_url)"},{"name":"cover","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Cover page: true/false/null (null=theme default)","title":"Cover"},"description":"Cover page: true/false/null (null=theme default)"},{"name":"cover_image_url","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Custom cover image (overrides post.cover_image_url)","title":"Cover Image Url"},"description":"Custom cover image (overrides post.cover_image_url)"},{"name":"starburst_theme","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Starburst style: minimal, vibrant, organic, geometric, dark_elegant, neon","title":"Starburst Theme"},"description":"Starburst style: minimal, vibrant, organic, geometric, dark_elegant, neon"},{"name":"design_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"p5.js generative art design ID (e.g. M_1_5_03, P_2_0_01)","title":"Design Id"},"description":"p5.js generative art design ID (e.g. M_1_5_03, P_2_0_01)"},{"name":"cover_label","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Label on cover (e.g. Proposal, Protokoll)","title":"Cover Label"},"description":"Label on cover (e.g. Proposal, Protokoll)"},{"name":"cover_bullets","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comma-separated bullet points for cover","title":"Cover Bullets"},"description":"Comma-separated bullet points for cover"},{"name":"smart_breaks","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Smart page breaks at H2 sections (default true, false=faster)","title":"Smart Breaks"},"description":"Smart page breaks at H2 sections (default true, false=faster)"},{"name":"download","in":"query","required":false,"schema":{"type":"boolean","description":"Force download instead of inline","default":false,"title":"Download"},"description":"Force download instead of inline"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/content-patch":{"patch":{"tags":["posts"],"summary":"Patch Content","description":"Patch content with line-level operations instead of full replacement.\n\nSupports:\n- replace: replace lines start_line..end_line with new text\n- insert: insert text after start_line (0 = before first line)\n- delete: remove lines start_line..end_line\n- find/replace_with: find text within line range and replace it\n\nReturns the updated post with new content.","operationId":"patch_content_api_v1_posts__post_id__content_patch_patch","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"If-Match","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"If-Match"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContentPatchRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/languages":{"get":{"tags":["posts"],"summary":"Get Post Languages","description":"List available language variants for a post.\n\nIf the post has no language_group yet, returns just this post as the\nonly variant (with its language defaulting to 'de').","operationId":"get_post_languages_api_v1_posts__post_id__languages_get","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostLanguagesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/language/{lang_code}":{"get":{"tags":["posts"],"summary":"Get Post In Language","description":"Fetch a post in a specific language, optionally auto-generating.\n\nBehavior:\n  1. If the source post is already in `lang_code` → return it directly\n  2. If a language_group sibling in `lang_code` exists → return that sibling\n  3. If sibling missing AND `auto_generate=false` → 404 with detail\n     listing available languages\n  4. If sibling missing AND `auto_generate=true` → synchronously\n     translate the source post into `lang_code`, persist as new sibling,\n     return it. Wall-clock cost depends on doctype (md/audio_guide fast\n     via Google Translate; story via Gemini). Downstream callers can\n     cache the returned post_id and hit the standard GET /posts/{id}\n     path from that point on.\n\nUX-driver: Alex 2026-07-01/02 wants \"first visit in a new language just\nworks\" — no 404 → prompt → retry. Frontend can call this endpoint with\nauto_generate=true on the first fetch per language.\n\nNOTE: requires write permission because auto_generate can create new\nposts. Callers that only want to read (never trigger generation) can\npass auto_generate=false; that path still validates write access but\nwon't mutate.","operationId":"get_post_in_language_api_v1_posts__post_id__language__lang_code__get","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"lang_code","in":"path","required":true,"schema":{"type":"string","title":"Lang Code"}},{"name":"auto_generate","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Auto Generate"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/translate":{"post":{"tags":["posts"],"summary":"Translate Post","description":"Explicitly translate a post to one or more target languages.\n\n- Creates new posts (with own IDs) for each target language\n- Links them via Post.language_group column (UUID, created on first call)\n- Source post becomes the \"source_language\" anchor\n- Will skip languages that already exist unless force_refresh=true\n- Translation runs through the configured AI API (settings.ai_api_base)","operationId":"translate_post_api_v1_posts__post_id__translate_post","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/content__services__language_service__TranslateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/content__services__language_service__TranslateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/media/":{"get":{"tags":["media"],"summary":"List Media","description":"List all media for a post.","operationId":"list_media_api_v1_posts__post_id__media__get","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MediaResponse"},"title":"Response List Media Api V1 Posts  Post Id  Media  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["media"],"summary":"Add Media","description":"Add media to a post.","operationId":"add_media_api_v1_posts__post_id__media__post","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/media/{media_id}":{"get":{"tags":["media"],"summary":"Get Media","description":"Get a single media item.","operationId":"get_media_api_v1_posts__post_id__media__media_id__get","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"media_id","in":"path","required":true,"schema":{"type":"integer","title":"Media Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["media"],"summary":"Update Media","description":"Update a media item.","operationId":"update_media_api_v1_posts__post_id__media__media_id__patch","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"media_id","in":"path","required":true,"schema":{"type":"integer","title":"Media Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["media"],"summary":"Remove Media","description":"Remove media from a post.","operationId":"remove_media_api_v1_posts__post_id__media__media_id__delete","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"media_id","in":"path","required":true,"schema":{"type":"integer","title":"Media Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/media/reorder":{"post":{"tags":["media"],"summary":"Reorder Media","description":"Reorder media items for a post.","operationId":"reorder_media_api_v1_posts__post_id__media_reorder_post","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaReorder"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MediaResponse"},"title":"Response Reorder Media Api V1 Posts  Post Id  Media Reorder Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/annotations/":{"get":{"tags":["annotations"],"summary":"List Annotations","description":"List all top-level annotations for a post (with nested replies).","operationId":"list_annotations_api_v1_posts__post_id__annotations__get","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AnnotationResponse"},"title":"Response List Annotations Api V1 Posts  Post Id  Annotations  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["annotations"],"summary":"Create Annotation","description":"Create an annotation on a post. Set parent_id to reply to an existing annotation.","operationId":"create_annotation_api_v1_posts__post_id__annotations__post","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnnotationCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnnotationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/annotations/{annotation_id}":{"get":{"tags":["annotations"],"summary":"Get Annotation","description":"Get a single annotation with its replies.","operationId":"get_annotation_api_v1_posts__post_id__annotations__annotation_id__get","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"annotation_id","in":"path","required":true,"schema":{"type":"integer","title":"Annotation Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnnotationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["annotations"],"summary":"Update Annotation","description":"Update an annotation.","operationId":"update_annotation_api_v1_posts__post_id__annotations__annotation_id__patch","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"annotation_id","in":"path","required":true,"schema":{"type":"integer","title":"Annotation Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnnotationUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnnotationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["annotations"],"summary":"Delete Annotation","description":"Delete an annotation and its replies.","operationId":"delete_annotation_api_v1_posts__post_id__annotations__annotation_id__delete","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"annotation_id","in":"path","required":true,"schema":{"type":"integer","title":"Annotation Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/blocks/":{"get":{"tags":["blocks"],"summary":"List Blocks","description":"List all blocks for a post.","operationId":"list_blocks_api_v1_posts__post_id__blocks__get","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/BlockResponse"},"title":"Response List Blocks Api V1 Posts  Post Id  Blocks  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["blocks"],"summary":"Create Block","description":"Create a block in a post.","operationId":"create_block_api_v1_posts__post_id__blocks__post","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlockCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlockResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/blocks/{block_id}":{"get":{"tags":["blocks"],"summary":"Get Block","description":"Get a single block.","operationId":"get_block_api_v1_posts__post_id__blocks__block_id__get","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"block_id","in":"path","required":true,"schema":{"type":"integer","title":"Block Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlockResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["blocks"],"summary":"Update Block","description":"Update a block.\n\nOptimistic locking: pass `If-Match: <version>` header or set\n`expected_version` in the body. On mismatch the server returns 409\nConflict with the current block state.","operationId":"update_block_api_v1_posts__post_id__blocks__block_id__patch","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"block_id","in":"path","required":true,"schema":{"type":"integer","title":"Block Id"}},{"name":"If-Match","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"If-Match"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlockUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlockResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["blocks"],"summary":"Delete Block","description":"Delete a block.","operationId":"delete_block_api_v1_posts__post_id__blocks__block_id__delete","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"block_id","in":"path","required":true,"schema":{"type":"integer","title":"Block Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/blocks/reorder":{"post":{"tags":["blocks"],"summary":"Reorder Blocks","description":"Reorder blocks for a post.","operationId":"reorder_blocks_api_v1_posts__post_id__blocks_reorder_post","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlockReorder"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/BlockResponse"},"title":"Response Reorder Blocks Api V1 Posts  Post Id  Blocks Reorder Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/profiles/{author_id}":{"get":{"tags":["profiles"],"summary":"Get Profile","description":"Get user profile by author_id.","operationId":"get_profile_api_v1_profiles__author_id__get","parameters":[{"name":"author_id","in":"path","required":true,"schema":{"type":"string","title":"Author Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["profiles"],"summary":"Upsert Profile","description":"Create or update a user profile.","operationId":"upsert_profile_api_v1_profiles__author_id__put","parameters":[{"name":"author_id","in":"path","required":true,"schema":{"type":"string","title":"Author Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileCreate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["profiles"],"summary":"Update Profile","description":"Partially update a user profile.","operationId":"update_profile_api_v1_profiles__author_id__patch","parameters":[{"name":"author_id","in":"path","required":true,"schema":{"type":"string","title":"Author Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/revisions/":{"get":{"tags":["revisions"],"summary":"List Revisions","description":"List all revisions for a post, newest first.","operationId":"list_revisions_api_v1_posts__post_id__revisions__get","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/RevisionListItem"},"title":"Response List Revisions Api V1 Posts  Post Id  Revisions  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/revisions/latest":{"get":{"tags":["revisions"],"summary":"Get Latest Revision","description":"Get the most recent revision (for diff comparison).","operationId":"get_latest_revision_api_v1_posts__post_id__revisions_latest_get","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/RevisionDetailResponse"},{"type":"null"}],"title":"Response Get Latest Revision Api V1 Posts  Post Id  Revisions Latest Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/revisions/{revision_id}":{"get":{"tags":["revisions"],"summary":"Get Revision","description":"Get a specific revision with full content.","operationId":"get_revision_api_v1_posts__post_id__revisions__revision_id__get","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"revision_id","in":"path","required":true,"schema":{"type":"integer","title":"Revision Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RevisionDetailResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/references/":{"get":{"tags":["references"],"summary":"List References","description":"List all references for a post, ordered by ref_number.","operationId":"list_references_api_v1_posts__post_id__references__get","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ReferenceResponse"},"title":"Response List References Api V1 Posts  Post Id  References  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["references"],"summary":"Create Reference","description":"Create a reference on a post.","operationId":"create_reference_api_v1_posts__post_id__references__post","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReferenceCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReferenceResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/references/{reference_id}":{"get":{"tags":["references"],"summary":"Get Reference","description":"Get a single reference.","operationId":"get_reference_api_v1_posts__post_id__references__reference_id__get","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"reference_id","in":"path","required":true,"schema":{"type":"integer","title":"Reference Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReferenceResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["references"],"summary":"Update Reference","description":"Update a reference.","operationId":"update_reference_api_v1_posts__post_id__references__reference_id__patch","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"reference_id","in":"path","required":true,"schema":{"type":"integer","title":"Reference Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReferenceUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReferenceResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["references"],"summary":"Delete Reference","description":"Delete a reference.","operationId":"delete_reference_api_v1_posts__post_id__references__reference_id__delete","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"reference_id","in":"path","required":true,"schema":{"type":"integer","title":"Reference Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/stories/":{"get":{"tags":["stories"],"summary":"List Stories","description":"List all stories in a given language.\n\nReturns story cards (no full scene text) with available_languages info.","operationId":"list_stories_api_v1_stories__get","parameters":[{"name":"language","in":"query","required":false,"schema":{"type":"string","description":"Language filter","default":"de","title":"Language"},"description":"Language filter"},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^(draft|published|archived)$"},{"type":"null"}],"default":"published","title":"Status"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StoryListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["stories"],"summary":"Create Story","description":"Create a new story with scenes.\n\nAutomatically builds the correct Post structure with metadata_json and\nJSON content from the provided flat parameters.","operationId":"create_story_api_v1_stories__post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StoryCreateRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StoryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/stories/{story_group}/languages":{"get":{"tags":["stories"],"summary":"Get Story Languages","description":"List all available languages for a story group.","operationId":"get_story_languages_api_v1_stories__story_group__languages_get","parameters":[{"name":"story_group","in":"path","required":true,"schema":{"type":"string","title":"Story Group"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/stories/{story_group}/generate-languages":{"post":{"tags":["stories"],"summary":"Generate Story Languages","description":"Batch-generate story translations for multiple languages.\n\nOnly generates TEXT — no audio generation.","operationId":"generate_story_languages_api_v1_stories__story_group__generate_languages_post","parameters":[{"name":"story_group","in":"path","required":true,"schema":{"type":"string","title":"Story Group"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/content__routes__stories__GenerateLanguagesRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/content__routes__stories__GenerateLanguagesResult"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/stories/{story_group}":{"get":{"tags":["stories"],"summary":"Get Story","description":"Get a story by group ID and language.\n\nFehlt die angefragte Sprachfassung, kommt **404 mit\n`available_languages`** — der Aufrufer sieht also, was existiert, und\nkann selbst entscheiden (z.B. erneut in der Grundsprache anfragen).\n\n`auto_generate=true` übersetzt stattdessen sofort. Das ist ein\n**opt-in**, seit 2026-08-11: Der Vorgabewert war bis dahin `True`,\nwodurch jeder gewöhnliche Lesezugriff auf eine fehlende Fassung\nungefragt einen kostenpflichtigen LLM-Aufruf auslöste — ein GET, das\nGeld ausgibt. Aufgefallen ist es nur, weil der Anbieter erschöpft war\nund die Übersetzung mit 502 scheiterte: Die Leser bekamen 500 statt\neiner Antwort (Meldung Tschepp, Tscheppa-App, Track 30). Ohne diesen\nAusfall wäre die Kostenseite unbemerkt geblieben.\n\nGleiches Muster wie `GET /posts/{id}/language/{lang}?auto_generate=true`\n— Erzeugen ist überall ausdrücklich zu verlangen, nie Nebenwirkung\neines Lesevorgangs.","operationId":"get_story_api_v1_stories__story_group__get","parameters":[{"name":"story_group","in":"path","required":true,"schema":{"type":"string","title":"Story Group"}},{"name":"language","in":"query","required":false,"schema":{"type":"string","description":"Language code","default":"de","title":"Language"},"description":"Language code"},{"name":"auto_generate","in":"query","required":false,"schema":{"type":"boolean","description":"Übersetzen, wenn die Fassung fehlt. Kostet Geld (LLM-Aufruf) und muss deshalb ausdrücklich verlangt werden.","default":false,"title":"Auto Generate"},"description":"Übersetzen, wenn die Fassung fehlt. Kostet Geld (LLM-Aufruf) und muss deshalb ausdrücklich verlangt werden."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StoryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["stories"],"summary":"Update Story","description":"Update an existing story.\n\nOnly provided (non-null) fields are updated. Scenes replace all existing\nscenes if provided.","operationId":"update_story_api_v1_stories__story_group__put","parameters":[{"name":"story_group","in":"path","required":true,"schema":{"type":"string","title":"Story Group"}},{"name":"language","in":"query","required":false,"schema":{"type":"string","description":"Language code","default":"de","title":"Language"},"description":"Language code"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StoryUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StoryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/stories/{story_group}/generate-audio":{"post":{"tags":["stories"],"summary":"Generate Audio for Story Scenes","description":"Generate dramatic TTS audio for story scenes via ai-api AudioDramaService.\n\nFor each scene: AI agent builds dramatic script → ElevenLabs TTS → audio saved as media.\nExisting audio for a scene is replaced.","operationId":"generate_story_audio_api_v1_stories__story_group__generate_audio_post","parameters":[{"name":"story_group","in":"path","required":true,"schema":{"type":"string","title":"Story Group"}},{"name":"language","in":"query","required":false,"schema":{"type":"string","default":"de","title":"Language"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateAudioRequest","default":{}}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateAudioResult"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/collections/":{"get":{"tags":["collections"],"summary":"List Collections","description":"List collections with post and children counts.\n\n- parent_id: filter by parent collection\n- root_only: if true, only return top-level collections (parent_id IS NULL)","operationId":"list_collections_api_v1_collections__get","parameters":[{"name":"parent_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Parent Id"}},{"name":"root_only","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Root Only"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CollectionResponse"},"title":"Response List Collections Api V1 Collections  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["collections"],"summary":"Create Collection","description":"Create a new collection.","operationId":"create_collection_api_v1_collections__post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/collections/{slug}":{"get":{"tags":["collections"],"summary":"Get Collection","description":"Get a collection by slug with its posts.","operationId":"get_collection_api_v1_collections__slug__get","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionDetailResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/collections/{collection_id}":{"put":{"tags":["collections"],"summary":"Update Collection","description":"Update a collection.","operationId":"update_collection_api_v1_collections__collection_id__put","parameters":[{"name":"collection_id","in":"path","required":true,"schema":{"type":"integer","title":"Collection Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["collections"],"summary":"Delete Collection","description":"Delete a collection (posts are not deleted).","operationId":"delete_collection_api_v1_collections__collection_id__delete","parameters":[{"name":"collection_id","in":"path","required":true,"schema":{"type":"integer","title":"Collection Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/collections/{collection_id}/posts/{post_id}":{"post":{"tags":["collections"],"summary":"Add Post To Collection","description":"Add a post to a collection.","operationId":"add_post_to_collection_api_v1_collections__collection_id__posts__post_id__post","parameters":[{"name":"collection_id","in":"path","required":true,"schema":{"type":"integer","title":"Collection Id"}},{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}}],"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostCollectionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["collections"],"summary":"Remove Post From Collection","description":"Remove a post from a collection.","operationId":"remove_post_from_collection_api_v1_collections__collection_id__posts__post_id__delete","parameters":[{"name":"collection_id","in":"path","required":true,"schema":{"type":"integer","title":"Collection Id"}},{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/collections/":{"get":{"tags":["collections"],"summary":"List Post Collections","description":"List all collections a post belongs to.","operationId":"list_post_collections_api_v1_posts__post_id__collections__get","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CollectionResponse"},"title":"Response List Post Collections Api V1 Posts  Post Id  Collections  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/annotations-knowledge/":{"get":{"tags":["annotations-knowledge"],"summary":"List Annotation Knowledge","description":"List all annotation knowledge entries, optionally filtered.","operationId":"list_annotation_knowledge_api_v1_annotations_knowledge__get","parameters":[{"name":"language","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Language"}},{"name":"source_storage_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Source Storage Id"}},{"name":"detail_level","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail Level"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnnotationKnowledgeListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["annotations-knowledge"],"summary":"Create Annotation Knowledge","description":"Create a new annotation knowledge entry.","operationId":"create_annotation_knowledge_api_v1_annotations_knowledge__post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnnotationKnowledgeRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnnotationKnowledgeResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/annotations-knowledge/{post_id}":{"get":{"tags":["annotations-knowledge"],"summary":"Get Annotation Knowledge","description":"Get a single annotation knowledge entry.","operationId":"get_annotation_knowledge_api_v1_annotations_knowledge__post_id__get","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnnotationKnowledgeResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["annotations-knowledge"],"summary":"Update Annotation Knowledge","description":"Update annotation knowledge content.","operationId":"update_annotation_knowledge_api_v1_annotations_knowledge__post_id__put","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAnnotationKnowledgeRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnnotationKnowledgeResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/annotations-knowledge/source/{source_storage_id}":{"get":{"tags":["annotations-knowledge"],"summary":"Get By Source","description":"Get annotation knowledge by source storage ID, language and detail level.","operationId":"get_by_source_api_v1_annotations_knowledge_source__source_storage_id__get","parameters":[{"name":"source_storage_id","in":"path","required":true,"schema":{"type":"integer","title":"Source Storage Id"}},{"name":"language","in":"query","required":false,"schema":{"type":"string","default":"de","title":"Language"}},{"name":"detail_level","in":"query","required":false,"schema":{"type":"string","default":"standard","title":"Detail Level"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnnotationKnowledgeResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/annotations-knowledge/source/{source_storage_id}/languages":{"get":{"tags":["annotations-knowledge"],"summary":"Get Source Languages","description":"Get available languages for a source + detail level.","operationId":"get_source_languages_api_v1_annotations_knowledge_source__source_storage_id__languages_get","parameters":[{"name":"source_storage_id","in":"path","required":true,"schema":{"type":"integer","title":"Source Storage Id"}},{"name":"detail_level","in":"query","required":false,"schema":{"type":"string","default":"standard","title":"Detail Level"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LanguagesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/annotations-knowledge/{annotation_group}/generate-languages":{"post":{"tags":["annotations-knowledge"],"summary":"Generate Languages","description":"Generate translations for annotation knowledge.\nUses the same AI translation engine as stories.","operationId":"generate_languages_api_v1_annotations_knowledge__annotation_group__generate_languages_post","parameters":[{"name":"annotation_group","in":"path","required":true,"schema":{"type":"string","title":"Annotation Group"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/content__routes__annotations_knowledge__GenerateLanguagesRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/content__routes__annotations_knowledge__GenerateLanguagesResult"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/annotations-knowledge/{post_id}/generate-audio":{"post":{"tags":["annotations-knowledge"],"summary":"Generate Audio for Annotation Knowledge","description":"Generate educational TTS audio for annotation knowledge via ai-api NarrationService.\n\nMode 'all': generates object description audio + each annotation audio (alternating characters).\nAudio refs are stored directly in the post content.","operationId":"generate_annotation_audio_endpoint_api_v1_annotations_knowledge__post_id__generate_audio_post","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateAnnotationAudioRequest","default":{"mode":"all"}}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateAnnotationAudioResult"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/doc-types":{"get":{"tags":["posts"],"summary":"List Doc Types","description":"List all distinct doc_types currently in use.","operationId":"list_doc_types_api_v1_doc_types_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/logos":{"get":{"tags":["posts"],"summary":"List Logos","description":"List available logo presets for PDF export branding.","operationId":"list_logos_api_v1_logos_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}},"post":{"tags":["posts"],"summary":"Add Logo","description":"Add a logo preset. Body: {\"url\": \"...\", \"label\": \"...\"}","operationId":"add_logo_api_v1_logos_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["posts"],"summary":"Remove Logo","description":"Remove a logo preset by URL.","operationId":"remove_logo_api_v1_logos_delete","parameters":[{"name":"url","in":"query","required":true,"schema":{"type":"string","title":"Url"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tags":{"get":{"tags":["posts"],"summary":"List Tags","description":"List all distinct tags in use across all posts.","operationId":"list_tags_api_v1_tags_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/posts/{post_id}/crdt/apply":{"post":{"tags":["crdt"],"summary":"Crdt Apply","description":"Apply a non-WS edit to a CRDT-backed post.\n\n`text` mode replaces the document's contents — internally we compute\nthe diff against the current state so other clients see only the\ninsert/delete delta, not a full reset. `update_b64` mode applies a\nraw Yjs update (for clients that already encode their own updates).","operationId":"crdt_apply_api_v1_posts__post_id__crdt_apply_post","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CRDTApplyRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/crdt/reset":{"post":{"tags":["crdt"],"summary":"Crdt Reset","description":"Wipe the CRDT state for a post — snapshot + op-log + in-memory session.\n\nUseful when a post's CRDT state got \"type-locked\" to the wrong Yjs\nroot type (e.g. an early test wrote Y.Text where TipTap expects\nY.XmlFragment). After reset the next WS connect starts with a fresh\nempty Doc and the client's first updates determine the type.\n\nLeaves `posts.content` untouched (the snapshot-materialized text\nstays as last-known) so the post isn't visually destroyed by the\nreset. To wipe the text too, follow up with a regular posts_update.\n\nReturns: { post_id, deleted_updates, snapshot_dropped, session_evicted }","operationId":"crdt_reset_api_v1_posts__post_id__crdt_reset_post","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/crdt/text":{"get":{"tags":["crdt"],"summary":"Crdt Get Live Text","description":"Return the live in-memory CRDT text — bypasses the snapshot lag.\n\n`posts.content` is only refreshed every N=50 ops or 60s by the\nsnapshot loop, so a `posts_get` right after a flurry of WS edits\nsees stale content. This endpoint reads the session's authoritative\ntext directly, so an agent that wants to know \"what does the human\nhave on screen RIGHT NOW\" gets the real answer instead of the last\nsnapshot.\n\nCold-starts a session if no one's connected (loads snapshot + replays\nop-log), so the answer is always coherent even when no WS is open.\n\nReturns: { post_id, text, version, length }\n  - version: highest seq in `crdt_updates` for this post","operationId":"crdt_get_live_text_api_v1_posts__post_id__crdt_text_get","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/crdt/backfill_created_at":{"post":{"tags":["crdt"],"summary":"Crdt Backfill Created At","description":"One-shot backfill of paragraph `created_at` attrs for legacy posts.\n\nStamps any paragraph whose `created_at` is null with\n`posts.created_at + (paragraph_index * epsilon_seconds)`.  Already-\nstamped paragraphs are skipped (idempotent — re-running this is a\nno-op once all stamps are present).  Single CRDT transaction →\none op-log entry, one WS broadcast, no notify push.\n\nPhase 2 Whiteboard-Timeline backfill (Issue #10) — for posts whose\nparagraphs predate the stamping deploy.  Once stamped, the canvas\nTimelineLayouter renders them on the real time axis even though\nthe original write timestamps weren't captured at write time.","operationId":"crdt_backfill_created_at_api_v1_posts__post_id__crdt_backfill_created_at_post","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"epsilon_seconds","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"Epsilon Seconds"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/crdt/structured":{"get":{"tags":["crdt"],"summary":"Crdt Get Structured","description":"Return structured paragraph-list with per-block author attribution.\n\nAgents use this to target their edits precisely (V2.6 modes\n`insert_after_paragraph`, `replace_paragraph`, etc need a\nparagraph_index — fetch this first to know what's where).\n\nEach paragraph in the response carries:\n  - index: 0-based position in the document\n  - text: plain text content (XML tags stripped)\n  - author_id: who wrote it (set by REST writes via Block-Level\n    Authorship; null for content written before V2.2 deploy)\n  - author_name, author_color: cosmetic metadata for the same author\n  - is_heading: true if the line starts with `#`, `##`, `###`\n  - heading_level: 1/2/3 for headings, null otherwise\n\nReturns: { post_id, version, paragraphs: [...] }","operationId":"crdt_get_structured_api_v1_posts__post_id__crdt_structured_get","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"include_authorship","in":"query","required":false,"schema":{"type":"boolean","description":"Opt-in V2.3 word-level authorship runs. Defaults false so agents/range-readers never receive authorship metadata unless they explicitly ask for it.","default":false,"title":"Include Authorship"},"description":"Opt-in V2.3 word-level authorship runs. Defaults false so agents/range-readers never receive authorship metadata unless they explicitly ask for it."},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/agents/available":{"get":{"tags":["agents"],"summary":"List Available Agents","description":"Return the agents this caller may subscribe to in Notify-Authors.\n\nReturns `{agents: [{name, node, owner_email, tenant_id, is_self_owned,\nis_public}], count: <int>}` — sorted with self-owned agents first,\nthen by name.","operationId":"list_available_agents_api_v1_agents_available_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Available Agents Api V1 Agents Available Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/field_map":{"get":{"tags":["field_map"],"summary":"Get Field Map","description":"Return the field_map graph for a post.\n\n`scope` must be `post:<id>`. Other scope types (federation, agent)\nare Phase B+.","operationId":"get_field_map_api_v1_field_map_get","parameters":[{"name":"scope","in":"query","required":true,"schema":{"type":"string","description":"Scope spec, currently only 'post:<id>'","title":"Scope"},"description":"Scope spec, currently only 'post:<id>'"},{"name":"detail","in":"query","required":false,"schema":{"type":"string","description":"'compact' (structural graph, default), 'full' (adds debug data + Phase-B metrics on section nodes), 'metrics' (Phase-B Counter-Salience: tensions, density, dominance — preferred for SalienceOverlay consumers)","default":"compact","title":"Detail"},"description":"'compact' (structural graph, default), 'full' (adds debug data + Phase-B metrics on section nodes), 'metrics' (Phase-B Counter-Salience: tensions, density, dominance — preferred for SalienceOverlay consumers)"},{"name":"time_window_hours","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"(Phase B) Only include changes within this many hours. Currently informational only — Phase A returns whole post.","title":"Time Window Hours"},"description":"(Phase B) Only include changes within this many hours. Currently informational only — Phase A returns whole post."},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Field Map Api V1 Field Map Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/claims":{"post":{"tags":["presence"],"summary":"Create Claim","description":"Region claimen. Eigener bestehender Claim derselben Region wird\nerneuert (renewed=true, Status bleibt 201 — Idempotenz vor\nStatus-Code-Feinheit).","operationId":"create_claim_api_v1_posts__post_id__claims_post","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimBody"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["presence"],"summary":"List Claims","description":"Aktive (held + TTL-lebendige) Claims des Posts.","operationId":"list_claims_api_v1_posts__post_id__claims_get","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/claims/{claim_id}/renew":{"post":{"tags":["presence"],"summary":"Renew Claim","description":"Heartbeat: Lease verlängern. Nur der Holder kann verlängern;\nein abgelaufener/fremder Claim gibt 404 — dann neu claimen.","operationId":"renew_claim_api_v1_posts__post_id__claims__claim_id__renew_post","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"claim_id","in":"path","required":true,"schema":{"type":"string","title":"Claim Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenewBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/claims/{claim_id}/release":{"post":{"tags":["presence"],"summary":"Release Claim","description":"held → released. Idempotent für den Holder (nochmaliges release\ngibt den Ist-Zustand zurück, kein Fehler).","operationId":"release_claim_api_v1_posts__post_id__claims__claim_id__release_post","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"claim_id","in":"path","required":true,"schema":{"type":"string","title":"Claim Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/collab/collision-metrics":{"get":{"tags":["collab-metrics"],"summary":"Collision Metrics","operationId":"collision_metrics_api_v1_collab_collision_metrics_get","parameters":[{"name":"window","in":"query","required":false,"schema":{"type":"string","description":"Fenster, z.B. '7d' oder '30d' (Kappe 90d).","default":"7d","title":"Window"},"description":"Fenster, z.B. '7d' oder '30d' (Kappe 90d)."},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/field_map":{"get":{"tags":["field_map"],"summary":"Get Post Field Map","description":"Issue #226: post-scoped Pfad-Alias für CloudV2s Feld-Karte —\nidentische Shape wie GET /field_map?scope=post:N und das MCP-Tool.","operationId":"get_post_field_map_api_v1_posts__post_id__field_map_get","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"detail","in":"query","required":false,"schema":{"type":"string","description":"'compact' | 'full' | 'metrics' — wie /field_map.","default":"compact","title":"Detail"},"description":"'compact' | 'full' | 'metrics' — wie /field_map."},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Post Field Map Api V1 Posts  Post Id  Field Map Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/edges/":{"post":{"tags":["block-edges"],"summary":"Create Edge","description":"Create one directional edge between two paragraphs in this post.\n\nReturns 409 on duplicate (same from + to + edge_type combination\nalready exists) — surfaced as JSON error with the conflicting\nedge_id so the caller can decide whether to PATCH it or skip.","operationId":"create_edge_api_v1_posts__post_id__edges__post","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlockEdgeCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlockEdgeResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["block-edges"],"summary":"List Edges","description":"List edges for a post. Optional filters apply ANDed.","operationId":"list_edges_api_v1_posts__post_id__edges__get","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"edge_type","in":"query","required":false,"schema":{"anyOf":[{"enum":["replies_to","contradicts","extends","references","synthesizes"],"type":"string"},{"type":"null"}],"description":"Filter by edge_type (replies_to/contradicts/…)","title":"Edge Type"},"description":"Filter by edge_type (replies_to/contradicts/…)"},{"name":"author","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by author_id","title":"Author"},"description":"Filter by author_id"},{"name":"from_block","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by from_block_id (outgoing edges)","title":"From Block"},"description":"Filter by from_block_id (outgoing edges)"},{"name":"to_block","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by to_block_id (incoming edges)","title":"To Block"},"description":"Filter by to_block_id (incoming edges)"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/BlockEdgeResponse"},"title":"Response List Edges Api V1 Posts  Post Id  Edges  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/edges/{edge_id}":{"get":{"tags":["block-edges"],"summary":"Get Edge","description":"Read one edge by id.","operationId":"get_edge_api_v1_posts__post_id__edges__edge_id__get","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"edge_id","in":"path","required":true,"schema":{"type":"string","title":"Edge Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlockEdgeResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["block-edges"],"summary":"Update Edge","description":"Mutate edge_type, label, or confidence. from/to/post are immutable.","operationId":"update_edge_api_v1_posts__post_id__edges__edge_id__patch","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"edge_id","in":"path","required":true,"schema":{"type":"string","title":"Edge Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlockEdgeUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlockEdgeResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["block-edges"],"summary":"Delete Edge","description":"Drop one edge.","operationId":"delete_edge_api_v1_posts__post_id__edges__edge_id__delete","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"edge_id","in":"path","required":true,"schema":{"type":"string","title":"Edge Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/uninvite":{"post":{"tags":["invite"],"summary":"Uninvite From Post","description":"Remove federation agents from a post's notify_authors — atomic\nmirror of /invite (Alex' Mid-Session-Teilnehmer-Verwaltung, CloudV2\nCollabView ✕-auf-der-Pill).\n\nServer-side read-modify-write in ONE request, statt FE-seitigem\nmetadata_json-PATCH — zwei parallele Clients können sich so keinen\nfrisch invited Agenten per last-write-wins wieder rauswerfen. Der\nchunk_committed-Fanout liest notify_authors bei jedem Commit frisch;\ndie Wirkung (keine weiteren Pushes) ist also sofort, kein Neustart.\nKein Liveness-Check und kein IACP-Ping: Entfernen ist ein reiner\nListen-Op ohne Onboarding-Gegenstück.","operationId":"uninvite_from_post_api_v1_posts__post_id__uninvite_post","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UninviteRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UninviteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/invite":{"post":{"tags":["invite"],"summary":"Invite To Post","description":"Add federation agents to a post's notify_authors AND ping them.\n\nSee module docstring for the three-step rationale.","operationId":"invite_to_post_api_v1_posts__post_id__invite_post","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InviteRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InviteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/permissions":{"get":{"tags":["permissions"],"summary":"List Permissions","description":"List all grants on this post. Granter-only (see can_grant_permissions).","operationId":"list_permissions_api_v1_posts__post_id__permissions_get","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"include_revoked","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Revoked"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PostPermissionResponse"},"title":"Response List Permissions Api V1 Posts  Post Id  Permissions Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["permissions"],"summary":"Grant Permission","description":"Add a permission grant.\n\nEmail principals get a fresh `share_token` minted automatically;\nuser/agent principals don't need one (they authenticate via their\nnormal JWT flow). Re-granting the same principal updates the\nexisting row (idempotent).","operationId":"grant_permission_api_v1_posts__post_id__permissions_post","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostPermissionCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostPermissionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/permissions/{permission_id}":{"patch":{"tags":["permissions"],"summary":"Update Permission","description":"Change permission level or expiry. Granter-only.","operationId":"update_permission_api_v1_posts__post_id__permissions__permission_id__patch","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"permission_id","in":"path","required":true,"schema":{"type":"integer","title":"Permission Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostPermissionUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostPermissionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["permissions"],"summary":"Revoke Permission","description":"Soft-revoke. Row stays for audit; queries filter on revoked_at IS NULL.","operationId":"revoke_permission_api_v1_posts__post_id__permissions__permission_id__delete","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"permission_id","in":"path","required":true,"schema":{"type":"integer","title":"Permission Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/share/{token}/redeem":{"post":{"tags":["permissions"],"summary":"Redeem Share Token","description":"Recipient hits this when they click the share link.\n\nBehaviour:\n  - If the share-token doesn't match anything live → 404.\n  - If caller HAS a valid JWT whose identity matches the grant\n    (email matches, or it's already been migrated to user:UUID) →\n    return granted=True, requires_login=False.\n  - If caller is NOT logged in OR the JWT doesn't match → return\n    requires_login=True + email so the frontend can pop the auth-api\n    magic-link flow targeted at exactly that email. Phase 3 wires\n    comm-api to send the link automatically; for now the frontend\n    triggers it.","operationId":"redeem_share_token_api_v1_share__token__redeem_post","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostPermissionRedeemResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/sections/":{"get":{"tags":["sections"],"summary":"List Sections","description":"List all sections in the post with metadata (no body content).","operationId":"list_sections_api_v1_posts__post_id__sections__get","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Type"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SectionSummary"},"title":"Response List Sections Api V1 Posts  Post Id  Sections  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["sections"],"summary":"Create Section","description":"Append a new `<section>` block to the post via the CRDT pipeline.\n\nInternally re-uses the existing `crdt/apply mode=append` path so\nsection attrs are stamped consistently with the markdown-parse flow.","operationId":"create_section_api_v1_posts__post_id__sections__post","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SectionCreateRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SectionSummary"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/sections/vision/latest":{"get":{"tags":["sections"],"summary":"Get Latest Vision","description":"Phase 2 (Vision-First-Pattern): return the most recent `vision`\nsection attached to this post, optionally filtered by `scope` attr\n(e.g. `?scope=fahrrad-v3`).\n\nBots call this BEFORE products_claim to fetch the canonical\nreference-points / style-spec / component-list the Coordinator\nhas pinned down. Body text is the human-readable spec; attrs\ncarry the structured metadata. If multiple visions exist with the\nsame scope, the latest one (by char_start) wins.","operationId":"get_latest_vision_api_v1_posts__post_id__sections_vision_latest_get","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"scope","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Scope"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VisionLatestResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/sections/{section_id}":{"get":{"tags":["sections"],"summary":"Get Section","description":"Return one section's metadata + all its paragraphs in order.","operationId":"get_section_api_v1_posts__post_id__sections__section_id__get","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"section_id","in":"path","required":true,"schema":{"type":"string","title":"Section Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SectionDetail"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["sections"],"summary":"Patch Section","description":"Update the section's attrs (e.g. status: open → resolved).\n\nRewrites the `<section …>` opening tag with merged attrs and\nre-stamps the `section_attrs` JSON on the start-paragraph. Body\nparagraphs are left untouched.","operationId":"patch_section_api_v1_posts__post_id__sections__section_id__patch","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"section_id","in":"path","required":true,"schema":{"type":"string","title":"Section Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SectionPatchRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SectionSummary"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/sections/{section_id}/reply":{"post":{"tags":["sections"],"summary":"Reply To Section","description":"Append a `<reply by=… at=…>…</reply>` block inside an existing\nsection (typically a question). Goes through the standard apply\npipeline so authoring + section attrs are stamped consistently.","operationId":"reply_to_section_api_v1_posts__post_id__sections__section_id__reply_post","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"section_id","in":"path","required":true,"schema":{"type":"string","title":"Section Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SectionReplyRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/sections/{section_id}/diff":{"post":{"tags":["sections"],"summary":"Diff Section","description":"Apply an in-place text edit inside the section. Char offsets are\nagainst the materialized text (same convention as annotations).\n\nCurrently a thin wrapper: we locate the paragraph_index that holds\n`start_pos` and emit a find_replace. Multi-paragraph diffs require\na future enhancement (the CRDT pipeline doesn't expose absolute\nchar-range edits yet).","operationId":"diff_section_api_v1_posts__post_id__sections__section_id__diff_post","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"section_id","in":"path","required":true,"schema":{"type":"string","title":"Section Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SectionDiffRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/sections/{section_id}/decline":{"post":{"tags":["sections"],"summary":"Decline Section","description":"Explicit decline of a question/task — closes the section as\n`status='declined'` and stamps the decliner + optional reason.\n\nA.2 state machine for question:\n    open → declined | timed_out | resolved\n\nAvoids \"silent open forever\" UX. The chunk_committed fires via the\napply path, so the asker sees the close in real time.","operationId":"decline_section_api_v1_posts__post_id__sections__section_id__decline_post","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"section_id","in":"path","required":true,"schema":{"type":"string","title":"Section Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SectionDeclineRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/sections/{section_id}/timeout":{"post":{"tags":["sections"],"summary":"Timeout Section","description":"Close an open section as `timed_out` — caller asserts the\nsection has expired (no answer within `due`).\n\nA.2 baseline: explicit caller-driven. A server-side auto-sweep\nagainst `section_attrs.due` could fire this same path later\nwithout changing the contract.","operationId":"timeout_section_api_v1_posts__post_id__sections__section_id__timeout_post","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"section_id","in":"path","required":true,"schema":{"type":"string","title":"Section Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SectionTimeoutRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/sections/{section_id}/resolve":{"post":{"tags":["sections"],"summary":"Resolve Section","description":"Mark a question/task as `resolved` — closes the section as\nsatisfactorily answered. Adds the resolver + optional note.\n\nState machine: question open → resolved; task open|in_progress →\nresolved. Symmetry with decline/timeout per Codex A.2 blocker 1.","operationId":"resolve_section_api_v1_posts__post_id__sections__section_id__resolve_post","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"section_id","in":"path","required":true,"schema":{"type":"string","title":"Section Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SectionResolveRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/sections/{section_id}/approve":{"post":{"tags":["sections"],"summary":"Approve Section","description":"Approve the current revision of a product section.\n\nA.3.5 spec (post-#889 q-7eed39ff7100):\n  - section_type must be 'product'\n  - caller must be in section.reviewers (or 'open' which means any\n    notify_author may approve)\n  - adds caller's agent name to section_attrs.approvals\n  - if approvals ⊇ reviewers (and reviewers != 'open' or all\n    notify_authors approved) → status auto-flips draft → approved\n\nBehaves idempotently: a second approve from the same caller is a\nno-op (no duplicate entry, no status flip-flop).","operationId":"approve_section_api_v1_posts__post_id__sections__section_id__approve_post","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"section_id","in":"path","required":true,"schema":{"type":"string","title":"Section Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SectionApproveRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/sections/{section_id}/handoff":{"post":{"tags":["sections"],"summary":"Handoff Section","description":"Transfer ownership of a product section to another agent.\n\nA.3.7: only the current owner may hand off. Records the transfer\nin section_attrs.handoff_history (newline-separated audit list:\n\"old → new @ ISO timestamp; reason\").\n\nReturns 403 not_current_owner when caller isn't the current owner.\nReturns 409 section_type_not_eligible for non-product sections.","operationId":"handoff_section_api_v1_posts__post_id__sections__section_id__handoff_post","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"section_id","in":"path","required":true,"schema":{"type":"string","title":"Section Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SectionHandoffRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/sections/{section_id}/editors":{"post":{"tags":["sections"],"summary":"Update Section Editors","description":"Editor-Liste eines Product pflegen — der kleine Bruder des Handoffs.\n\nWarum es das braucht: `editors` ist server-owned und damit über PATCH\nfür jeden gesperrt (403 `server_owned_product_attrs`). Als Ausweg nannte\nder Hinweis bisher nur `handoff` — der überträgt aber gleich das\nEIGENTUM. Wer jemanden bloß mitschreiben lassen wollte, musste die\nVerantwortung abgeben; wer die Verantwortung behalten wollte, konnte\nniemanden hinzunehmen. Aufgefallen 2026-08-07 an Post 4431/\np-5cde1ac88a89, wo genau ein Editor-Eintrag verlangt und ein\nEigentümerwechsel ausdrücklich ausgeschlossen war — beides zusammen\nwar schlicht nicht durchführbar.\n\nBerechtigung wie beim Handoff: der aktuelle Eigentümer, plus ein\nauditierter Admin-Notausgang für den Fall, dass er handlungsunfähig\nist. Jede Änderung landet in `editors_history`.\n\nRührt `approvals` NICHT an: geschrieben wird ausschließlich die\nSection-Startzeile, und die Abnahme-Invalidierung greift nur bei\n`section_role='content'`. Ein Editor-Eintrag entwertet also keine\nbestehende Freigabe — die Mitschreib-Erlaubnis ist keine inhaltliche\nÄnderung.","operationId":"update_section_editors_api_v1_posts__post_id__sections__section_id__editors_post","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"section_id","in":"path","required":true,"schema":{"type":"string","title":"Section Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SectionEditorsRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/sections/{section_id}/vote":{"post":{"tags":["sections"],"summary":"Cast Vote","description":"Cast a vote on a voting section.\n\nIteration D — MVP:\n- section_type must be 'vote' and status='open'\n- caller must be in voters (or voters='open' → any notify_author)\n- choice must be in options (or options='open' → any string)\n- votes are idempotent per voter: re-vote overwrites previous\n- after each vote, server tallies:\n  - threshold='majority' (default): top > 50% of eligible → tallied\n  - threshold='all': every eligible voter cast + unanimous → tallied\n  - threshold='<N>': top count ≥ N → tallied\n\nOn threshold-met, server flips status='open' → 'tallied', stamps\nwinner + tallied_at + tallied_by. A.D.2 will add derived action\nbased on attrs.action_type.","operationId":"cast_vote_api_v1_posts__post_id__sections__section_id__vote_post","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"section_id","in":"path","required":true,"schema":{"type":"string","title":"Section Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SectionVoteRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/products/claim":{"post":{"tags":["products"],"summary":"Claim Product","description":"Atomic canonical-claim. Race-safe via DB UNIQUE constraint plus\nper-post tenant gate via assert_can_access.\n\nIdempotency uses reservation-first semantics (Codex P0.9): the\nidempotency_records row is INSERTED in state='in_progress' BEFORE\nthe product insert. Two parallel callers with same key can't both\nexecute the side effect even if they have different\ncollaboration_keys.","operationId":"claim_product_api_v1_posts__post_id__products_claim_post","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/products/{product_id}/components/{component_id}/reserve":{"post":{"tags":["components"],"summary":"Reserve Component","description":"Claim a fresh hold on (product_id, component_id).\n\nReturns the plaintext token ONCE. Persists only the HMAC hash.","operationId":"reserve_component_api_v1_products__product_id__components__component_id__reserve_post","parameters":[{"name":"product_id","in":"path","required":true,"schema":{"type":"string","title":"Product Id"}},{"name":"component_id","in":"path","required":true,"schema":{"type":"string","title":"Component Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReserveRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReserveResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/products/{product_id}/components/{component_id}/heartbeat":{"post":{"tags":["components"],"summary":"Heartbeat Component","operationId":"heartbeat_component_api_v1_products__product_id__components__component_id__heartbeat_post","parameters":[{"name":"product_id","in":"path","required":true,"schema":{"type":"string","title":"Product Id"}},{"name":"component_id","in":"path","required":true,"schema":{"type":"string","title":"Component Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HeartbeatRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HeartbeatResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/products/{product_id}/components/{component_id}/release":{"post":{"tags":["components"],"summary":"Release Component","operationId":"release_component_api_v1_products__product_id__components__component_id__release_post","parameters":[{"name":"product_id","in":"path","required":true,"schema":{"type":"string","title":"Product Id"}},{"name":"component_id","in":"path","required":true,"schema":{"type":"string","title":"Component Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/products/{product_id}/components/{component_id}/revoke":{"post":{"tags":["components"],"summary":"Revoke Component","description":"Privileged revoke. Codex gate: only creator (stable id) or\nsuperadmin may execute.","operationId":"revoke_component_api_v1_products__product_id__components__component_id__revoke_post","parameters":[{"name":"product_id","in":"path","required":true,"schema":{"type":"string","title":"Product Id"}},{"name":"component_id","in":"path","required":true,"schema":{"type":"string","title":"Component Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RevokeRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RevokeResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/products/{product_id}/components/{component_id}":{"get":{"tags":["components"],"summary":"Get Component","description":"SOCM Phase 4.4.3 — Component-Detail read endpoint.\n\nRead-only state view of a single ProductComponent. Same opaque-404\ndiscipline as POST routes (foreign-tenant probing must surface as\nnot_found, not 403). Unknown component_id under a valid product\nsurfaces as 404 component_not_found — the product is known, so\ndistinguishing component existence is not a tenant-probe vector.","operationId":"get_component_api_v1_products__product_id__components__component_id__get","parameters":[{"name":"product_id","in":"path","required":true,"schema":{"type":"string","title":"Product Id"}},{"name":"component_id","in":"path","required":true,"schema":{"type":"string","title":"Component Id"}},{"name":"include_content","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Content"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComponentDetailResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/products/{product_id}/components/{component_id}/apply":{"post":{"tags":["components"],"summary":"Apply Component Route","description":"SOCM Phase B.4b.2 — Component Apply.\n\nGate A: auth + lifecycle + payload validation BEFORE idempotency\nclaim. Identity.id binds the reservation; body cannot supply\nholder_id (extra='forbid').\n\nGate D: response carries product_id, component_id, revisions,\ncontent_hash, reservation_state='released', render_state='pending',\nidempotent_replay.","operationId":"apply_component_route_api_v1_products__product_id__components__component_id__apply_post","parameters":[{"name":"product_id","in":"path","required":true,"schema":{"type":"string","title":"Product Id"}},{"name":"component_id","in":"path","required":true,"schema":{"type":"string","title":"Component Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApplyRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApplyResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/products/{product_id}/components/{component_id}/regions":{"get":{"tags":["regions"],"summary":"List Regions","description":"SOCM Phase 4.4.3 — list region-reservations for one component.\n\nRead-only. Filters: ``state`` (one of held/released/revoked/expired)\nand ``region_id`` (exact). No state filter returns ALL rows for the\ncomponent including audit history (released/revoked/expired). Use\n?state=held for the active-lock-view that's analogous to\ncomponent_reservations' single-held semantics.\n\nToken HMAC is never returned (server-side credential). Plaintext\ntoken cannot leak — it's not persisted at all.","operationId":"list_regions_api_v1_products__product_id__components__component_id__regions_get","parameters":[{"name":"product_id","in":"path","required":true,"schema":{"type":"string","title":"Product Id"}},{"name":"component_id","in":"path","required":true,"schema":{"type":"string","title":"Component Id"}},{"name":"state","in":"query","required":false,"schema":{"anyOf":[{"enum":["held","released","revoked","expired"],"type":"string"},{"type":"null"}],"title":"State"}},{"name":"region_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Region Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegionListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/products/{product_id}/components/{component_id}/regions/{region_id}/reserve":{"post":{"tags":["regions"],"summary":"Reserve Region","description":"Claim a sub-component region lock.\n\nReturns plaintext token ONCE alongside the convention_hint that\nreminds the holder of Federation Max-Effort discipline (Politeness-\nConvention §12.4).","operationId":"reserve_region_api_v1_products__product_id__components__component_id__regions__region_id__reserve_post","parameters":[{"name":"product_id","in":"path","required":true,"schema":{"type":"string","title":"Product Id"}},{"name":"component_id","in":"path","required":true,"schema":{"type":"string","title":"Component Id"}},{"name":"region_id","in":"path","required":true,"schema":{"type":"string","title":"Region Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegionReserveRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegionReserveResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/products/{product_id}/components/{component_id}/regions/{claim_id}/release":{"post":{"tags":["regions"],"summary":"Release Region","operationId":"release_region_api_v1_products__product_id__components__component_id__regions__claim_id__release_post","parameters":[{"name":"product_id","in":"path","required":true,"schema":{"type":"string","title":"Product Id"}},{"name":"component_id","in":"path","required":true,"schema":{"type":"string","title":"Component Id"}},{"name":"claim_id","in":"path","required":true,"schema":{"type":"string","title":"Claim Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegionReleaseRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegionReleaseResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/products/{product_id}/components/{component_id}/regions/{claim_id}/apply":{"post":{"tags":["regions"],"summary":"Apply Region Route","description":"Apply a region-scoped patch and release the lock atomically.","operationId":"apply_region_route_api_v1_products__product_id__components__component_id__regions__claim_id__apply_post","parameters":[{"name":"product_id","in":"path","required":true,"schema":{"type":"string","title":"Product Id"}},{"name":"component_id","in":"path","required":true,"schema":{"type":"string","title":"Component Id"}},{"name":"claim_id","in":"path","required":true,"schema":{"type":"string","title":"Claim Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegionApplyRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegionApplyResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/products/{product_id}/components/{component_id}/regions/{claim_id}/revoke":{"post":{"tags":["regions"],"summary":"Revoke Region","description":"Admin-revoke a region lock without the token.\n\nAuthorization: today this trusts require_write — Codex' Phase B\nreview notes that revoke is privileged. For Phase 4.2 MVP we keep\nparity with component-revoke (write-permission); a stricter\ncreator-or-superadmin check will follow in 4.3 to mirror\ncomponents.revoke_component exactly.","operationId":"revoke_region_api_v1_products__product_id__components__component_id__regions__claim_id__revoke_post","parameters":[{"name":"product_id","in":"path","required":true,"schema":{"type":"string","title":"Product Id"}},{"name":"component_id","in":"path","required":true,"schema":{"type":"string","title":"Component Id"}},{"name":"claim_id","in":"path","required":true,"schema":{"type":"string","title":"Claim Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegionRevokeRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegionRevokeResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/products/{product_id}/components/{component_id}/element-claims/reserve":{"post":{"tags":["element-claims"],"summary":"Reserve Element Claim","operationId":"reserve_element_claim_api_v1_products__product_id__components__component_id__element_claims_reserve_post","parameters":[{"name":"product_id","in":"path","required":true,"schema":{"type":"string","title":"Product Id"}},{"name":"component_id","in":"path","required":true,"schema":{"type":"string","title":"Component Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ElementClaimReserveRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ElementClaimReserveResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/products/{product_id}/components/{component_id}/element-claims/{claim_id}/apply":{"post":{"tags":["element-claims"],"summary":"Apply Element Claim Route","operationId":"apply_element_claim_route_api_v1_products__product_id__components__component_id__element_claims__claim_id__apply_post","parameters":[{"name":"product_id","in":"path","required":true,"schema":{"type":"string","title":"Product Id"}},{"name":"component_id","in":"path","required":true,"schema":{"type":"string","title":"Component Id"}},{"name":"claim_id","in":"path","required":true,"schema":{"type":"string","title":"Claim Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ElementClaimApplyRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ElementClaimApplyResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/products/{product_id}/components/{component_id}/element-claims/{claim_id}/release":{"post":{"tags":["element-claims"],"summary":"Release Element Claim Route","operationId":"release_element_claim_route_api_v1_products__product_id__components__component_id__element_claims__claim_id__release_post","parameters":[{"name":"product_id","in":"path","required":true,"schema":{"type":"string","title":"Product Id"}},{"name":"component_id","in":"path","required":true,"schema":{"type":"string","title":"Component Id"}},{"name":"claim_id","in":"path","required":true,"schema":{"type":"string","title":"Claim Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ElementClaimReleaseRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ElementClaimReleaseResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/products/{product_id}/components/{component_id}/element-claims/{claim_id}/revoke":{"post":{"tags":["element-claims"],"summary":"Revoke Element Claim Route","operationId":"revoke_element_claim_route_api_v1_products__product_id__components__component_id__element_claims__claim_id__revoke_post","parameters":[{"name":"product_id","in":"path","required":true,"schema":{"type":"string","title":"Product Id"}},{"name":"component_id","in":"path","required":true,"schema":{"type":"string","title":"Component Id"}},{"name":"claim_id","in":"path","required":true,"schema":{"type":"string","title":"Claim Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ElementClaimRevokeRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ElementClaimRevokeResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/products/{product_id}/initialize":{"post":{"tags":["products","initialize"],"summary":"Initialize Product Route","operationId":"initialize_product_route_api_v1_products__product_id__initialize_post","parameters":[{"name":"product_id","in":"path","required":true,"schema":{"type":"string","title":"Product Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InitializeRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InitializeResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/products/{product_id}/transition":{"post":{"tags":["products","initialize"],"summary":"Transition Product Route","description":"SOCM Phase C.0 — Lifecycle transition (Codex IACP afee7f13).\n\nAllowed transitions:\n- `component_editing → merge_review` (enter_merge_review,\n  event `merge_review_entered`, atomically revokes all held\n  reservations + emits one `reservation_revoked` per row with\n  reason=`merge_review_entered`)\n- `merge_review → component_editing` (owner_withdraw, event\n  `merge_review_resolved`, does NOT resurrect any reservations\n  revoked on entry)","operationId":"transition_product_route_api_v1_products__product_id__transition_post","parameters":[{"name":"product_id","in":"path","required":true,"schema":{"type":"string","title":"Product Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LifecycleTransitionRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LifecycleTransitionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/products/{product_id}/rollback":{"post":{"tags":["products","initialize"],"summary":"Rollback Product Route","description":"SOCM Phase C.1b — Shape-preserving rollback.\n\nRestores Components/Envelope/Manifest/Extras from the target\nrevision's immutable snapshot, mints a new Product-Revision\n(current + 1), and enqueues a render-job. Strict invariants:\n- Snapshot must exist (no bootstrap for pre-C.1 revisions).\n- Component-IDs and Extra-Indices must match between snapshot\n  and HEAD (shape-preserving only).\n- Live component_revisions are monotone: each restored\n  component gets current_revision + 1, never rewinds to the\n  historical snapshot revision.\n- rendered_revision = NULL after rollback; render-worker picks\n  up the new pending job.","operationId":"rollback_product_route_api_v1_products__product_id__rollback_post","parameters":[{"name":"product_id","in":"path","required":true,"schema":{"type":"string","title":"Product Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RollbackRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RollbackResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/products/{product_id}/verifications":{"post":{"tags":["products","initialize"],"summary":"Publish Verification Route","description":"SOCM Phase C.2 — publish a reality verification.\n\nState is classified at publish-time (stale-at-publish if the\nuser's claimed revisions/doc-version don't match the server-\nobserved values). Auto-stale triggers on subsequent component\napply / product rollback. See content/services/product_\nverification.py for the full contract.","operationId":"publish_verification_route_api_v1_products__product_id__verifications_post","parameters":[{"name":"product_id","in":"path","required":true,"schema":{"type":"string","title":"Product Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishVerificationRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishVerificationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["products","initialize"],"summary":"List Verifications Route","description":"SOCM Phase C.2 — list verifications with stable cursor\npagination ordered by (verified_at DESC, id DESC). Bounded\nlimit ∈ [1, 100], default 50. Opaque 404 for cross-tenant.","operationId":"list_verifications_route_api_v1_products__product_id__verifications_get","parameters":[{"name":"product_id","in":"path","required":true,"schema":{"type":"string","title":"Product Id"}},{"name":"scope","in":"query","required":false,"schema":{"anyOf":[{"enum":["global","component"],"type":"string"},{"type":"null"}],"title":"Scope"}},{"name":"component_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Component Id"}},{"name":"state","in":"query","required":false,"schema":{"anyOf":[{"enum":["current","stale"],"type":"string"},{"type":"null"}],"title":"State"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Limit"}},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cursor"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/products/{product_id}/approve":{"post":{"tags":["products","initialize"],"summary":"Approve Product Route","description":"SOCM Phase C.3-5 approve route. Winner sends merge_completion\npriority notification; replay does not.","operationId":"approve_product_route_api_v1_products__product_id__approve_post","parameters":[{"name":"product_id","in":"path","required":true,"schema":{"type":"string","title":"Product Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApproveProductRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApproveProductResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/products/{product_id}/reject":{"post":{"tags":["products","initialize"],"summary":"Reject Review Route","description":"SOCM Phase C.3-5 reject route. Winner sends approval_rejected\npriority notification; replay does not.","operationId":"reject_review_route_api_v1_products__product_id__reject_post","parameters":[{"name":"product_id","in":"path","required":true,"schema":{"type":"string","title":"Product Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RejectReviewRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RejectReviewResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/products/{product_id}/reopen":{"post":{"tags":["products","initialize"],"summary":"Reopen Product Route","description":"SOCM Phase C.3-5 reopen route. NO priority notification (Gate\n7) — marker is absent on both winner AND replay; route never\ncalls notify_chunk_committed for reopen.","operationId":"reopen_product_route_api_v1_products__product_id__reopen_post","parameters":[{"name":"product_id","in":"path","required":true,"schema":{"type":"string","title":"Product Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReopenProductRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReopenProductResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/products/{product_id}/collaboration-status":{"get":{"tags":["products"],"summary":"Product Collaboration Status Route","operationId":"product_collaboration_status_route_api_v1_products__product_id__collaboration_status_get","parameters":[{"name":"product_id","in":"path","required":true,"schema":{"type":"string","title":"Product Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductCollaborationStatusResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/products/{product_id}/render.svg":{"get":{"tags":["products"],"summary":"Product Render Svg Route","description":"Public render — browser `<img src=\"…/render.svg\">` cannot attach\na JWT bearer header, so requiring auth would break the entire point\nof the endpoint (display the composite as an image in posts). UUIDs\nare opaque (122-bit), and the rendered composite is a strictly\nlighter exposure than the auth-gated collaboration-status JSON.","operationId":"product_render_svg_route_api_v1_products__product_id__render_svg_get","parameters":[{"name":"product_id","in":"path","required":true,"schema":{"type":"string","title":"Product Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/products/{product_id}/suggestions/{section_id}/accept":{"post":{"tags":["products"],"summary":"Accept Suggestion Route","description":"Owner-side accept of a proposed component patch.\n\nCaller must pass `post_id` as a query param so we can locate the\nsuggestion section in its CRDT doc — products don't carry a back-\npointer to the host post-id in their URL; the section lives in\nthe post, not the product.","operationId":"accept_suggestion_route_api_v1_products__product_id__suggestions__section_id__accept_post","parameters":[{"name":"product_id","in":"path","required":true,"schema":{"type":"string","title":"Product Id"}},{"name":"section_id","in":"path","required":true,"schema":{"type":"string","title":"Section Id"}},{"name":"post_id","in":"query","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuggestionAcceptResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/products/{product_id}/suggestions/{section_id}/decline":{"post":{"tags":["products"],"summary":"Decline Suggestion Route","operationId":"decline_suggestion_route_api_v1_products__product_id__suggestions__section_id__decline_post","parameters":[{"name":"product_id","in":"path","required":true,"schema":{"type":"string","title":"Product Id"}},{"name":"section_id","in":"path","required":true,"schema":{"type":"string","title":"Section Id"}},{"name":"post_id","in":"query","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuggestionDeclineRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuggestionDeclineResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/products/collaboration-status":{"get":{"tags":["products"],"summary":"Post Product Collaboration Statuses Route","operationId":"post_product_collaboration_statuses_route_api_v1_posts__post_id__products_collaboration_status_get","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostProductCollaborationStatusesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/events":{"get":{"tags":["sse"],"summary":"Stream Post Events","description":"Open a server-sent-events stream of every `chunk_committed`\nevent for `post_id`.\n\nStream protocol:\n  ``:`` comment frames as initial-connect-ack + 15s keepalive.\n  Each real event is `event: chunk_committed\\n data: <json>\\n\\n`\n  with the same payload shape that goes out via IACP push (so\n  clients can share parser between SSE + IACP-debug paths).\n\nAuth + access:\n  - Identity from Bearer JWT (require_read).\n  - Post must exist + identity must have read access (tenant gate,\n    share-grant, or notify_authors auto-grant).\n  - Disconnect = unsubscribe (cleanup on cancel).","operationId":"stream_post_events_api_v1_posts__post_id__events_get","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/posts/{post_id}/refine_phrase":{"post":{"tags":["refine_phrase"],"summary":"Refine Phrase","description":"V2.3.1 word-level refinement via stable find/replace.\n\nImplementiert Codex' Spec aus Post #1202 — siehe Modul-Docstring\nfür vollständige Fail-closed-Regeln.","operationId":"refine_phrase_api_v1_posts__post_id__refine_phrase_post","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefinePhraseRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/narrations":{"get":{"tags":["narrations"],"summary":"Resolve Narration","description":"Resolve (identifier, persona, lang) → post_id.\n\nResponse shape (slim, include_content=false):\n    {\n      \"post_id\": 1271,\n      \"language\": \"sl\",\n      \"persona_id\": \"dr_tschauko\",\n      \"track_id\": \"30\",\n      \"knowledge_id\": null,\n      \"fallback_applied\": false,\n      \"requested\": {\"persona\": \"dr_tschauko\", \"lang\": \"sl\"}\n    }\n\nWith include_content=true, adds \"title\", \"content\", \"content_type\",\n\"doc_type\" of the resolved post.\n\nWith fallback=true (default) the resolver tries, in order:\n    1. (persona, lang)          — exact\n    2. (persona, de)            — language fallback\n    3. (dr_tschauko, lang)      — persona fallback\n    4. (dr_tschauko, de)        — full default\nand reports which substitution happened via fallback_applied +\nresolved persona_id/language differing from `requested`.\n\nReturns 404 with structured detail when no match exists even after\nfallback (or immediately with fallback=false).\n\nNo auth required — public read-path for consumer routing.","operationId":"resolve_narration_api_v1_narrations_get","parameters":[{"name":"track_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The audio_guide track identifier (from metadata_json.track_id). Mutually exclusive with knowledge_id.","title":"Track Id"},"description":"The audio_guide track identifier (from metadata_json.track_id). Mutually exclusive with knowledge_id."},{"name":"knowledge_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The Knowledge-Item identifier. Matches metadata_json.knowledge_id first, falls back to metadata_json.source_storage_id (legacy linkage of the pre-backfill annotation posts). Mutually exclusive with track_id.","title":"Knowledge Id"},"description":"The Knowledge-Item identifier. Matches metadata_json.knowledge_id first, falls back to metadata_json.source_storage_id (legacy linkage of the pre-backfill annotation posts). Mutually exclusive with track_id."},{"name":"lang","in":"query","required":false,"schema":{"type":"string","description":"Target language code (e.g. 'de', 'sl', 'en'). Defaults to 'de' when omitted.","default":"de","title":"Lang"},"description":"Target language code (e.g. 'de', 'sl', 'en'). Defaults to 'de' when omitted."},{"name":"persona","in":"query","required":false,"schema":{"type":"string","description":"Persona-ID (e.g. 'dr_tschauko', 'tschauko', 'tschauka'). Defaults to 'dr_tschauko' when omitted.","default":"dr_tschauko","title":"Persona"},"description":"Persona-ID (e.g. 'dr_tschauko', 'tschauko', 'tschauka'). Defaults to 'dr_tschauko' when omitted."},{"name":"fallback","in":"query","required":false,"schema":{"type":"boolean","description":"Central fallback semantics: when the exact (persona, lang) cell has no post, fall back lang→de, then persona→dr_tschauko, then both, instead of 404. The response carries fallback_applied + the actually-resolved persona/lang. Pass false for strict-404 behavior.","default":true,"title":"Fallback"},"description":"Central fallback semantics: when the exact (persona, lang) cell has no post, fall back lang→de, then persona→dr_tschauko, then both, instead of 404. The response carries fallback_applied + the actually-resolved persona/lang. Pass false for strict-404 behavior."},{"name":"include_content","in":"query","required":false,"schema":{"type":"boolean","description":"Include the resolved post's full content + title in the response (one-call hot-path for consumers like knowledge-api). Default false keeps the response a slim routing record.","default":false,"title":"Include Content"},"description":"Include the resolved post's full content + title in the response (one-call hot-path for consumers like knowledge-api). Default false keeps the response a slim routing record."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tracks/{track_id}/personas":{"get":{"tags":["tracks"],"summary":"List Track Personas","description":"List all personas available for a track, joined with Persona-Post details.\n\nResponse shape:\n    {\n      \"track_id\": \"30\",\n      \"personas\": [\n        {\n          \"persona_id\": \"dr_tschauko\",\n          \"name\": \"Dr. Peter Tschauko\",\n          \"persona_post_id\": 1270,\n          \"voice_id\": \"llAvE3WPPWbZOjaYywej\",\n          \"voice_source\": \"elevenlabs\",\n          \"voice_model\": \"eleven_multilingual_v2\",\n          \"avatar_color\": \"#7CB342\",\n          \"available_languages\": [\"de\", \"en\", \"sl\", \"it\", \"nl\", \"fr\"],\n          \"post_ids\": {\n            \"de\": 447, \"en\": 1277, \"sl\": 1271,\n            \"it\": 1272, \"nl\": 1273, \"fr\": 1274\n          },\n          \"default_language\": \"de\"\n        }\n      ]\n    }\n\n404 when no track_id posts exist. Empty `personas: []` when posts exist\nbut no persona_id can be resolved (should not happen with the backfill).","operationId":"list_track_personas_api_v1_tracks__track_id__personas_get","parameters":[{"name":"track_id","in":"path","required":true,"schema":{"type":"string","description":"The audio_guide track identifier.","title":"Track Id"},"description":"The audio_guide track identifier."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/translate":{"post":{"tags":["translate"],"summary":"Translate String","description":"Translate a single string.\n\nFast-path via Google Translate. Falls back to Gemini on error. Same\nfallback chain that TranslationService uses internally for title\ntranslation, exposed here as a stable HTTP surface for federation\nconsumers.\n\nIdempotent within backend limits — Google Translate is not strictly\ndeterministic, but typically stable across calls for short strings.","operationId":"translate_string_api_v1_translate_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/content__routes__translate__TranslateRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/content__routes__translate__TranslateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/":{"get":{"summary":"Root","description":"Serve debug UI.","operationId":"root__get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/health":{"get":{"summary":"Health","description":"Health check endpoint.","operationId":"health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1":{"get":{"summary":"Api Info","description":"API information.","operationId":"api_info_api_v1_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}}},"components":{"schemas":{"AnnotationAnchor":{"properties":{"x":{"type":"number","title":"X"},"y":{"type":"number","title":"Y"}},"type":"object","required":["x","y"],"title":"AnnotationAnchor"},"AnnotationCreate":{"properties":{"start_pos":{"type":"integer","minimum":0.0,"title":"Start Pos"},"end_pos":{"type":"integer","minimum":0.0,"title":"End Pos"},"note_text":{"type":"string","minLength":1,"title":"Note Text"},"author_id":{"type":"string","maxLength":100,"minLength":1,"title":"Author Id"},"author_name":{"type":"string","maxLength":200,"minLength":1,"title":"Author Name"},"parent_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Parent Id","description":"Parent annotation ID for replies"}},"type":"object","required":["start_pos","end_pos","note_text","author_id","author_name"],"title":"AnnotationCreate","description":"Schema for creating an annotation."},"AnnotationKnowledgeListItem":{"properties":{"id":{"type":"integer","title":"Id"},"annotation_group":{"type":"string","title":"Annotation Group"},"source_storage_id":{"type":"integer","title":"Source Storage Id"},"detail_level":{"type":"string","title":"Detail Level"},"language":{"type":"string","title":"Language"},"title":{"type":"string","title":"Title"},"annotation_count":{"type":"integer","title":"Annotation Count"},"available_languages":{"items":{"type":"string"},"type":"array","title":"Available Languages","default":[]},"created_at":{"type":"string","title":"Created At"},"updated_at":{"type":"string","title":"Updated At"}},"type":"object","required":["id","annotation_group","source_storage_id","detail_level","language","title","annotation_count","created_at","updated_at"],"title":"AnnotationKnowledgeListItem","description":"List item without full content."},"AnnotationKnowledgeListResponse":{"properties":{"stories":{"items":{"$ref":"#/components/schemas/AnnotationKnowledgeListItem"},"type":"array","title":"Stories"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["stories","total"],"title":"AnnotationKnowledgeListResponse"},"AnnotationKnowledgeResponse":{"properties":{"id":{"type":"integer","title":"Id"},"annotation_group":{"type":"string","title":"Annotation Group"},"source_storage_id":{"type":"integer","title":"Source Storage Id"},"detail_level":{"type":"string","title":"Detail Level"},"language":{"type":"string","title":"Language"},"title":{"type":"string","title":"Title"},"object_description":{"type":"string","title":"Object Description"},"facts":{"items":{"$ref":"#/components/schemas/FactItem"},"type":"array","title":"Facts"},"annotations":{"items":{"$ref":"#/components/schemas/AnnotationPoint"},"type":"array","title":"Annotations"},"object_audio":{"anyOf":[{"$ref":"#/components/schemas/AudioRef"},{"type":"null"}]},"combined_audio":{"anyOf":[{"$ref":"#/components/schemas/AudioRef"},{"type":"null"}]},"model_used":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model Used"},"available_languages":{"items":{"type":"string"},"type":"array","title":"Available Languages","default":[]},"created_at":{"type":"string","title":"Created At"},"updated_at":{"type":"string","title":"Updated At"},"binom":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Binom"},"common_name_de":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Common Name De"},"short":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Short"},"wiki":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Wiki"},"image_search_hint":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Search Hint"},"media":{"items":{"$ref":"#/components/schemas/MediaRef"},"type":"array","title":"Media","default":[]},"locations":{"items":{"$ref":"#/components/schemas/LocationRef"},"type":"array","title":"Locations","default":[]},"cover_storage_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Cover Storage Id"}},"type":"object","required":["id","annotation_group","source_storage_id","detail_level","language","title","object_description","facts","annotations","created_at","updated_at"],"title":"AnnotationKnowledgeResponse","description":"Full annotation knowledge response."},"AnnotationPoint":{"properties":{"id":{"type":"string","title":"Id"},"anchor":{"$ref":"#/components/schemas/AnnotationAnchor"},"label":{"type":"string","title":"Label"},"description":{"type":"string","title":"Description"},"audio":{"anyOf":[{"$ref":"#/components/schemas/AudioRef"},{"type":"null"}]},"position3D":{"anyOf":[{"$ref":"#/components/schemas/Position3D"},{"type":"null"}]}},"type":"object","required":["id","anchor","label","description"],"title":"AnnotationPoint"},"AnnotationResponse":{"properties":{"id":{"type":"integer","title":"Id"},"parent_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Parent Id"},"start_pos":{"type":"integer","title":"Start Pos"},"end_pos":{"type":"integer","title":"End Pos"},"note_text":{"type":"string","title":"Note Text"},"author_id":{"type":"string","title":"Author Id"},"author_name":{"type":"string","title":"Author Name"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"replies":{"items":{"$ref":"#/components/schemas/AnnotationResponse"},"type":"array","title":"Replies","default":[]}},"type":"object","required":["id","start_pos","end_pos","note_text","author_id","author_name","created_at","updated_at"],"title":"AnnotationResponse","description":"Response schema for an annotation."},"AnnotationUpdate":{"properties":{"start_pos":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Start Pos"},"end_pos":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"End Pos"},"note_text":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"title":"Note Text"}},"type":"object","title":"AnnotationUpdate","description":"Schema for updating an annotation."},"ApplyRequest":{"properties":{"token":{"type":"string","minLength":1,"title":"Token"},"new_content_svg":{"type":"string","maxLength":2000000,"minLength":1,"title":"New Content Svg"},"expected_revision":{"type":"integer","minimum":0.0,"title":"Expected Revision"},"idempotency_key":{"type":"string","maxLength":120,"minLength":1,"title":"Idempotency Key"}},"additionalProperties":false,"type":"object","required":["token","new_content_svg","expected_revision","idempotency_key"],"title":"ApplyRequest","description":"SOCM Phase B.4b.2 — Component Apply request body.\n\nCodex Gate A: extra='forbid' so an attacker can't inject a\nholder_id or other fields. Plaintext token is the credential —\nNEVER persisted into idempotency_records.content_hash or audit\npayload (see content/services/component_apply.py)."},"ApplyResponse":{"properties":{"product_id":{"type":"string","title":"Product Id"},"component_id":{"type":"string","title":"Component Id"},"component_revision":{"type":"integer","title":"Component Revision"},"product_revision":{"type":"integer","title":"Product Revision"},"content_hash":{"type":"string","title":"Content Hash"},"reservation_state":{"type":"string","title":"Reservation State"},"render_state":{"type":"string","title":"Render State"},"idempotent_replay":{"type":"boolean","title":"Idempotent Replay"}},"type":"object","required":["product_id","component_id","component_revision","product_revision","content_hash","reservation_state","render_state","idempotent_replay"],"title":"ApplyResponse"},"ApproveProductRequest":{"properties":{"revision_to_approve":{"type":"integer","minimum":1.0,"title":"Revision To Approve"},"reason":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Reason"},"idempotency_key":{"type":"string","maxLength":120,"minLength":1,"title":"Idempotency Key"}},"additionalProperties":false,"type":"object","required":["revision_to_approve","idempotency_key"],"title":"ApproveProductRequest"},"ApproveProductResponse":{"properties":{"product_id":{"type":"string","title":"Product Id"},"decision_revision":{"type":"integer","title":"Decision Revision"},"prior_state":{"type":"string","title":"Prior State"},"new_state":{"type":"string","title":"New State"},"decision_at":{"type":"string","title":"Decision At"},"idempotent_replay":{"type":"boolean","title":"Idempotent Replay"},"approved_revision":{"type":"integer","title":"Approved Revision"}},"type":"object","required":["product_id","decision_revision","prior_state","new_state","decision_at","idempotent_replay","approved_revision"],"title":"ApproveProductResponse"},"AudioRef":{"properties":{"id":{"type":"integer","title":"Id"},"url":{"type":"string","title":"Url"},"duration_seconds":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Duration Seconds"},"voice":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Voice"},"character":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Character"},"provider":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider"}},"type":"object","required":["id","url"],"title":"AudioRef"},"BlockCreate":{"properties":{"block_type":{"type":"string","pattern":"^(text|quote|code|callout|embed|code_section|reservation)$","title":"Block Type"},"content":{"type":"string","minLength":1,"title":"Content"},"position":{"type":"integer","title":"Position","default":0},"metadata_json":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Metadata Json"},"author_id":{"type":"string","maxLength":100,"minLength":1,"title":"Author Id"},"author_name":{"type":"string","maxLength":200,"minLength":1,"title":"Author Name"}},"type":"object","required":["block_type","content","author_id","author_name"],"title":"BlockCreate","description":"Schema for creating a block."},"BlockEdgeCreate":{"properties":{"from_block_id":{"type":"string","maxLength":36,"minLength":1,"title":"From Block Id"},"to_block_id":{"type":"string","maxLength":36,"minLength":1,"title":"To Block Id"},"edge_type":{"type":"string","enum":["replies_to","contradicts","extends","references","synthesizes"],"title":"Edge Type"},"label":{"anyOf":[{"type":"string","maxLength":1000},{"type":"null"}],"title":"Label"},"confidence":{"anyOf":[{"type":"number","maximum":1.0,"minimum":0.0},{"type":"null"}],"title":"Confidence"}},"type":"object","required":["from_block_id","to_block_id","edge_type"],"title":"BlockEdgeCreate","description":"Body for `POST /posts/{id}/edges`.\n\n`confidence` is optional and follows the spec semantics:\n- None → manually created (UI button, agent decision)\n- 0.0-1.0 → auto-detected with that confidence score\n\nAuto-detection pipeline (V2.9+) will fill confidence; manual edges\nleave it null. Above-threshold auto edges are created with confidence\nset; below-threshold suggestions DON'T persist as edges (they live in\na separate suggestion buffer outside the relational layer)."},"BlockEdgeResponse":{"properties":{"id":{"type":"string","title":"Id"},"post_id":{"type":"integer","title":"Post Id"},"from_block_id":{"type":"string","title":"From Block Id"},"to_block_id":{"type":"string","title":"To Block Id"},"edge_type":{"type":"string","enum":["replies_to","contradicts","extends","references","synthesizes"],"title":"Edge Type"},"author_id":{"type":"string","title":"Author Id"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"confidence":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Confidence"},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label"}},"type":"object","required":["id","post_id","from_block_id","to_block_id","edge_type","author_id","created_at"],"title":"BlockEdgeResponse","description":"Response for any edge endpoint."},"BlockEdgeUpdate":{"properties":{"edge_type":{"anyOf":[{"type":"string","enum":["replies_to","contradicts","extends","references","synthesizes"]},{"type":"null"}],"title":"Edge Type"},"label":{"anyOf":[{"type":"string","maxLength":1000},{"type":"null"}],"title":"Label"},"confidence":{"anyOf":[{"type":"number","maximum":1.0,"minimum":0.0},{"type":"null"}],"title":"Confidence"}},"type":"object","title":"BlockEdgeUpdate","description":"Body for `PATCH /posts/{id}/edges/{edge_id}`.\n\nOnly the mutable fields are exposed. from/to/post are immutable —\ndelete + recreate if a wrong pairing was committed (preserves the\naudit trail of who created the original)."},"BlockReorder":{"properties":{"order":{"items":{"type":"integer"},"type":"array","title":"Order","description":"List of block IDs in desired order"}},"type":"object","required":["order"],"title":"BlockReorder","description":"Schema for reordering blocks."},"BlockResponse":{"properties":{"id":{"type":"integer","title":"Id"},"block_type":{"type":"string","title":"Block Type"},"content":{"type":"string","title":"Content"},"position":{"type":"integer","title":"Position"},"author_id":{"type":"string","title":"Author Id"},"author_name":{"type":"string","title":"Author Name"},"metadata_json":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Metadata Json"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"version":{"type":"integer","title":"Version","default":1}},"type":"object","required":["id","block_type","content","position","author_id","author_name","metadata_json","created_at"],"title":"BlockResponse","description":"Response schema for a block."},"BlockUpdate":{"properties":{"block_type":{"anyOf":[{"type":"string","pattern":"^(text|quote|code|callout|embed|code_section|reservation)$"},{"type":"null"}],"title":"Block Type"},"content":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"title":"Content"},"position":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Position"},"metadata_json":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Metadata Json"},"expected_version":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Expected Version"}},"type":"object","title":"BlockUpdate","description":"Schema for updating a block."},"CRDTApplyRequest":{"properties":{"text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Text"},"update_b64":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Update B64"},"mode":{"type":"string","title":"Mode","default":"replace"},"paragraph_index":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Paragraph Index"},"find":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Find"},"attrs":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Attrs"},"block_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Block Type"},"canvas_meta":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Canvas Meta"},"expected_version":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Expected Version"},"expected_author":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expected Author"},"parent_section_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Section Id"},"parent_section_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Section Type"},"override_section_targets":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Override Section Targets"},"block_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Block Id"},"start_char_offset":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Start Char Offset"},"end_char_offset":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"End Char Offset"},"expected_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expected Text"},"suppress_push":{"type":"boolean","title":"Suppress Push","default":false}},"type":"object","title":"CRDTApplyRequest","description":"Body for `POST /posts/{id}/crdt/apply`.\n\n    Exactly one of `text` or `update_b64` must be set.\n\n    `mode` (text-writes only — `update_b64` writes apply verbatim):\n\n    Whole-doc modes (don't need a target index):\n      - `replace`: delete current content, insert new. Safe when you are\n        the only writer or have a fresh read of the state.\n      - `append`: insert `text` at the END of the current document.\n      - `prepend`: insert `text` at the BEGINNING of the document.\n\n    Targeted modes (V2.6 — agents can edit specific paragraphs):\n      - `insert_after_paragraph` + `paragraph_index`: insert a new\n        paragraph immediately AFTER the given 0-based index. Use -1 to\n        insert at the very beginning (= same as prepend). To find the\n        right index, fetch /crdt/structured first.\n      - `replace_paragraph` + `paragraph_index`: replace the paragraph\n        at the given index with `text` (split on `\n\n` for multi-para\n        replacement). Author-attrs are re-stamped to the caller.\n      - `find_replace` + `find`: find first occurrence of `find` in\n        the materialized text and replace it with `text`. Safe for\n        small spelling/clarification edits. Returns 404 if not found.\n      - `update_paragraph_attrs` + `paragraph_index` + `attrs`: change\n        paragraph-level attributes (e.g. force a re-attribution) without\n        touching text. `text` is ignored.\n    "},"ClaimBody":{"properties":{"region_type":{"type":"string","title":"Region Type","description":"post | section | block","default":"section"},"region_ref":{"type":"string","title":"Region Ref","description":"section_id (q-…/p-…/t-…/a-…) bei region_type=section, block_id (UUID aus doc_get_structured) bei block, leer bei post.","default":""},"intent":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Intent","description":"Kurztext, was du vorhast (für die Präsenz-Anzeige)."},"ttl":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Ttl","description":"Lease-Sekunden, default 300, Kappe 1800."}},"type":"object","title":"ClaimBody"},"ClaimRequest":{"properties":{"collaboration_key":{"type":"string","maxLength":120,"minLength":1,"title":"Collaboration Key","description":"Stable key identifying the shared work. Parallel claims with the same key collapse onto one product."},"object_type":{"type":"string","enum":["svg","json","markdown","text"],"title":"Object Type","description":"One of: svg | json | markdown | text"},"owner":{"type":"string","maxLength":120,"minLength":1,"title":"Owner","description":"Agent/user name that drives the work"},"reviewers":{"items":{"type":"string"},"type":"array","title":"Reviewers","description":"Reviewer names (stored as JSON array)"},"idempotency_key":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}],"title":"Idempotency Key","description":"Optional client-supplied key. Reuse with same content → cached response; reuse with different content → 409."},"initial_svg":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Initial Svg","description":"Optional initial SVG body. When provided with object_type='svg', the route runs claim + initialize_product atomically. Other object_types ignore this field."}},"type":"object","required":["collaboration_key","object_type","owner"],"title":"ClaimRequest"},"ClaimResponse":{"properties":{"product_id":{"type":"string","title":"Product Id"},"post_id":{"type":"integer","title":"Post Id"},"collaboration_key":{"type":"string","title":"Collaboration Key"},"object_type":{"type":"string","title":"Object Type"},"state":{"type":"string","title":"State"},"current_revision":{"type":"integer","title":"Current Revision"},"owner":{"type":"string","title":"Owner"},"reviewers":{"items":{"type":"string"},"type":"array","title":"Reviewers"},"created":{"type":"boolean","title":"Created"},"canonical":{"type":"boolean","title":"Canonical"}},"type":"object","required":["product_id","post_id","collaboration_key","object_type","state","current_revision","owner","reviewers","created","canonical"],"title":"ClaimResponse"},"CollectionCreate":{"properties":{"name":{"type":"string","maxLength":200,"minLength":1,"title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"color":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Color"},"icon":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Icon"},"position":{"type":"integer","minimum":0.0,"title":"Position","default":0},"parent_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Parent Id"}},"type":"object","required":["name"],"title":"CollectionCreate","description":"Schema for creating a collection."},"CollectionDetailResponse":{"properties":{"id":{"type":"integer","title":"Id"},"parent_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Parent Id"},"name":{"type":"string","title":"Name"},"slug":{"type":"string","title":"Slug"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"color":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Color"},"icon":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Icon"},"position":{"type":"integer","title":"Position"},"posts":{"items":{"$ref":"#/components/schemas/PostResponse"},"type":"array","title":"Posts","default":[]},"children":{"items":{"$ref":"#/components/schemas/CollectionResponse"},"type":"array","title":"Children","default":[]},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","name","slug","position","created_at","updated_at"],"title":"CollectionDetailResponse","description":"Response schema for a collection with its posts and children."},"CollectionResponse":{"properties":{"id":{"type":"integer","title":"Id"},"parent_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Parent Id"},"name":{"type":"string","title":"Name"},"slug":{"type":"string","title":"Slug"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"color":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Color"},"icon":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Icon"},"position":{"type":"integer","title":"Position"},"post_count":{"type":"integer","title":"Post Count","default":0},"children_count":{"type":"integer","title":"Children Count","default":0},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","name","slug","position","created_at","updated_at"],"title":"CollectionResponse","description":"Response schema for a collection (list view)."},"CollectionUpdate":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":200,"minLength":1},{"type":"null"}],"title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"color":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Color"},"icon":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Icon"},"position":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Position"},"parent_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Parent Id"}},"type":"object","title":"CollectionUpdate","description":"Schema for updating a collection."},"ComponentDetailResponse":{"properties":{"product_id":{"type":"string","title":"Product Id"},"component_id":{"type":"string","title":"Component Id"},"current_revision":{"type":"integer","title":"Current Revision"},"content_hash":{"type":"string","title":"Content Hash"},"content_type":{"type":"string","title":"Content Type"},"updated_by":{"type":"string","title":"Updated By"},"updated_at":{"type":"string","title":"Updated At"},"content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content"}},"additionalProperties":false,"type":"object","required":["product_id","component_id","current_revision","content_hash","content_type","updated_by","updated_at"],"title":"ComponentDetailResponse","description":"SOCM Phase 4.4.3 — read-only Component-Detail view.\n\nExposes static + lifecycle state of a single ProductComponent:\nrevision counter, content_hash for client-side staleness check,\ncontent_type for resolver-dispatch awareness, audit fields.\n\nContent body itself is only returned when ?include_content=true to\nkeep the default response shape predictable and small. Large\nartifact bodies (python_ast modules, generic_text files) can run\ninto MBs and shouldn't pay transit cost on every poll."},"ComponentStatusResponse":{"properties":{"component_id":{"type":"string","title":"Component Id"},"current_revision":{"type":"integer","title":"Current Revision"},"content_hash":{"type":"string","title":"Content Hash"},"updated_by":{"type":"string","title":"Updated By"},"updated_at":{"type":"string","title":"Updated At"},"reservation":{"anyOf":[{"$ref":"#/components/schemas/ReservationStatusResponse"},{"type":"null"}]}},"type":"object","required":["component_id","current_revision","content_hash","updated_by","updated_at","reservation"],"title":"ComponentStatusResponse"},"ContentPatchOperation":{"properties":{"op":{"type":"string","pattern":"^(replace|insert|delete)$","title":"Op","description":"Operation: replace, insert, delete"},"start_line":{"type":"integer","minimum":1.0,"title":"Start Line","description":"Start line (1-based)"},"end_line":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"End Line","description":"End line (1-based, inclusive). Required for replace/delete"},"text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Text","description":"New text (for replace/insert)"},"find":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Find","description":"Find and replace within the line range"},"replace_with":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Replace With","description":"Replacement text for find (alias: 'replace')"}},"type":"object","required":["op","start_line"],"title":"ContentPatchOperation","description":"A single content patch operation.\n\nIssue #435 (2026-07-28, Datenverlust): Das Ersetzungs-Feld heisst\n`replace_with`. Wer stattdessen das naheliegende `replace` schickte,\nverlor es an Pydantics extra-ignore — dann war `replace_with=None`,\nder find/replace-Zweig fiel durch, und `op=replace` griff mit\n`text=None` auf `\"\".split()` zurueck: die adressierte Zeile wurde\ndurch eine LEERZEILE ersetzt, mit HTTP 200 und Erfolgs-Response.\nZwei Gegenmassnahmen: (1) `replace` ist jetzt ein akzeptierter Alias,\n(2) ein Validator verweigert Operationen, die sonst still Inhalt\nloeschen wuerden."},"ContentPatchRequest":{"properties":{"operations":{"items":{"$ref":"#/components/schemas/ContentPatchOperation"},"type":"array","title":"Operations","description":"List of patch operations"},"author_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Author Id"},"author_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Author Name"},"expected_version":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Expected Version"}},"type":"object","required":["operations"],"title":"ContentPatchRequest","description":"Patch content with line-level operations."},"CreateAnnotationKnowledgeRequest":{"properties":{"title":{"type":"string","title":"Title"},"source_storage_id":{"type":"integer","title":"Source Storage Id"},"detail_level":{"type":"string","title":"Detail Level","default":"standard"},"language":{"type":"string","title":"Language","default":"de"},"object_description":{"type":"string","title":"Object Description","default":""},"facts":{"items":{"$ref":"#/components/schemas/FactItem"},"type":"array","title":"Facts","default":[]},"annotations":{"items":{"$ref":"#/components/schemas/AnnotationPoint"},"type":"array","title":"Annotations","default":[]},"model_used":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model Used"},"author_id":{"type":"string","title":"Author Id","default":"system"},"author_name":{"type":"string","title":"Author Name","default":"Knowledge API"}},"type":"object","required":["title","source_storage_id"],"title":"CreateAnnotationKnowledgeRequest","description":"Create a new annotation knowledge entry."},"ElementClaimApplyRequest":{"properties":{"token":{"type":"string","minLength":1,"title":"Token"},"patches":{"items":{"$ref":"#/components/schemas/ElementPatch"},"type":"array","maxItems":64,"minItems":1,"title":"Patches"},"idempotency_key":{"type":"string","maxLength":120,"minLength":1,"title":"Idempotency Key"}},"additionalProperties":false,"type":"object","required":["token","patches","idempotency_key"],"title":"ElementClaimApplyRequest"},"ElementClaimApplyResponse":{"properties":{"claim_id":{"type":"string","title":"Claim Id"},"product_id":{"type":"string","title":"Product Id"},"component_id":{"type":"string","title":"Component Id"},"component_revision":{"type":"integer","title":"Component Revision"},"product_revision":{"type":"integer","title":"Product Revision"},"content_hash":{"type":"string","title":"Content Hash"},"claim_state":{"type":"string","title":"Claim State"},"applied_patches":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Applied Patches"},"idempotent_replay":{"type":"boolean","title":"Idempotent Replay","default":false}},"type":"object","required":["claim_id","product_id","component_id","component_revision","product_revision","content_hash","claim_state","applied_patches"],"title":"ElementClaimApplyResponse"},"ElementClaimReleaseRequest":{"properties":{"token":{"type":"string","minLength":1,"title":"Token"}},"additionalProperties":false,"type":"object","required":["token"],"title":"ElementClaimReleaseRequest"},"ElementClaimReleaseResponse":{"properties":{"claim_id":{"type":"string","title":"Claim Id"},"state":{"type":"string","title":"State"},"idempotent":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Idempotent"}},"type":"object","required":["claim_id","state"],"title":"ElementClaimReleaseResponse"},"ElementClaimReserveRequest":{"properties":{"element_ids":{"items":{"type":"string"},"type":"array","maxItems":64,"minItems":1,"title":"Element Ids"},"base_revision":{"type":"integer","minimum":0.0,"title":"Base Revision"},"intent":{"type":"string","enum":["edit","create","delete"],"title":"Intent"},"ttl_seconds":{"anyOf":[{"type":"integer","maximum":1800.0,"minimum":1.0},{"type":"null"}],"title":"Ttl Seconds"}},"additionalProperties":false,"type":"object","required":["element_ids","base_revision","intent"],"title":"ElementClaimReserveRequest"},"ElementClaimReserveResponse":{"properties":{"claim_id":{"type":"string","title":"Claim Id"},"product_id":{"type":"string","title":"Product Id"},"component_id":{"type":"string","title":"Component Id"},"element_ids":{"items":{"type":"string"},"type":"array","title":"Element Ids"},"token":{"type":"string","title":"Token"},"base_revision":{"type":"integer","title":"Base Revision"},"element_status":{"additionalProperties":{"type":"string"},"type":"object","title":"Element Status"},"element_hashes":{"additionalProperties":{"anyOf":[{"type":"string"},{"type":"null"}]},"type":"object","title":"Element Hashes"},"expires_at":{"type":"string","title":"Expires At"},"anchor_kind":{"type":"string","title":"Anchor Kind","default":"element_id"},"anchor_ref":{"type":"string","title":"Anchor Ref","default":""},"base_hash":{"type":"string","title":"Base Hash","default":""},"active_peer_claims":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Active Peer Claims"},"committed_elements":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Committed Elements"},"style_manifest":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Style Manifest"},"convention_hint":{"type":"string","title":"Convention Hint"}},"type":"object","required":["claim_id","product_id","component_id","element_ids","token","base_revision","element_status","element_hashes","expires_at","convention_hint"],"title":"ElementClaimReserveResponse"},"ElementClaimRevokeRequest":{"properties":{"reason":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Reason"}},"additionalProperties":false,"type":"object","title":"ElementClaimRevokeRequest"},"ElementClaimRevokeResponse":{"properties":{"claim_id":{"type":"string","title":"Claim Id"},"state":{"type":"string","title":"State"},"idempotent":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Idempotent"}},"type":"object","required":["claim_id","state"],"title":"ElementClaimRevokeResponse"},"ElementPatch":{"properties":{"id":{"type":"string","minLength":1,"title":"Id"},"op":{"type":"string","enum":["replace","create","delete"],"title":"Op"},"svg":{"anyOf":[{"type":"string","maxLength":200000},{"type":"null"}],"title":"Svg"},"insert_after":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Insert After"}},"additionalProperties":false,"type":"object","required":["id","op"],"title":"ElementPatch"},"FactItem":{"properties":{"label":{"type":"string","title":"Label"},"value":{"type":"string","title":"Value"}},"type":"object","required":["label","value"],"title":"FactItem"},"GenerateAnnotationAudioRequest":{"properties":{"mode":{"type":"string","title":"Mode","description":"'all' = object + annotations, 'object' = only object, or annotation ID","default":"all"},"character":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Character","description":"Override character (tschauko/tschauka)"},"character2":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Character2","description":"Second character for alternating"}},"type":"object","title":"GenerateAnnotationAudioRequest"},"GenerateAnnotationAudioResult":{"properties":{"post_id":{"type":"integer","title":"Post Id"},"results":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Results"}},"type":"object","required":["post_id","results"],"title":"GenerateAnnotationAudioResult"},"GenerateAudioRequest":{"properties":{"narrator_override":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Narrator Override","description":"Override narrator character"},"voice_id_override":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Voice Id Override","description":"Override ElevenLabs voice ID"},"scenes":{"anyOf":[{"items":{"type":"integer"},"type":"array"},{"type":"null"}],"title":"Scenes","description":"Scene indices (1-based) to generate. None = all"}},"type":"object","title":"GenerateAudioRequest"},"GenerateAudioResult":{"properties":{"story_group":{"type":"string","title":"Story Group"},"results":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Results"}},"type":"object","required":["story_group","results"],"title":"GenerateAudioResult"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"HeartbeatRequest":{"properties":{"token":{"type":"string","minLength":1,"title":"Token"},"ttl_seconds":{"anyOf":[{"type":"integer","maximum":1800.0,"minimum":1.0},{"type":"null"}],"title":"Ttl Seconds"}},"additionalProperties":false,"type":"object","required":["token"],"title":"HeartbeatRequest"},"HeartbeatResponse":{"properties":{"product_id":{"type":"string","title":"Product Id"},"component_id":{"type":"string","title":"Component Id"},"holder_id":{"type":"string","title":"Holder Id"},"expires_at":{"type":"string","title":"Expires At"},"heartbeat_at":{"type":"string","title":"Heartbeat At"}},"type":"object","required":["product_id","component_id","holder_id","expires_at","heartbeat_at"],"title":"HeartbeatResponse"},"InitializeRequest":{"properties":{"svg_text":{"type":"string","maxLength":2000000,"minLength":1,"title":"Svg Text"},"idempotency_key":{"type":"string","maxLength":120,"minLength":1,"title":"Idempotency Key"}},"additionalProperties":false,"type":"object","required":["svg_text","idempotency_key"],"title":"InitializeRequest"},"InitializeResponse":{"properties":{"product_id":{"type":"string","title":"Product Id"},"current_revision":{"type":"integer","title":"Current Revision"},"state":{"type":"string","title":"State"},"rendered_revision":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Rendered Revision"},"render_status":{"type":"string","title":"Render Status"},"components_seeded":{"items":{"type":"string"},"type":"array","title":"Components Seeded"},"extras_count":{"type":"integer","title":"Extras Count"},"initialized_at":{"type":"string","title":"Initialized At"}},"type":"object","required":["product_id","current_revision","state","rendered_revision","render_status","components_seeded","extras_count","initialized_at"],"title":"InitializeResponse"},"InviteRequest":{"properties":{"agent_names":{"items":{"type":"string"},"type":"array","minItems":1,"title":"Agent Names","description":"Federation session names to invite (e.g. 'Defence', 'ArkturianGemini'). Resolved against the live-agents registry; offline names are skipped not failed so a partial batch still succeeds for the live ones."},"message":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Message","description":"Optional context snippet appended to the onboarding ping so the new agent sees a one-liner about what the discussion is about without having to read the whole post first."},"skip_liveness_check":{"type":"boolean","title":"Skip Liveness Check","description":"Bypass the cloud-api registry lookup and ping the agents anyway. Use when the registry is known to be stale OR you explicitly want to pre-subscribe an offline agent so they see the post in their inbox on next start.","default":false}},"type":"object","required":["agent_names"],"title":"InviteRequest","description":"Body for POST /posts/{post_id}/invite."},"InviteResponse":{"properties":{"post_id":{"type":"integer","title":"Post Id"},"invited":{"items":{"type":"string"},"type":"array","title":"Invited"},"offline_skipped":{"items":{"type":"string"},"type":"array","title":"Offline Skipped"},"already_subscribed":{"items":{"type":"string"},"type":"array","title":"Already Subscribed"},"notify_authors_after":{"items":{"type":"string"},"type":"array","title":"Notify Authors After"}},"type":"object","required":["post_id","invited","offline_skipped","already_subscribed","notify_authors_after"],"title":"InviteResponse"},"LanguageVariant":{"properties":{"post_id":{"type":"integer","title":"Post Id"},"language":{"type":"string","title":"Language"},"title":{"type":"string","title":"Title"},"is_current":{"type":"boolean","title":"Is Current","default":false},"auto_translated":{"type":"boolean","title":"Auto Translated","default":false},"manually_edited":{"type":"boolean","title":"Manually Edited","default":false},"updated_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["post_id","language","title"],"title":"LanguageVariant","description":"Info about one language variant of a post."},"LanguagesResponse":{"properties":{"annotation_group":{"type":"string","title":"Annotation Group"},"languages":{"items":{"type":"string"},"type":"array","title":"Languages"},"supported_languages":{"items":{"type":"string"},"type":"array","title":"Supported Languages"},"missing_languages":{"items":{"type":"string"},"type":"array","title":"Missing Languages"}},"type":"object","required":["annotation_group","languages","supported_languages","missing_languages"],"title":"LanguagesResponse"},"LifecycleTransitionRequest":{"properties":{"target_state":{"type":"string","enum":["component_editing","merge_review"],"title":"Target State"},"reason":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Reason"},"idempotency_key":{"type":"string","maxLength":120,"minLength":1,"title":"Idempotency Key"}},"additionalProperties":false,"type":"object","required":["target_state","idempotency_key"],"title":"LifecycleTransitionRequest","description":"SOCM Phase C.0 — lifecycle transition body.\n\nCodex P0.1: `target_state` Literal excludes `draft` and `approved`.\n- `draft` stays exclusively in initialize_product.\n- `approved` belongs to C.3 Approval-Service."},"LifecycleTransitionResponse":{"properties":{"product_id":{"type":"string","title":"Product Id"},"from_state":{"type":"string","title":"From State"},"to_state":{"type":"string","title":"To State"},"transition_kind":{"type":"string","title":"Transition Kind"},"revoked_reservations":{"type":"integer","title":"Revoked Reservations"},"transition_at":{"type":"string","title":"Transition At"},"idempotent_replay":{"type":"boolean","title":"Idempotent Replay"}},"type":"object","required":["product_id","from_state","to_state","transition_kind","revoked_reservations","transition_at","idempotent_replay"],"title":"LifecycleTransitionResponse"},"LocationRef":{"properties":{"lat":{"type":"number","title":"Lat"},"lon":{"type":"number","title":"Lon"},"waypoint_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Waypoint Id"},"track_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Track Id"}},"type":"object","required":["lat","lon"],"title":"LocationRef","description":"One observation location for a species (GPS, optionally tied to ArTrack waypoint)."},"MediaCreate":{"properties":{"storage_id":{"type":"integer","title":"Storage Id"},"position":{"type":"integer","title":"Position","default":0},"caption":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Caption"},"role":{"type":"string","pattern":"^(hero|gallery|inline|thumbnail|attachment|illustration|video)$","title":"Role","default":"gallery"}},"type":"object","required":["storage_id"],"title":"MediaCreate","description":"Schema for creating media."},"MediaRef":{"properties":{"storage_id":{"type":"integer","title":"Storage Id"},"kind":{"type":"string","title":"Kind"},"lat":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lat"},"lon":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lon"},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url"},"thumbnail_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnail Url"},"display":{"type":"boolean","title":"Display","default":true}},"type":"object","required":["storage_id","kind"],"title":"MediaRef","description":"One media file (illustration, real photo, video, 3D model, audio) for a species."},"MediaReorder":{"properties":{"order":{"items":{"type":"integer"},"type":"array","title":"Order","description":"List of media IDs in desired order"}},"type":"object","required":["order"],"title":"MediaReorder","description":"Schema for reordering media."},"MediaResponse":{"properties":{"id":{"type":"integer","title":"Id"},"storage_id":{"type":"integer","title":"Storage Id"},"position":{"type":"integer","title":"Position"},"caption":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Caption"},"role":{"type":"string","title":"Role"},"media_url":{"type":"string","title":"Media Url"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","storage_id","position","caption","role","media_url","created_at"],"title":"MediaResponse","description":"Response schema for media."},"MediaUpdate":{"properties":{"position":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Position"},"caption":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Caption"},"role":{"anyOf":[{"type":"string","pattern":"^(hero|gallery|inline|thumbnail|attachment|illustration|video)$"},{"type":"null"}],"title":"Role"}},"type":"object","title":"MediaUpdate","description":"Schema for updating media."},"Position3D":{"properties":{"x":{"type":"number","title":"X"},"y":{"type":"number","title":"Y"},"z":{"type":"number","title":"Z"}},"type":"object","required":["x","y","z"],"title":"Position3D"},"PostCollectionResponse":{"properties":{"collection_id":{"type":"integer","title":"Collection Id"},"post_id":{"type":"integer","title":"Post Id"},"position":{"type":"integer","title":"Position"},"added_at":{"type":"string","format":"date-time","title":"Added At"}},"type":"object","required":["collection_id","post_id","position","added_at"],"title":"PostCollectionResponse","description":"Response schema for a post-collection link."},"PostCreate":{"properties":{"title":{"type":"string","maxLength":500,"minLength":1,"title":"Title"},"slug":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Slug"},"doc_type":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Doc Type","description":"Document type: beitrag, angebot, rechnung, honorarnote, story, survey"},"content_type":{"type":"string","pattern":"^(json|txt|md)$","title":"Content Type","default":"md"},"content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content"},"status":{"type":"string","pattern":"^(draft|published|archived)$","title":"Status","default":"draft"},"partner_id":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Partner Id"},"subtitle":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Subtitle"},"tags":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Tags"},"category":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Category"},"language":{"anyOf":[{"type":"string","maxLength":10},{"type":"null"}],"title":"Language","default":"de"},"language_group":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Language Group"},"source_language":{"anyOf":[{"type":"string","maxLength":10},{"type":"null"}],"title":"Source Language"},"color":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}],"title":"Color"},"logo_url":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Logo Url","description":"Logo URL for PDF export branding"},"cover_image_url":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Cover Image Url","description":"Cover image URL for PDF title page (overrides auto-generated)"},"auto_translated":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Auto Translated","default":false},"manually_edited":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Manually Edited","default":false},"collab_enabled":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Collab Enabled"},"primary_collection_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Primary Collection Id"},"metadata_json":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Metadata Json"},"storage_ids":{"anyOf":[{"items":{"type":"integer"},"type":"array"},{"type":"null"}],"title":"Storage Ids"},"author_id":{"type":"string","maxLength":100,"minLength":1,"title":"Author Id","default":"system"},"author_name":{"type":"string","maxLength":200,"minLength":1,"title":"Author Name","default":"System"}},"type":"object","required":["title"],"title":"PostCreate","description":"Schema for creating a post."},"PostDetailResponse":{"properties":{"id":{"type":"integer","title":"Id"},"title":{"type":"string","title":"Title"},"slug":{"type":"string","title":"Slug"},"doc_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Doc Type"},"content_type":{"type":"string","title":"Content Type"},"content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content"},"status":{"type":"string","title":"Status"},"author_id":{"type":"string","title":"Author Id"},"author_name":{"type":"string","title":"Author Name"},"partner_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Partner Id"},"subtitle":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subtitle"},"tags":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Tags"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"},"language":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Language"},"language_group":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Language Group"},"source_language":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Language"},"color":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Color"},"logo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Logo Url"},"cover_image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cover Image Url"},"auto_translated":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Auto Translated","default":false},"manually_edited":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Manually Edited","default":false},"collab_enabled":{"type":"boolean","title":"Collab Enabled","default":false},"primary_collection_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Primary Collection Id"},"created_by_agent":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created By Agent"},"metadata_json":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Metadata Json"},"storage_ids":{"anyOf":[{"items":{"type":"integer"},"type":"array"},{"type":"null"}],"title":"Storage Ids"},"storage_urls":{"items":{"type":"string"},"type":"array","title":"Storage Urls","default":[]},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"version":{"type":"integer","title":"Version","default":1},"media":{"items":{"$ref":"#/components/schemas/MediaResponse"},"type":"array","title":"Media","default":[]},"annotations":{"items":{"$ref":"#/components/schemas/AnnotationResponse"},"type":"array","title":"Annotations","default":[]},"blocks":{"items":{"$ref":"#/components/schemas/BlockResponse"},"type":"array","title":"Blocks","default":[]},"references":{"items":{"$ref":"#/components/schemas/ReferenceResponse"},"type":"array","title":"References","default":[]},"access_summary":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Access Summary"}},"type":"object","required":["id","title","slug","content_type","content","status","author_id","author_name","created_at","updated_at"],"title":"PostDetailResponse","description":"Response schema for a post with all details."},"PostLanguagesResponse":{"properties":{"language_group":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Language Group"},"current_language":{"type":"string","title":"Current Language"},"source_language":{"type":"string","title":"Source Language"},"variants":{"items":{"$ref":"#/components/schemas/LanguageVariant"},"type":"array","title":"Variants"},"supported_languages":{"items":{"type":"string"},"type":"array","title":"Supported Languages","default":["de","en","sl","it","es","nl","fr"]}},"type":"object","required":["current_language","source_language","variants"],"title":"PostLanguagesResponse","description":"Available languages for a post."},"PostListResponse":{"properties":{"posts":{"items":{"$ref":"#/components/schemas/PostResponse"},"type":"array","title":"Posts"},"total":{"type":"integer","title":"Total"},"limit":{"type":"integer","title":"Limit"},"offset":{"type":"integer","title":"Offset"}},"type":"object","required":["posts","total","limit","offset"],"title":"PostListResponse","description":"Response schema for post list."},"PostPermissionCreate":{"properties":{"principal_type":{"type":"string","enum":["user","agent","email"],"title":"Principal Type","description":"user (existing auth-api UUID), agent (AgentOS name), email (unregistered recipient)"},"principal_id":{"type":"string","maxLength":200,"minLength":1,"title":"Principal Id","description":"Full prefixed identity: 'user:<uuid>' / 'agent:<name>' / 'email:<addr>'. The prefix MUST match principal_type."},"permission":{"type":"string","enum":["read","write"],"title":"Permission","default":"read"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At","description":"Optional ISO-8601 timestamp; NULL = never"},"send_email":{"type":"boolean","title":"Send Email","description":"For email-shares: send a magic-link redemption mail via comm-api. Ignored for user/agent principals.","default":true},"note":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Note","description":"Free-form audit note"}},"type":"object","required":["principal_type","principal_id"],"title":"PostPermissionCreate","description":"Body of POST /posts/{id}/permissions.\n\nEither `principal_type + principal_id` directly, OR `email` + we\nderive `principal_type='email'` and emit a magic-link share-token."},"PostPermissionRedeemResponse":{"properties":{"post_id":{"type":"integer","title":"Post Id"},"permission":{"type":"string","enum":["read","write"],"title":"Permission"},"requires_login":{"type":"boolean","title":"Requires Login"},"email":{"anyOf":[{"type":"string","format":"email"},{"type":"null"}],"title":"Email"},"granted":{"type":"boolean","title":"Granted"}},"type":"object","required":["post_id","permission","requires_login","granted"],"title":"PostPermissionRedeemResponse","description":"What the recipient learns after clicking the share link."},"PostPermissionResponse":{"properties":{"id":{"type":"integer","title":"Id"},"post_id":{"type":"integer","title":"Post Id"},"principal_type":{"type":"string","enum":["user","agent","email"],"title":"Principal Type"},"principal_id":{"type":"string","title":"Principal Id"},"permission":{"type":"string","enum":["read","write"],"title":"Permission"},"granted_by":{"type":"string","title":"Granted By"},"granted_at":{"type":"string","format":"date-time","title":"Granted At"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"},"revoked_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Revoked At"},"revoked_by":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Revoked By"},"share_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Share Token"},"share_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Share Url"},"metadata_json":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Metadata Json"}},"type":"object","required":["id","post_id","principal_type","principal_id","permission","granted_by","granted_at","expires_at","revoked_at","revoked_by","share_token"],"title":"PostPermissionResponse","description":"One row in GET /posts/{id}/permissions."},"PostPermissionUpdate":{"properties":{"permission":{"anyOf":[{"type":"string","enum":["read","write"]},{"type":"null"}],"title":"Permission"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"}},"type":"object","title":"PostPermissionUpdate","description":"PATCH body — permission level or expiry only."},"PostProductCollaborationStatusesResponse":{"properties":{"post_id":{"type":"integer","title":"Post Id"},"products":{"items":{"$ref":"#/components/schemas/ProductCollaborationStatusResponse"},"type":"array","title":"Products"}},"type":"object","required":["post_id","products"],"title":"PostProductCollaborationStatusesResponse"},"PostResponse":{"properties":{"id":{"type":"integer","title":"Id"},"title":{"type":"string","title":"Title"},"slug":{"type":"string","title":"Slug"},"doc_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Doc Type"},"content_type":{"type":"string","title":"Content Type"},"status":{"type":"string","title":"Status"},"author_id":{"type":"string","title":"Author Id"},"author_name":{"type":"string","title":"Author Name"},"partner_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Partner Id"},"subtitle":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subtitle"},"tags":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Tags"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"},"language":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Language"},"language_group":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Language Group"},"source_language":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Language"},"auto_translated":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Auto Translated","default":false},"collab_enabled":{"type":"boolean","title":"Collab Enabled","default":false},"primary_collection_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Primary Collection Id"},"created_by_agent":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created By Agent"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"metadata_json":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Metadata Json"},"section_types":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Section Types"}},"type":"object","required":["id","title","slug","content_type","status","author_id","author_name","created_at","updated_at"],"title":"PostResponse","description":"Response schema for a post (list view)."},"PostUpdate":{"properties":{"title":{"anyOf":[{"type":"string","maxLength":500,"minLength":1},{"type":"null"}],"title":"Title"},"slug":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Slug"},"doc_type":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Doc Type"},"content_type":{"anyOf":[{"type":"string","pattern":"^(json|txt|md)$"},{"type":"null"}],"title":"Content Type"},"content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content"},"status":{"anyOf":[{"type":"string","pattern":"^(draft|published|archived)$"},{"type":"null"}],"title":"Status"},"author_id":{"anyOf":[{"type":"string","maxLength":100,"minLength":1},{"type":"null"}],"title":"Author Id"},"author_name":{"anyOf":[{"type":"string","maxLength":200,"minLength":1},{"type":"null"}],"title":"Author Name"},"partner_id":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Partner Id"},"subtitle":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Subtitle"},"tags":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Tags"},"category":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Category"},"language":{"anyOf":[{"type":"string","maxLength":10},{"type":"null"}],"title":"Language"},"language_group":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Language Group"},"source_language":{"anyOf":[{"type":"string","maxLength":10},{"type":"null"}],"title":"Source Language"},"color":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}],"title":"Color"},"logo_url":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Logo Url"},"cover_image_url":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Cover Image Url"},"auto_translated":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Auto Translated"},"manually_edited":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Manually Edited"},"collab_enabled":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Collab Enabled"},"primary_collection_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Primary Collection Id"},"metadata_json":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Metadata Json"},"storage_ids":{"anyOf":[{"items":{"type":"integer"},"type":"array"},{"type":"null"}],"title":"Storage Ids"},"expected_version":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Expected Version"}},"type":"object","title":"PostUpdate","description":"Schema for updating a post."},"ProductCollaborationStatusResponse":{"properties":{"product_id":{"type":"string","title":"Product Id"},"post_id":{"type":"integer","title":"Post Id"},"section_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Section Id"},"object_type":{"type":"string","title":"Object Type"},"state":{"type":"string","title":"State"},"current_revision":{"type":"integer","title":"Current Revision"},"rendered_revision":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Rendered Revision"},"candidate_revision":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Candidate Revision"},"validation_profile":{"type":"string","title":"Validation Profile"},"owner":{"type":"string","title":"Owner"},"created_by":{"type":"string","title":"Created By"},"reviewers":{"items":{"type":"string"},"type":"array","title":"Reviewers"},"components":{"items":{"$ref":"#/components/schemas/ComponentStatusResponse"},"type":"array","title":"Components"}},"type":"object","required":["product_id","post_id","section_id","object_type","state","current_revision","rendered_revision","candidate_revision","validation_profile","owner","created_by","reviewers","components"],"title":"ProductCollaborationStatusResponse"},"ProfileCreate":{"properties":{"author_id":{"type":"string","maxLength":100,"minLength":1,"title":"Author Id"},"author_name":{"type":"string","maxLength":200,"minLength":1,"title":"Author Name"},"email":{"anyOf":[{"type":"string","maxLength":300},{"type":"null"}],"title":"Email"},"phone":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Phone"},"notify_on_reply":{"type":"boolean","title":"Notify On Reply","default":true},"notify_on_annotation":{"type":"boolean","title":"Notify On Annotation","default":true}},"type":"object","required":["author_id","author_name"],"title":"ProfileCreate","description":"Schema for creating/updating a user profile."},"ProfileResponse":{"properties":{"author_id":{"type":"string","title":"Author Id"},"author_name":{"type":"string","title":"Author Name"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"phone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone"},"notify_on_reply":{"type":"boolean","title":"Notify On Reply"},"notify_on_annotation":{"type":"boolean","title":"Notify On Annotation","default":true},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["author_id","author_name","notify_on_reply","created_at","updated_at"],"title":"ProfileResponse","description":"Response schema for a user profile."},"ProfileUpdate":{"properties":{"author_name":{"anyOf":[{"type":"string","maxLength":200,"minLength":1},{"type":"null"}],"title":"Author Name"},"email":{"anyOf":[{"type":"string","maxLength":300},{"type":"null"}],"title":"Email"},"phone":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Phone"},"notify_on_reply":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Notify On Reply"},"notify_on_annotation":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Notify On Annotation"}},"type":"object","title":"ProfileUpdate","description":"Schema for partial profile update."},"PublishVerificationRequest":{"properties":{"scope":{"type":"string","enum":["global","component"],"title":"Scope"},"component_id":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}],"title":"Component Id"},"verified_object_revision":{"type":"integer","minimum":0.0,"title":"Verified Object Revision"},"verified_component_revision":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Verified Component Revision"},"verified_doc_version":{"type":"integer","minimum":0.0,"title":"Verified Doc Version"},"note":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Note"},"idempotency_key":{"type":"string","maxLength":120,"minLength":1,"title":"Idempotency Key"}},"additionalProperties":false,"type":"object","required":["scope","verified_object_revision","verified_doc_version","idempotency_key"],"title":"PublishVerificationRequest","description":"SOCM Phase C.2 — verification publish body.\n\nArkturianCodex Cluster-3 GO (IACP 1e890e68) carry-forward:\n- extra='forbid': verifier_id in body → 422 (verifier identity\n  is taken from JWT only, never from request)\n- scope-shape cross-field validation via Pydantic model_validator\n- note ≤ 500 chars (matches DB CHECK ck_verification_note_bound)\n- revisions ≥ 0 (matches DB CHECK ck_*_non_negative)"},"PublishVerificationResponse":{"properties":{"verification_id":{"type":"string","title":"Verification Id"},"state":{"type":"string","enum":["current","stale"],"title":"State"},"current_object_revision_at_publish":{"type":"integer","title":"Current Object Revision At Publish"},"current_component_revision_at_publish":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Current Component Revision At Publish"},"current_doc_version_at_publish":{"type":"integer","title":"Current Doc Version At Publish"},"verified_at":{"type":"string","title":"Verified At"},"idempotent_replay":{"type":"boolean","title":"Idempotent Replay"}},"type":"object","required":["verification_id","state","current_object_revision_at_publish","current_component_revision_at_publish","current_doc_version_at_publish","verified_at","idempotent_replay"],"title":"PublishVerificationResponse"},"ReferenceCreate":{"properties":{"ref_number":{"type":"integer","minimum":1.0,"title":"Ref Number"},"title":{"type":"string","maxLength":500,"minLength":1,"title":"Title"},"authors":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Authors"},"url":{"anyOf":[{"type":"string","maxLength":1000},{"type":"null"}],"title":"Url"},"publication":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Publication"},"year":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}],"title":"Year"},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Note"}},"type":"object","required":["ref_number","title"],"title":"ReferenceCreate","description":"Schema for creating a reference."},"ReferenceResponse":{"properties":{"id":{"type":"integer","title":"Id"},"ref_number":{"type":"integer","title":"Ref Number"},"title":{"type":"string","title":"Title"},"authors":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authors"},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url"},"publication":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Publication"},"year":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Year"},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Note"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","ref_number","title","created_at","updated_at"],"title":"ReferenceResponse","description":"Response schema for a reference."},"ReferenceUpdate":{"properties":{"ref_number":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Ref Number"},"title":{"anyOf":[{"type":"string","maxLength":500,"minLength":1},{"type":"null"}],"title":"Title"},"authors":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Authors"},"url":{"anyOf":[{"type":"string","maxLength":1000},{"type":"null"}],"title":"Url"},"publication":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Publication"},"year":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}],"title":"Year"},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Note"}},"type":"object","title":"ReferenceUpdate","description":"Schema for updating a reference."},"RefinePhraseRequest":{"properties":{"find":{"type":"string","minLength":1,"title":"Find","description":"Substring to locate + replace"},"replace":{"type":"string","title":"Replace","description":"Replacement text (may be empty string for pure delete)"},"section_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Section Id","description":"Narrow search to paragraphs in this section. Ignored when block_id is set."},"block_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Block Id","description":"Pin search to ONE paragraph by its block_id (UUID). Most drift-stable scope."},"occurrence":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Occurrence","description":"1-based pick of the n-th match WITHIN the block_id-pinned paragraph. Requires block_id to be set."},"expected_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expected Text","description":"Optimistic-lock: only apply if the actually-found range currently contains this text. Default = the matched text in the live doc. Mismatch → 409 expected_text_mismatch."}},"type":"object","required":["find","replace"],"title":"RefinePhraseRequest"},"RegionApplyRequest":{"properties":{"token":{"type":"string","minLength":1,"title":"Token"},"region_content_svg":{"type":"string","maxLength":2000000,"minLength":1,"title":"Region Content Svg"},"expected_revision":{"type":"integer","minimum":0.0,"title":"Expected Revision"},"expected_region_hash":{"type":"string","maxLength":64,"minLength":64,"title":"Expected Region Hash"},"idempotency_key":{"type":"string","maxLength":120,"minLength":1,"title":"Idempotency Key"}},"additionalProperties":false,"type":"object","required":["token","region_content_svg","expected_revision","expected_region_hash","idempotency_key"],"title":"RegionApplyRequest"},"RegionApplyResponse":{"properties":{"claim_id":{"type":"string","title":"Claim Id"},"product_id":{"type":"string","title":"Product Id"},"component_id":{"type":"string","title":"Component Id"},"region_id":{"type":"string","title":"Region Id"},"component_revision":{"type":"integer","title":"Component Revision"},"product_revision":{"type":"integer","title":"Product Revision"},"content_hash":{"type":"string","title":"Content Hash"},"reservation_state":{"type":"string","title":"Reservation State"}},"type":"object","required":["claim_id","product_id","component_id","region_id","component_revision","product_revision","content_hash","reservation_state"],"title":"RegionApplyResponse"},"RegionListResponse":{"properties":{"product_id":{"type":"string","title":"Product Id"},"component_id":{"type":"string","title":"Component Id"},"count":{"type":"integer","title":"Count"},"regions":{"items":{"$ref":"#/components/schemas/RegionStateView"},"type":"array","title":"Regions"}},"additionalProperties":false,"type":"object","required":["product_id","component_id","count","regions"],"title":"RegionListResponse"},"RegionReleaseRequest":{"properties":{"token":{"type":"string","minLength":1,"title":"Token"}},"additionalProperties":false,"type":"object","required":["token"],"title":"RegionReleaseRequest"},"RegionReleaseResponse":{"properties":{"claim_id":{"type":"string","title":"Claim Id"},"state":{"type":"string","title":"State"},"idempotent":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Idempotent"}},"type":"object","required":["claim_id","state"],"title":"RegionReleaseResponse"},"RegionReserveRequest":{"properties":{"base_revision":{"type":"integer","minimum":0.0,"title":"Base Revision"},"base_region_hash":{"type":"string","maxLength":64,"minLength":64,"title":"Base Region Hash"},"intent":{"anyOf":[{"type":"string","enum":["edit","review","merge"]},{"type":"null"}],"title":"Intent"},"depends_on":{"items":{"type":"string"},"type":"array","title":"Depends On"},"ttl_seconds":{"anyOf":[{"type":"integer","maximum":1800.0,"minimum":1.0},{"type":"null"}],"title":"Ttl Seconds"}},"additionalProperties":false,"type":"object","required":["base_revision","base_region_hash"],"title":"RegionReserveRequest"},"RegionReserveResponse":{"properties":{"claim_id":{"type":"string","title":"Claim Id"},"product_id":{"type":"string","title":"Product Id"},"component_id":{"type":"string","title":"Component Id"},"region_id":{"type":"string","title":"Region Id"},"token":{"type":"string","title":"Token"},"base_revision":{"type":"integer","title":"Base Revision"},"base_region_hash":{"type":"string","title":"Base Region Hash"},"is_new_region":{"type":"boolean","title":"Is New Region"},"expires_at":{"type":"string","title":"Expires At"},"convention_hint":{"type":"string","title":"Convention Hint"}},"type":"object","required":["claim_id","product_id","component_id","region_id","token","base_revision","base_region_hash","is_new_region","expires_at","convention_hint"],"title":"RegionReserveResponse"},"RegionRevokeRequest":{"properties":{"reason":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Reason"}},"additionalProperties":false,"type":"object","title":"RegionRevokeRequest"},"RegionRevokeResponse":{"properties":{"claim_id":{"type":"string","title":"Claim Id"},"state":{"type":"string","title":"State"},"idempotent":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Idempotent"}},"type":"object","required":["claim_id","state"],"title":"RegionRevokeResponse"},"RegionStateView":{"properties":{"claim_id":{"type":"string","title":"Claim Id"},"region_id":{"type":"string","title":"Region Id"},"holder_id":{"type":"string","title":"Holder Id"},"state":{"type":"string","title":"State"},"base_revision":{"type":"integer","title":"Base Revision"},"base_region_hash":{"type":"string","title":"Base Region Hash"},"intent":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Intent"},"claimed_at":{"type":"string","title":"Claimed At"},"expires_at":{"type":"string","title":"Expires At"},"heartbeat_at":{"type":"string","title":"Heartbeat At"},"released_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Released At"}},"additionalProperties":false,"type":"object","required":["claim_id","region_id","holder_id","state","base_revision","base_region_hash","intent","claimed_at","expires_at","heartbeat_at","released_at"],"title":"RegionStateView","description":"SOCM Phase 4.4.3 — single region-reservation row, read-only view.\n\nMirrors region_reservations columns minus the secret token_hmac\n(HMAC of the plaintext token; never exposed). The plaintext token\nitself is only returned ONCE in the reserve response and never\npersisted, so it cannot appear here regardless."},"RejectReviewRequest":{"properties":{"revision_to_reject":{"type":"integer","minimum":1.0,"title":"Revision To Reject"},"reason":{"type":"string","maxLength":500,"title":"Reason"},"idempotency_key":{"type":"string","maxLength":120,"minLength":1,"title":"Idempotency Key"}},"additionalProperties":false,"type":"object","required":["revision_to_reject","reason","idempotency_key"],"title":"RejectReviewRequest"},"RejectReviewResponse":{"properties":{"product_id":{"type":"string","title":"Product Id"},"decision_revision":{"type":"integer","title":"Decision Revision"},"prior_state":{"type":"string","title":"Prior State"},"new_state":{"type":"string","title":"New State"},"decision_at":{"type":"string","title":"Decision At"},"idempotent_replay":{"type":"boolean","title":"Idempotent Replay"},"rejected_revision":{"type":"integer","title":"Rejected Revision"}},"type":"object","required":["product_id","decision_revision","prior_state","new_state","decision_at","idempotent_replay","rejected_revision"],"title":"RejectReviewResponse"},"ReleaseRequest":{"properties":{"token":{"type":"string","minLength":1,"title":"Token"}},"additionalProperties":false,"type":"object","required":["token"],"title":"ReleaseRequest"},"ReleaseResponse":{"properties":{"product_id":{"type":"string","title":"Product Id"},"component_id":{"type":"string","title":"Component Id"},"state":{"type":"string","const":"released","title":"State"},"released_at":{"type":"string","title":"Released At"}},"type":"object","required":["product_id","component_id","state","released_at"],"title":"ReleaseResponse"},"RenewBody":{"properties":{"ttl":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Ttl"}},"type":"object","title":"RenewBody"},"ReopenProductRequest":{"properties":{"revision_to_reopen":{"type":"integer","minimum":1.0,"title":"Revision To Reopen"},"reason":{"type":"string","maxLength":500,"title":"Reason"},"idempotency_key":{"type":"string","maxLength":120,"minLength":1,"title":"Idempotency Key"}},"additionalProperties":false,"type":"object","required":["revision_to_reopen","reason","idempotency_key"],"title":"ReopenProductRequest"},"ReopenProductResponse":{"properties":{"product_id":{"type":"string","title":"Product Id"},"decision_revision":{"type":"integer","title":"Decision Revision"},"prior_state":{"type":"string","title":"Prior State"},"new_state":{"type":"string","title":"New State"},"decision_at":{"type":"string","title":"Decision At"},"idempotent_replay":{"type":"boolean","title":"Idempotent Replay"},"revoked_revision":{"type":"integer","title":"Revoked Revision"}},"type":"object","required":["product_id","decision_revision","prior_state","new_state","decision_at","idempotent_replay","revoked_revision"],"title":"ReopenProductResponse"},"ReservationStatusResponse":{"properties":{"holder_id":{"type":"string","title":"Holder Id"},"base_revision":{"type":"integer","title":"Base Revision"},"intent":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Intent"},"depends_on":{"items":{"type":"string"},"type":"array","title":"Depends On"},"state":{"type":"string","enum":["held","released","revoked","expired"],"title":"State"},"claimed_at":{"type":"string","title":"Claimed At"},"expires_at":{"type":"string","title":"Expires At"},"heartbeat_at":{"type":"string","title":"Heartbeat At"},"terminal_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Terminal At"}},"type":"object","required":["holder_id","base_revision","intent","depends_on","state","claimed_at","expires_at","heartbeat_at","terminal_at"],"title":"ReservationStatusResponse"},"ReserveRequest":{"properties":{"base_revision":{"type":"integer","minimum":0.0,"title":"Base Revision"},"intent":{"anyOf":[{"type":"string","enum":["edit","review","merge"]},{"type":"null"}],"title":"Intent"},"depends_on":{"items":{"type":"string"},"type":"array","title":"Depends On"},"ttl_seconds":{"anyOf":[{"type":"integer","maximum":1800.0,"minimum":1.0},{"type":"null"}],"title":"Ttl Seconds"}},"additionalProperties":false,"type":"object","required":["base_revision"],"title":"ReserveRequest"},"ReserveResponse":{"properties":{"product_id":{"type":"string","title":"Product Id"},"component_id":{"type":"string","title":"Component Id"},"holder_id":{"type":"string","title":"Holder Id"},"token":{"type":"string","title":"Token"},"expires_at":{"type":"string","title":"Expires At"},"claimed_at":{"type":"string","title":"Claimed At"}},"type":"object","required":["product_id","component_id","holder_id","token","expires_at","claimed_at"],"title":"ReserveResponse"},"RevisionDetailResponse":{"properties":{"id":{"type":"integer","title":"Id"},"post_id":{"type":"integer","title":"Post Id"},"content":{"type":"string","title":"Content"},"author_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Author Id"},"author_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Author Name"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","post_id","content","created_at"],"title":"RevisionDetailResponse","description":"Detail view — includes full old content for diffing."},"RevisionListItem":{"properties":{"id":{"type":"integer","title":"Id"},"post_id":{"type":"integer","title":"Post Id"},"author_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Author Id"},"author_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Author Name"},"content_preview":{"type":"string","title":"Content Preview"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","post_id","content_preview","created_at"],"title":"RevisionListItem","description":"List view — no full content, just preview."},"RevokeRequest":{"properties":{"reason":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Reason"}},"additionalProperties":false,"type":"object","title":"RevokeRequest"},"RevokeResponse":{"properties":{"product_id":{"type":"string","title":"Product Id"},"component_id":{"type":"string","title":"Component Id"},"state":{"type":"string","const":"revoked","title":"State"},"revoked_at":{"type":"string","title":"Revoked At"}},"type":"object","required":["product_id","component_id","state","revoked_at"],"title":"RevokeResponse"},"RollbackRequest":{"properties":{"target_revision":{"type":"integer","minimum":1.0,"title":"Target Revision"},"reason":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Reason"},"idempotency_key":{"type":"string","maxLength":120,"minLength":1,"title":"Idempotency Key"}},"additionalProperties":false,"type":"object","required":["target_revision","idempotency_key"],"title":"RollbackRequest","description":"SOCM Phase C.1b — rollback body.\n\nArkturianClaude P1.2 IACP 8efed70c: target_revision >= 1\nenforced at the Pydantic layer; service-layer backstop catches\ndirect service-call abuse."},"RollbackResponse":{"properties":{"product_id":{"type":"string","title":"Product Id"},"from_revision":{"type":"integer","title":"From Revision"},"target_revision":{"type":"integer","title":"Target Revision"},"new_revision":{"type":"integer","title":"New Revision"},"render_state":{"type":"string","title":"Render State"},"rollback_at":{"type":"string","title":"Rollback At"},"idempotent_replay":{"type":"boolean","title":"Idempotent Replay"}},"type":"object","required":["product_id","from_revision","target_revision","new_revision","render_state","rollback_at","idempotent_replay"],"title":"RollbackResponse"},"SceneInput":{"properties":{"title":{"type":"string","title":"Title"},"narrative":{"type":"string","title":"Narrative"},"mood":{"type":"string","title":"Mood"},"location":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Location"},"illustrationPrompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Illustrationprompt"},"illustrationId":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Illustrationid"},"videoId":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Videoid"},"audioId":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Audioid"}},"type":"object","required":["title","narrative","mood"],"title":"SceneInput","description":"Input for a single scene."},"SceneResponse":{"properties":{"id":{"type":"string","title":"Id"},"title":{"type":"string","title":"Title"},"narrative":{"type":"string","title":"Narrative"},"mood":{"type":"string","title":"Mood"},"location":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Location"},"illustrationPrompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Illustrationprompt"},"illustrationId":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Illustrationid"},"videoId":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Videoid"},"audioId":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Audioid"}},"type":"object","required":["id","title","narrative","mood"],"title":"SceneResponse","description":"A single story scene."},"SectionApproveRequest":{"properties":{},"type":"object","title":"SectionApproveRequest"},"SectionCreateRequest":{"properties":{"type":{"type":"string","title":"Type","description":"product | question | task"},"attrs":{"additionalProperties":true,"type":"object","title":"Attrs","description":"Section-type-specific attributes — e.g. {name, mode, goal} for product, {initiator, targets, status} for question, {assignee, status, due} for task."},"initial_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Initial Text","description":"Optional body text inserted as the section's initial content. For questions, set this to the `<main>` body."},"paragraph_index":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Paragraph Index","description":"0-based paragraph index to insert the new section AFTER. None = append at the end of the doc (legacy default)."}},"type":"object","required":["type"],"title":"SectionCreateRequest"},"SectionDeclineRequest":{"properties":{"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"}},"type":"object","title":"SectionDeclineRequest"},"SectionDetail":{"properties":{"id":{"type":"string","title":"Id"},"type":{"type":"string","title":"Type"},"role_start_index":{"type":"integer","title":"Role Start Index"},"role_end_index":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Role End Index"},"char_start":{"type":"integer","title":"Char Start"},"char_end":{"type":"integer","title":"Char End"},"attrs":{"additionalProperties":true,"type":"object","title":"Attrs"},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"},"paragraph_count":{"type":"integer","title":"Paragraph Count"},"paragraphs":{"items":{"$ref":"#/components/schemas/SectionParagraph"},"type":"array","title":"Paragraphs"}},"type":"object","required":["id","type","role_start_index","role_end_index","char_start","char_end","attrs","paragraph_count","paragraphs"],"title":"SectionDetail"},"SectionDiffRequest":{"properties":{"start_pos":{"type":"integer","minimum":0.0,"title":"Start Pos","description":"Char offset in materialized text"},"end_pos":{"type":"integer","minimum":0.0,"title":"End Pos"},"new_text":{"type":"string","title":"New Text","default":""}},"type":"object","required":["start_pos","end_pos"],"title":"SectionDiffRequest"},"SectionEditorsRequest":{"properties":{"add":{"items":{"type":"string"},"type":"array","title":"Add"},"remove":{"items":{"type":"string"},"type":"array","title":"Remove"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"}},"type":"object","title":"SectionEditorsRequest","description":"Body für POST /{section_id}/editors — Editor-Liste pflegen.\n\nGegenstück zum Handoff für den häufigeren, kleineren Fall: jemand\nsoll am Produkt mitschreiben dürfen, ohne die Verantwortung dafür\nzu übernehmen. Bis dahin gab es dafür GAR keinen Weg — `editors`\nist server-owned, also über PATCH gesperrt, und der einzige\nangebotene Ausweg war der Handoff, der gleich das Eigentum mit\nüberträgt. Wer nur mitschreiben lassen wollte, musste abgeben."},"SectionHandoffRequest":{"properties":{"new_owner":{"type":"string","minLength":1,"title":"New Owner"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"}},"type":"object","required":["new_owner"],"title":"SectionHandoffRequest"},"SectionParagraph":{"properties":{"index":{"type":"integer","title":"Index"},"text":{"type":"string","title":"Text"},"author_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Author Id"},"author_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Author Name"},"block_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Block Id"},"section_role":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Section Role"}},"type":"object","required":["index","text"],"title":"SectionParagraph"},"SectionPatchRequest":{"properties":{"attrs":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Attrs"},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},"type":"object","title":"SectionPatchRequest"},"SectionReplyRequest":{"properties":{"text":{"type":"string","minLength":1,"title":"Text"},"by":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"By","description":"Override the reply's `by` attr — defaults to the calling identity. Useful when a tool/proxy submits on behalf."},"targets":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Targets","description":"Optional comma-list of agent names. When set, the reply's chunk_committed push narrows to that subset. Default is the parent section's targets (or broadcast). Visibility is unaffected — all post readers see the reply in the doc."}},"type":"object","required":["text"],"title":"SectionReplyRequest"},"SectionResolveRequest":{"properties":{"note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Note"}},"type":"object","title":"SectionResolveRequest"},"SectionSummary":{"properties":{"id":{"type":"string","title":"Id"},"type":{"type":"string","title":"Type"},"role_start_index":{"type":"integer","title":"Role Start Index"},"role_end_index":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Role End Index"},"char_start":{"type":"integer","title":"Char Start"},"char_end":{"type":"integer","title":"Char End"},"attrs":{"additionalProperties":true,"type":"object","title":"Attrs"},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"},"paragraph_count":{"type":"integer","title":"Paragraph Count"}},"type":"object","required":["id","type","role_start_index","role_end_index","char_start","char_end","attrs","paragraph_count"],"title":"SectionSummary"},"SectionTimeoutRequest":{"properties":{},"type":"object","title":"SectionTimeoutRequest"},"SectionVoteRequest":{"properties":{"choice":{"type":"string","maxLength":2000,"minLength":1,"title":"Choice"}},"type":"object","required":["choice"],"title":"SectionVoteRequest"},"StoryCreateRequest":{"properties":{"title":{"type":"string","title":"Title","description":"Story title"},"story_group":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Story Group","description":"Group ID (auto-generated from title if omitted)"},"language":{"type":"string","title":"Language","description":"Language code","default":"de"},"subtitle":{"type":"string","title":"Subtitle","description":"Subtitle","default":""},"narrator":{"type":"string","title":"Narrator","description":"Narrator name","default":"tschauko"},"color":{"type":"string","title":"Color","description":"Theme color hex","default":"#7CB342"},"cover":{"type":"string","title":"Cover","description":"Cover image URL or storage ID","default":""},"region":{"type":"string","title":"Region","description":"Region/location","default":""},"duration":{"type":"string","title":"Duration","description":"Duration estimate (e.g. '12 min')","default":""},"status":{"type":"string","title":"Status","description":"draft, published, or archived","default":"draft"},"author_id":{"type":"string","title":"Author Id","description":"Author ID","default":"system"},"author_name":{"type":"string","title":"Author Name","description":"Author display name","default":"System"},"scenes":{"items":{"$ref":"#/components/schemas/SceneInput"},"type":"array","title":"Scenes","description":"Story scenes"}},"type":"object","required":["title"],"title":"StoryCreateRequest","description":"Request to create a new story."},"StoryListItem":{"properties":{"id":{"type":"integer","title":"Id"},"story_group":{"type":"string","title":"Story Group"},"language":{"type":"string","title":"Language"},"title":{"type":"string","title":"Title"},"subtitle":{"type":"string","title":"Subtitle"},"slug":{"type":"string","title":"Slug"},"narrator":{"type":"string","title":"Narrator"},"color":{"type":"string","title":"Color"},"cover":{"type":"string","title":"Cover"},"region":{"type":"string","title":"Region"},"duration":{"type":"string","title":"Duration"},"scene_count":{"type":"integer","title":"Scene Count"},"available_languages":{"items":{"type":"string"},"type":"array","title":"Available Languages","default":[]}},"type":"object","required":["id","story_group","language","title","subtitle","slug","narrator","color","cover","region","duration","scene_count"],"title":"StoryListItem","description":"Story in list view (no scenes)."},"StoryListResponse":{"properties":{"stories":{"items":{"$ref":"#/components/schemas/StoryListItem"},"type":"array","title":"Stories"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["stories","total"],"title":"StoryListResponse","description":"List of stories."},"StoryResponse":{"properties":{"id":{"type":"integer","title":"Id"},"story_group":{"type":"string","title":"Story Group"},"language":{"type":"string","title":"Language"},"title":{"type":"string","title":"Title"},"subtitle":{"type":"string","title":"Subtitle"},"slug":{"type":"string","title":"Slug"},"narrator":{"type":"string","title":"Narrator"},"color":{"type":"string","title":"Color"},"cover":{"type":"string","title":"Cover"},"region":{"type":"string","title":"Region"},"duration":{"type":"string","title":"Duration"},"status":{"type":"string","title":"Status"},"scenes":{"items":{"$ref":"#/components/schemas/SceneResponse"},"type":"array","title":"Scenes"},"available_languages":{"items":{"type":"string"},"type":"array","title":"Available Languages","default":[]},"auto_translated":{"type":"boolean","title":"Auto Translated","default":false}},"type":"object","required":["id","story_group","language","title","subtitle","slug","narrator","color","cover","region","duration","status","scenes"],"title":"StoryResponse","description":"Full story response."},"StoryUpdateRequest":{"properties":{"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"subtitle":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subtitle"},"narrator":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Narrator"},"color":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Color"},"cover":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cover"},"region":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Region"},"duration":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Duration"},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"},"scenes":{"anyOf":[{"items":{"$ref":"#/components/schemas/SceneInput"},"type":"array"},{"type":"null"}],"title":"Scenes"}},"type":"object","title":"StoryUpdateRequest","description":"Request to update an existing story. All fields optional."},"SuggestionAcceptResponse":{"properties":{"suggestion_id":{"type":"string","title":"Suggestion Id"},"status":{"type":"string","const":"accepted","title":"Status"},"applied_to_component":{"type":"string","title":"Applied To Component"},"new_component_revision":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"New Component Revision"},"new_product_revision":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"New Product Revision"}},"type":"object","required":["suggestion_id","status","applied_to_component"],"title":"SuggestionAcceptResponse"},"SuggestionDeclineRequest":{"properties":{"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"}},"type":"object","title":"SuggestionDeclineRequest"},"SuggestionDeclineResponse":{"properties":{"suggestion_id":{"type":"string","title":"Suggestion Id"},"status":{"type":"string","const":"declined","title":"Status"}},"type":"object","required":["suggestion_id","status"],"title":"SuggestionDeclineResponse"},"TranslationResult":{"properties":{"language":{"type":"string","title":"Language"},"post_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Post Id"},"status":{"type":"string","title":"Status"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"}},"type":"object","required":["language","status"],"title":"TranslationResult","description":"Result for one language translation."},"UninviteRequest":{"properties":{"agent_names":{"items":{"type":"string"},"type":"array","minItems":1,"title":"Agent Names","description":"Federation session names to remove from notify_authors. Names that aren't subscribed are reported, not failed — a partial batch still succeeds for the subscribed ones."}},"type":"object","required":["agent_names"],"title":"UninviteRequest","description":"Body for POST /posts/{post_id}/uninvite."},"UninviteResponse":{"properties":{"post_id":{"type":"integer","title":"Post Id"},"removed":{"items":{"type":"string"},"type":"array","title":"Removed"},"not_subscribed":{"items":{"type":"string"},"type":"array","title":"Not Subscribed"},"notify_authors_after":{"items":{"type":"string"},"type":"array","title":"Notify Authors After"}},"type":"object","required":["post_id","removed","not_subscribed","notify_authors_after"],"title":"UninviteResponse"},"UpdateAnnotationKnowledgeRequest":{"properties":{"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"object_description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Object Description"},"object_audio":{"anyOf":[{"$ref":"#/components/schemas/AudioRef"},{"type":"null"}]},"facts":{"anyOf":[{"items":{"$ref":"#/components/schemas/FactItem"},"type":"array"},{"type":"null"}],"title":"Facts"},"annotations":{"anyOf":[{"items":{"$ref":"#/components/schemas/AnnotationPoint"},"type":"array"},{"type":"null"}],"title":"Annotations"},"combined_audio":{"anyOf":[{"$ref":"#/components/schemas/AudioRef"},{"type":"null"}]},"binom":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Binom"},"common_name_de":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Common Name De"},"short":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Short"},"wiki":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Wiki"},"image_search_hint":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Search Hint"},"media":{"anyOf":[{"items":{"$ref":"#/components/schemas/MediaRef"},"type":"array"},{"type":"null"}],"title":"Media"},"locations":{"anyOf":[{"items":{"$ref":"#/components/schemas/LocationRef"},"type":"array"},{"type":"null"}],"title":"Locations"},"cover_storage_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Cover Storage Id"}},"type":"object","title":"UpdateAnnotationKnowledgeRequest","description":"Update annotation knowledge content."},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"VerificationListItem":{"properties":{"verification_id":{"type":"string","title":"Verification Id"},"scope":{"type":"string","enum":["global","component"],"title":"Scope"},"component_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Component Id"},"verified_object_revision":{"type":"integer","title":"Verified Object Revision"},"verified_component_revision":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Verified Component Revision"},"verified_doc_version":{"type":"integer","title":"Verified Doc Version"},"current_object_revision_at_publish":{"type":"integer","title":"Current Object Revision At Publish"},"current_component_revision_at_publish":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Current Component Revision At Publish"},"current_doc_version_at_publish":{"type":"integer","title":"Current Doc Version At Publish"},"verifier_id":{"type":"string","title":"Verifier Id"},"state":{"type":"string","enum":["current","stale"],"title":"State"},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Note"},"verified_at":{"type":"string","title":"Verified At"},"staled_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Staled At"},"staled_by_object_revision":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Staled By Object Revision"}},"type":"object","required":["verification_id","scope","component_id","verified_object_revision","verified_component_revision","verified_doc_version","current_object_revision_at_publish","current_component_revision_at_publish","current_doc_version_at_publish","verifier_id","state","note","verified_at","staled_at","staled_by_object_revision"],"title":"VerificationListItem"},"VerificationListResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/VerificationListItem"},"type":"array","title":"Items"},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"}},"type":"object","required":["items","next_cursor"],"title":"VerificationListResponse"},"VisionLatestResponse":{"properties":{"section_id":{"type":"string","title":"Section Id"},"attrs":{"additionalProperties":true,"type":"object","title":"Attrs"},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"},"body_text":{"type":"string","title":"Body Text"}},"type":"object","required":["section_id","attrs","body_text"],"title":"VisionLatestResponse"},"content__routes__annotations_knowledge__GenerateLanguagesRequest":{"properties":{"languages":{"items":{"type":"string"},"type":"array","title":"Languages","description":"Target language codes"},"force_refresh":{"type":"boolean","title":"Force Refresh","default":false}},"type":"object","required":["languages"],"title":"GenerateLanguagesRequest"},"content__routes__annotations_knowledge__GenerateLanguagesResult":{"properties":{"annotation_group":{"type":"string","title":"Annotation Group"},"results":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Results"}},"type":"object","required":["annotation_group","results"],"title":"GenerateLanguagesResult"},"content__routes__stories__GenerateLanguagesRequest":{"properties":{"languages":{"items":{"type":"string"},"type":"array","title":"Languages","description":"Target language codes"},"force_refresh":{"type":"boolean","title":"Force Refresh","description":"Re-translate even if exists","default":false}},"type":"object","required":["languages"],"title":"GenerateLanguagesRequest","description":"Request to batch-generate story translations."},"content__routes__stories__GenerateLanguagesResult":{"properties":{"story_group":{"type":"string","title":"Story Group"},"results":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Results"}},"type":"object","required":["story_group","results"],"title":"GenerateLanguagesResult","description":"Result of batch translation."},"content__routes__translate__TranslateRequest":{"properties":{"text":{"type":"string","title":"Text","description":"Single string to translate. UTF-8, any length."},"source":{"type":"string","title":"Source","description":"ISO 639-1 source language code (e.g. 'de')."},"target":{"type":"string","title":"Target","description":"ISO 639-1 target language code (e.g. 'en')."}},"type":"object","required":["text","source","target"],"title":"TranslateRequest"},"content__routes__translate__TranslateResponse":{"properties":{"translated":{"type":"string","title":"Translated"},"source":{"type":"string","title":"Source"},"target":{"type":"string","title":"Target"},"backend":{"type":"string","title":"Backend","default":"google_translate"}},"type":"object","required":["translated","source","target"],"title":"TranslateResponse"},"content__services__language_service__TranslateRequest":{"properties":{"target_languages":{"items":{"type":"string"},"type":"array","title":"Target Languages","description":"Target language codes (e.g. ['en','sl'])"},"force_refresh":{"type":"boolean","title":"Force Refresh","description":"Re-translate even if a variant already exists","default":false}},"type":"object","required":["target_languages"],"title":"TranslateRequest","description":"Explicit translation request."},"content__services__language_service__TranslateResponse":{"properties":{"language_group":{"type":"string","title":"Language Group"},"source_language":{"type":"string","title":"Source Language"},"results":{"items":{"$ref":"#/components/schemas/TranslationResult"},"type":"array","title":"Results"}},"type":"object","required":["language_group","source_language","results"],"title":"TranslateResponse"}}}}