{"openapi":"3.0.0","paths":{"/":{"get":{"operationId":"App_get","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"string"}}}}},"tags":["Health"]}},"/realtime/config":{"get":{"operationId":"Realtime_get","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RealtimeConfiguration"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible"}},"security":[{"bearer":[]}],"tags":["Realtime"]}},"/realtime/authorize":{"post":{"operationId":"Realtime_authorize","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthorizeRealtime"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RealtimeAuthorization"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible"}},"security":[{"bearer":[]}],"tags":["Realtime"]}},"/realtime/authenticate":{"post":{"operationId":"Realtime_authenticate","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RealtimeSocket"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RealtimeUserAuthorization"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible"}},"security":[{"bearer":[]}],"tags":["Realtime"]}},"/realtime/presence":{"get":{"operationId":"Realtime_list","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ActorPresence"}}}}},"400":{"description":"Missing or invalid workspace header, or invalid input"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible"}},"security":[{"bearer":[]}],"tags":["Realtime"]}},"/realtime/webhooks/pusher":{"post":{"operationId":"RealtimeWebhooks_create","parameters":[],"responses":{"204":{"description":"Signed Pusher webhook accepted; current occupancy will be reconciled."}},"tags":["Realtime"]}},"/workspace/actors":{"get":{"operationId":"WorkspaceActors_list","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WorkspaceActor"}}}}},"400":{"description":"Missing or invalid workspace header, or invalid input\n\nInvalid workspace ID"},"401":{"description":"Missing, expired or revoked session"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible\n\nWorkspace not found or membership not accepted"}},"security":[{"bearer":[]}],"tags":["Workspace actors"]}},"/workspace/actors/me":{"get":{"operationId":"WorkspaceActors_myProfile","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceActor"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input\n\nInvalid workspace ID"},"401":{"description":"Missing, expired or revoked session"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible\n\nWorkspace not found or membership not accepted"}},"security":[{"bearer":[]}],"tags":["Workspace actors"]},"patch":{"operationId":"WorkspaceActors_updateMine","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateActorProfile"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceActor"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input\n\nInvalid workspace ID"},"401":{"description":"Missing, expired or revoked session"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible\n\nWorkspace not found or membership not accepted"}},"security":[{"bearer":[]}],"tags":["Workspace actors"]}},"/workspace/actors/{workspace_actor_id}":{"patch":{"operationId":"WorkspaceActors_update","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"workspace_actor_id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateActorProfile"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceActor"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input\n\nInvalid workspace ID"},"401":{"description":"Missing, expired or revoked session"},"403":{"description":"Only your own profile or an agent managed by workspace admins can be edited"},"404":{"description":"Workspace or resource not found or inaccessible\n\nWorkspace not found or membership not accepted"}},"security":[{"bearer":[]}],"tags":["Workspace actors"]},"get":{"operationId":"WorkspaceActors_get","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"workspace_actor_id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceActor"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input\n\nInvalid workspace ID"},"401":{"description":"Missing, expired or revoked session"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible\n\nWorkspace not found or membership not accepted"}},"security":[{"bearer":[]}],"tags":["Workspace actors"]}},"/workspace/actors/{workspace_actor_id}/avatar":{"put":{"operationId":"ActorAvatars_upload","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"workspace_actor_id","required":true,"in":"path","schema":{"format":"uuid","type":"string"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary"}}}}}},"responses":{"200":{"description":"Replace the workspace photo. JPG, PNG, WebP or GIF up to 10 MiB / 40 MP; stored as one 256 × 256 WebP.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceActor"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible"}},"security":[{"bearer":[]}],"tags":["Workspace actors"]},"delete":{"operationId":"ActorAvatars_remove","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"workspace_actor_id","required":true,"in":"path","schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceActor"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible"}},"security":[{"bearer":[]}],"tags":["Workspace actors"]}},"/workspace/actors/{workspace_actor_id}/avatar/{avatar_id}":{"get":{"operationId":"ActorAvatars_download","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"workspace_actor_id","required":true,"in":"path","schema":{"format":"uuid","type":"string"}},{"name":"avatar_id","required":true,"in":"path","schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssetDownload"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible"}},"security":[{"bearer":[]}],"tags":["Workspace actors"]}},"/workspace/users":{"post":{"operationId":"WorkspaceUsers_create","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddWorkspaceUser"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceUser"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input"},"401":{"description":"Missing, expired or revoked session"},"403":{"description":"Only owners and admins can add members"},"404":{"description":"Existing Fryll account not found"},"409":{"description":"Account already belongs to the workspace"}},"security":[{"bearer":[]}],"tags":["Workspace users"]},"get":{"operationId":"WorkspaceUsers_list","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WorkspaceUser"}}}}},"400":{"description":"Invalid workspace ID"},"401":{"description":"Missing, expired or revoked session"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace not found or membership not accepted"}},"security":[{"bearer":[]}],"tags":["Workspace users"]}},"/workspace/users/{workspace_user_id}":{"patch":{"operationId":"WorkspaceUsers_update","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"workspace_user_id","required":true,"in":"path","schema":{"format":"uuid","type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateWorkspaceUserRole"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceUser"}}}},"400":{"description":"Invalid role or attempted owner demotion"},"401":{"description":"Missing, expired or revoked session"},"403":{"description":"Only the owner can assign admin/member roles"},"404":{"description":"Workspace or workspace user not found"}},"security":[{"bearer":[]}],"tags":["Workspace users"]},"delete":{"operationId":"WorkspaceUsers_delete","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"workspace_user_id","required":true,"in":"path","schema":{"format":"uuid","type":"string"}}],"responses":{"204":{"description":"Workspace membership removed"},"400":{"description":"The owner cannot be removed"},"401":{"description":"Missing, expired or revoked session"},"403":{"description":"Owners can remove admins/members; admins can remove members"},"404":{"description":"Workspace or workspace user not found"}},"security":[{"bearer":[]}],"tags":["Workspace users"]}},"/conversations/{conversation_id}/messages/{message_id}/saved":{"put":{"operationId":"Messages_save","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"conversation_id","required":true,"in":"path","schema":{"format":"uuid","type":"string"}},{"name":"message_id","required":true,"in":"path","schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"description":"Privately saves a readable message. Idempotent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SavedMessageState"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input"},"401":{"description":"Missing, expired or revoked session"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible"},"409":{"description":"Message has been deleted"}},"security":[{"bearer":[]}],"tags":["Messages"]},"delete":{"operationId":"Messages_unsave","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"conversation_id","required":true,"in":"path","schema":{"format":"uuid","type":"string"}},{"name":"message_id","required":true,"in":"path","schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"description":"Removes only the caller’s bookmark. Idempotent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SavedMessageState"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input"},"401":{"description":"Missing, expired or revoked session"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible"}},"security":[{"bearer":[]}],"tags":["Messages"]}},"/conversations/{conversation_id}/messages/{message_id}/reactions/{emoji}":{"put":{"operationId":"Messages_addReaction","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"conversation_id","required":true,"in":"path","schema":{"format":"uuid","type":"string"}},{"name":"message_id","required":true,"in":"path","schema":{"format":"uuid","type":"string"}},{"name":"emoji","required":true,"in":"path","description":"One URL-encoded Unicode emoji.","schema":{"type":"string"}}],"responses":{"200":{"description":"Adds your reaction idempotently.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageReactions"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input"},"401":{"description":"Missing, expired or revoked session"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible"},"409":{"description":"Message has been deleted"}},"security":[{"bearer":[]}],"tags":["Messages"]},"delete":{"operationId":"Messages_removeReaction","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"conversation_id","required":true,"in":"path","schema":{"format":"uuid","type":"string"}},{"name":"message_id","required":true,"in":"path","schema":{"format":"uuid","type":"string"}},{"name":"emoji","required":true,"in":"path","description":"One URL-encoded Unicode emoji.","schema":{"type":"string"}}],"responses":{"200":{"description":"Removes only your reaction idempotently.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageReactions"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input"},"401":{"description":"Missing, expired or revoked session"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible"}},"security":[{"bearer":[]}],"tags":["Messages"]}},"/conversations/{conversation_id}/messages":{"post":{"operationId":"Messages_create","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"conversation_id","required":true,"in":"path","schema":{"format":"uuid","type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMessage"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Message"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input"},"401":{"description":"Missing, expired or revoked session"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible"},"409":{"description":"Thread root has been deleted"}},"security":[{"bearer":[]}],"tags":["Messages"]},"get":{"operationId":"Messages_list","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"conversation_id","required":true,"in":"path","schema":{"format":"uuid","type":"string"}},{"name":"cursor","required":false,"in":"query","description":"Return messages older than this page cursor. Use next_cursor from the previous response.","schema":{"format":"uuid","type":"string"}},{"name":"parent_message_id","required":false,"in":"query","description":"List replies to this root message; omit to list top-level channel messages.","schema":{"format":"uuid","type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":50,"type":"number"}}],"responses":{"200":{"description":"Newest first. Omit parent_message_id for conversation history; specify a root ID for its replies.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessagePage"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input"},"401":{"description":"Missing, expired or revoked session"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible"}},"security":[{"bearer":[]}],"tags":["Messages"]}},"/conversations/{conversation_id}/messages/{message_id}":{"get":{"operationId":"Messages_get","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"conversation_id","required":true,"in":"path","schema":{"format":"uuid","type":"string"}},{"name":"message_id","required":true,"in":"path","schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Message"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input"},"401":{"description":"Missing, expired or revoked session"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible"}},"security":[{"bearer":[]}],"tags":["Messages"]},"patch":{"operationId":"Messages_update","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"conversation_id","required":true,"in":"path","schema":{"format":"uuid","type":"string"}},{"name":"message_id","required":true,"in":"path","schema":{"format":"uuid","type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateMessage"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Message"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input"},"401":{"description":"Missing, expired or revoked session"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible"},"409":{"description":"Message has been deleted"}},"security":[{"bearer":[]}],"tags":["Messages"]},"delete":{"operationId":"Messages_delete","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"conversation_id","required":true,"in":"path","schema":{"format":"uuid","type":"string"}},{"name":"message_id","required":true,"in":"path","schema":{"format":"uuid","type":"string"}}],"responses":{"204":{"description":"Message text deleted; thread placeholder retained"},"400":{"description":"Missing or invalid workspace header, or invalid input"},"401":{"description":"Missing, expired or revoked session"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible"}},"security":[{"bearer":[]}],"tags":["Messages"]}},"/channels/{channel_id}/messages":{"post":{"operationId":"ChannelMessages_create","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"channel_id","required":true,"in":"path","schema":{"format":"uuid","type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMessage"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Message"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input"},"401":{"description":"Missing, expired or revoked session"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible"},"409":{"description":"Thread root has been deleted"}},"security":[{"bearer":[]}],"tags":["Messages"]},"get":{"operationId":"ChannelMessages_list","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"channel_id","required":true,"in":"path","schema":{"format":"uuid","type":"string"}},{"name":"cursor","required":false,"in":"query","description":"Return messages older than this page cursor. Use next_cursor from the previous response.","schema":{"format":"uuid","type":"string"}},{"name":"parent_message_id","required":false,"in":"query","description":"List replies to this root message; omit to list top-level channel messages.","schema":{"format":"uuid","type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":50,"type":"number"}}],"responses":{"200":{"description":"Newest first. Omit parent_message_id for conversation history; specify a root ID for its replies.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessagePage"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input"},"401":{"description":"Missing, expired or revoked session"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible"}},"security":[{"bearer":[]}],"tags":["Messages"]}},"/channels/{channel_id}/messages/{message_id}":{"get":{"operationId":"ChannelMessages_get","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"channel_id","required":true,"in":"path","schema":{"format":"uuid","type":"string"}},{"name":"message_id","required":true,"in":"path","schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Message"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input"},"401":{"description":"Missing, expired or revoked session"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible"}},"security":[{"bearer":[]}],"tags":["Messages"]},"patch":{"operationId":"ChannelMessages_update","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"channel_id","required":true,"in":"path","schema":{"format":"uuid","type":"string"}},{"name":"message_id","required":true,"in":"path","schema":{"format":"uuid","type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateMessage"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Message"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input"},"401":{"description":"Missing, expired or revoked session"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible"},"409":{"description":"Message has been deleted"}},"security":[{"bearer":[]}],"tags":["Messages"]},"delete":{"operationId":"ChannelMessages_delete","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"channel_id","required":true,"in":"path","schema":{"format":"uuid","type":"string"}},{"name":"message_id","required":true,"in":"path","schema":{"format":"uuid","type":"string"}}],"responses":{"204":{"description":"Message text deleted; thread placeholder retained"},"400":{"description":"Missing or invalid workspace header, or invalid input"},"401":{"description":"Missing, expired or revoked session"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible"}},"security":[{"bearer":[]}],"tags":["Messages"]}},"/saved-messages":{"get":{"operationId":"SavedMessages_list","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"cursor","required":false,"in":"query","description":"Opaque next_cursor from the previous page. Newest saves first.","schema":{"maxLength":512,"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":50,"type":"number"}}],"responses":{"200":{"description":"Private bookmarks for the caller in this workspace. Inaccessible and deleted messages are omitted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SavedMessagePage"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible"}},"security":[{"bearer":[]}],"tags":["Saved messages"]}},"/conversations/{conversation_id}/assets":{"post":{"operationId":"Assets_create","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"conversation_id","required":true,"in":"path","schema":{"format":"uuid","type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAsset"}}}},"responses":{"201":{"description":"Reserve a pending attachment. Attach its ID to a message, then upload content.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Asset"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible"}},"security":[{"bearer":[]}],"tags":["Assets"]}},"/conversations/{conversation_id}/assets/{asset_id}/content":{"put":{"operationId":"Assets_upload","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"conversation_id","required":true,"in":"path","schema":{"format":"uuid","type":"string"}},{"name":"asset_id","required":true,"in":"path","schema":{"format":"uuid","type":"string"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary"}}}}}},"responses":{"200":{"description":"Upload at most 10 MiB. Ready assets are immutable; retries return the existing asset.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Asset"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible"}},"security":[{"bearer":[]}],"tags":["Assets"]}},"/conversations/{conversation_id}/assets/{asset_id}/download":{"get":{"operationId":"Assets_download","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"conversation_id","required":true,"in":"path","schema":{"format":"uuid","type":"string"}},{"name":"asset_id","required":true,"in":"path","schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssetDownload"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible"}},"security":[{"bearer":[]}],"tags":["Assets"]}},"/channels":{"post":{"operationId":"Channels_create","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateChannel"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Channel"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input\n\nInvalid input"},"401":{"description":"Missing, expired or revoked session"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible\n\nWorkspace or channel not found or inaccessible"},"409":{"description":"Channel name already taken in this workspace"}},"security":[{"bearer":[]}],"tags":["Channels"]},"get":{"operationId":"Channels_list","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Channel"}}}}},"400":{"description":"Missing or invalid workspace header, or invalid input\n\nInvalid input"},"401":{"description":"Missing, expired or revoked session"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible\n\nWorkspace or channel not found or inaccessible"}},"security":[{"bearer":[]}],"tags":["Channels"]}},"/channels/{channel_id}":{"get":{"operationId":"Channels_get","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"channel_id","required":true,"in":"path","schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Channel"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input\n\nInvalid input"},"401":{"description":"Missing, expired or revoked session"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible\n\nWorkspace or channel not found or inaccessible"}},"security":[{"bearer":[]}],"tags":["Channels"]}},"/conversations/{conversation_id}/read-state":{"get":{"operationId":"ConversationReadState_get","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"conversation_id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConversationReadState"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input\n\nInvalid input or message belongs to another conversation"},"401":{"description":"Missing, expired or revoked session"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible\n\nConversation not found or inaccessible"}},"security":[{"bearer":[]}],"tags":["Conversations"]},"put":{"operationId":"ConversationReadState_update","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"conversation_id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateReadState"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConversationReadState"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input\n\nInvalid input or message belongs to another conversation"},"401":{"description":"Missing, expired or revoked session"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible\n\nConversation not found or inaccessible"}},"security":[{"bearer":[]}],"tags":["Conversations"]}},"/channels/{channel_id}/read-state":{"get":{"operationId":"ChannelReadState_get","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"channel_id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConversationReadState"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input\n\nInvalid input or message belongs to another conversation"},"401":{"description":"Missing, expired or revoked session"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible\n\nConversation not found or inaccessible"}},"security":[{"bearer":[]}],"tags":["Conversations"]},"put":{"operationId":"ChannelReadState_update","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"channel_id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateReadState"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConversationReadState"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input\n\nInvalid input or message belongs to another conversation"},"401":{"description":"Missing, expired or revoked session"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible\n\nConversation not found or inaccessible"}},"security":[{"bearer":[]}],"tags":["Conversations"]}},"/threads/{thread_root_id}/read-state":{"get":{"operationId":"ThreadReadState_get","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"thread_root_id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConversationReadState"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input\n\nInvalid input or message belongs to another conversation"},"401":{"description":"Missing, expired or revoked session"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible\n\nConversation not found or inaccessible"}},"security":[{"bearer":[]}],"tags":["Conversations"]},"put":{"operationId":"ThreadReadState_update","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"thread_root_id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateReadState"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConversationReadState"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input\n\nInvalid input or message belongs to another conversation"},"401":{"description":"Missing, expired or revoked session"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible\n\nConversation not found or inaccessible"}},"security":[{"bearer":[]}],"tags":["Conversations"]}},"/threads/{thread_root_id}/subscription":{"put":{"operationId":"ThreadSubscription_update","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"thread_root_id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateThreadSubscription"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConversationReadState"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input\n\nInvalid input or message belongs to another conversation"},"401":{"description":"Missing, expired or revoked session"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible\n\nConversation not found or inaccessible"}},"security":[{"bearer":[]}],"tags":["Conversations"]}},"/threads":{"get":{"operationId":"Threads_list","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"following","required":false,"in":"query","description":"When false, include all accessible threads, including unfollowed ones.","schema":{"default":true,"type":"boolean"}},{"name":"unread","required":false,"in":"query","schema":{"default":false,"type":"boolean"}},{"name":"cursor","required":false,"in":"query","description":"Root message ID from next_cursor. Ordered by root ID descending for stable pagination.","schema":{"format":"uuid","type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":50,"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ThreadPage"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input\n\nInvalid input or message belongs to another conversation"},"401":{"description":"Missing, expired or revoked session"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible\n\nConversation not found or inaccessible"}},"security":[{"bearer":[]}],"tags":["Conversations"]}},"/auth/register":{"post":{"operationId":"Auth_register","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Register"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailPending"}}}},"400":{"description":"Invalid registration fields"},"429":{"description":"Too many registration attempts"}},"tags":["Auth"]}},"/auth/magic-link":{"post":{"operationId":"Auth_magicLink","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailLink"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailPending"}}}}},"tags":["Auth"]}},"/auth/recover":{"post":{"operationId":"Auth_recover","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecoverAccount"}}}},"responses":{"200":{"description":"Same response whether the account exists or not","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailPending"}}}},"400":{"description":"Invalid email"},"429":{"description":"Too many recovery attempts"}},"tags":["Auth"]}},"/auth/reset-password":{"post":{"operationId":"Auth_resetPassword","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResetPassword"}}}},"responses":{"200":{"description":"Password changed; existing sessions and email links revoked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordReset"}}}},"400":{"description":"Invalid token or password"},"401":{"description":"Invalid, expired or used reset link"},"429":{"description":"Too many reset attempts"}},"tags":["Auth"]}},"/auth/email-code":{"post":{"operationId":"Auth_emailCode","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailLink"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailCodePending"}}}}},"tags":["Auth"]}},"/auth/verify-code":{"post":{"operationId":"Auth_verifyCode","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyEmailCode"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}}},"401":{"description":"Invalid, expired or exhausted code"}},"tags":["Auth"]}},"/auth/verify-email":{"post":{"operationId":"Auth_verifyEmail","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyEmail"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/AuthResponse"},{"$ref":"#/components/schemas/EmailVerified"}]}}}}},"tags":["Auth"]}},"/auth/login":{"post":{"operationId":"Auth_login","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Login"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}}},"400":{"description":"Invalid login fields"},"401":{"description":"Invalid email or password"},"429":{"description":"Too many login attempts"}},"tags":["Auth"]}},"/auth/logout":{"post":{"operationId":"Auth_logout","parameters":[],"responses":{"204":{"description":"Current session revoked"},"401":{"description":"Missing, expired or revoked session"}},"security":[{"bearer":[]}],"tags":["Auth"]}},"/users/me":{"get":{"operationId":"Users_get","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/User"}}}},"401":{"description":"Missing, expired or revoked session"}},"security":[{"bearer":[]}],"tags":["Users"]},"patch":{"operationId":"Users_update","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateUser"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/User"}}}},"400":{"description":"Invalid profile fields"},"401":{"description":"Missing, expired or revoked session"}},"security":[{"bearer":[]}],"tags":["Users"]}},"/workspaces":{"post":{"operationId":"Workspaces_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWorkspace"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Workspace"}}}},"400":{"description":"Invalid name or slug"},"401":{"description":"Missing, expired or revoked session"},"409":{"description":"Workspace slug already taken"}},"security":[{"bearer":[]}],"tags":["Workspaces"]},"get":{"operationId":"Workspaces_list","parameters":[],"responses":{"200":{"description":"Workspaces where the current user has accepted membership","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Workspace"}}}}},"401":{"description":"Missing, expired or revoked session"}},"security":[{"bearer":[]}],"tags":["Workspaces"]}},"/workspace":{"get":{"operationId":"Workspace_get","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Workspace"}}}},"400":{"description":"Invalid workspace ID"},"401":{"description":"Missing, expired or revoked session"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace not found or membership not accepted"}},"security":[{"bearer":[]}],"tags":["Workspaces"]},"patch":{"operationId":"Workspace_update","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateWorkspace"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Workspace"}}}},"400":{"description":"Invalid name or slug"},"401":{"description":"Missing, expired or revoked session"},"403":{"description":"Only owners and admins can update workspace settings"},"404":{"description":"Workspace not found"},"409":{"description":"Workspace slug already taken"}},"security":[{"bearer":[]}],"tags":["Workspaces"]},"delete":{"operationId":"Workspace_delete","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Workspace deleted"},"400":{"description":"Missing or invalid workspace header, or invalid input"},"401":{"description":"Missing, expired or revoked session"},"403":{"description":"Only the owner can delete the workspace"},"404":{"description":"Workspace not found"}},"security":[{"bearer":[]}],"tags":["Workspaces"]}},"/workspace/owner":{"put":{"operationId":"Workspace_transferOwnership","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransferWorkspaceOwnership"}}}},"responses":{"200":{"description":"New owner membership; the previous owner becomes an admin","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceUser"}}}},"400":{"description":"The target must be an accepted workspace user"},"401":{"description":"Missing, expired or revoked session"},"403":{"description":"Only the owner can transfer ownership"},"404":{"description":"Workspace or workspace user not found"}},"security":[{"bearer":[]}],"tags":["Workspaces"]}},"/workspace/avatar":{"put":{"operationId":"WorkspaceAvatars_upload","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary"}}}}}},"responses":{"200":{"description":"Store one 256 × 256 WebP from a JPG, PNG, WebP or GIF up to 10 MiB / 40 MP.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Workspace"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input"},"403":{"description":"Only workspace owners and admins can change the photo"},"404":{"description":"Workspace or resource not found or inaccessible"}},"security":[{"bearer":[]}],"tags":["Workspaces"]},"delete":{"operationId":"WorkspaceAvatars_remove","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Workspace"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input"},"403":{"description":"Only workspace owners and admins can change the photo"},"404":{"description":"Workspace or resource not found or inaccessible"}},"security":[{"bearer":[]}],"tags":["Workspaces"]}},"/workspace/avatar/{avatar_id}":{"get":{"operationId":"WorkspaceAvatars_download","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"avatar_id","required":true,"in":"path","schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssetDownload"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible"}},"security":[{"bearer":[]}],"tags":["Workspaces"]}},"/channels/{channel_id}/members":{"post":{"operationId":"ChannelMembers_create","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"channel_id","required":true,"in":"path","schema":{"format":"uuid","type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddChannelMember"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChannelMember"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input\n\nInvalid input or pending workspace membership"},"401":{"description":"Missing, expired or revoked session"},"403":{"description":"Join the public channel before adding other members"},"404":{"description":"Workspace or resource not found or inaccessible\n\nWorkspace, channel or actor not found or inaccessible"},"409":{"description":"Actor is already a channel member"}},"security":[{"bearer":[]}],"tags":["Channel members"]},"get":{"operationId":"ChannelMembers_list","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"channel_id","required":true,"in":"path","schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ChannelMember"}}}}},"400":{"description":"Missing or invalid workspace header, or invalid input\n\nInvalid input or pending workspace membership"},"401":{"description":"Missing, expired or revoked session"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible\n\nWorkspace, channel or actor not found or inaccessible"}},"security":[{"bearer":[]}],"tags":["Channel members"]}},"/direct-conversations":{"get":{"operationId":"DirectConversations_list","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DirectConversation"}}}}},"400":{"description":"Missing or invalid workspace header, or invalid input"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible"}},"security":[{"bearer":[]}],"tags":["Direct conversations"]},"post":{"operationId":"DirectConversations_create","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDirectConversation"}}}},"responses":{"201":{"description":"Creates or reopens the unique conversation with this actor, including yourself for private notes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DirectConversation"}}}},"400":{"description":"Inactive participant"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Actor is outside the workspace"}},"security":[{"bearer":[]}],"tags":["Direct conversations"]}},"/conversations/{conversation_id}/token":{"get":{"operationId":"ConversationTokens_get","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"conversation_id","required":true,"in":"path","schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"description":"Your current token for this conversation, without the secret.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConversationToken"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input"},"401":{"description":"Missing, expired or revoked session"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible"}},"security":[{"bearer":[]}],"tags":["Conversation tokens"]},"post":{"operationId":"ConversationTokens_issue","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"conversation_id","required":true,"in":"path","schema":{"format":"uuid","type":"string"}}],"responses":{"201":{"description":"Issues a new token, replacing and revoking only your earlier token for this conversation. The token is shown only in this response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IssuedConversationToken"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input"},"401":{"description":"Missing, expired or revoked session"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible"}},"security":[{"bearer":[]}],"tags":["Conversation tokens"]},"delete":{"operationId":"ConversationTokens_revoke","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"conversation_id","required":true,"in":"path","schema":{"format":"uuid","type":"string"}}],"responses":{"204":{"description":"Token revoked; requests that use it are refused."},"400":{"description":"Missing or invalid workspace header, or invalid input"},"401":{"description":"Missing, expired or revoked session"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible"}},"security":[{"bearer":[]}],"tags":["Conversation tokens"]}},"/in/{token}":{"post":{"description":"No session or headers needed: `curl -d \"Deployed api v1.42.1\" <api>/in/<token>`. Send plain text, form fields or JSON. Messages are posted as the user who generated the token unless an `agent` name is supplied. Named agents join channels; DM participants remain unchanged. Set `thread_id` to reply in a thread. The owner must still be an active participant. Each token may post 60 times a minute.","operationId":"Inbound_post","parameters":[{"name":"token","required":true,"in":"path","description":"Your conversation token, from POST /conversations/{conversation_id}/token","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"text/plain":{"schema":{"oneOf":[{"type":"string","example":"Deployed api v1.42.1 to production"},{"type":"object","required":["text"],"properties":{"text":{"type":"string","maxLength":40000},"children":{"type":"array","maxItems":32,"description":"Optional message UI. Replaces the whole array on edit; [] clears it. At most 32 components and 40,000 combined characters, including info labels and children. Info contains text only and appears beside the preceding component. Loading expires 30 minutes after a children update.","items":{"oneOf":[{"type":"object","required":["type","text"],"additionalProperties":false,"properties":{"type":{"type":"string","enum":["text"]},"text":{"type":"string","minLength":1,"maxLength":40000}}},{"type":"object","required":["type","label"],"additionalProperties":false,"properties":{"type":{"type":"string","enum":["loading"]},"label":{"type":"string","minLength":1,"maxLength":200},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$","description":"Spinner/dot color. Defaults to the client accent; label uses the normal readable text color.","example":"#6366F1"}}},{"type":"object","required":["type","label","children"],"additionalProperties":false,"properties":{"type":{"type":"string","enum":["info"]},"label":{"type":"string","minLength":1,"maxLength":200,"description":"Accessible button label and popover heading."},"children":{"type":"array","minItems":1,"maxItems":31,"items":{"type":"object","required":["type","text"],"additionalProperties":false,"properties":{"type":{"type":"string","enum":["text"]},"text":{"type":"string","minLength":1,"maxLength":40000}}}}}}]}},"agent":{"type":"string","maxLength":80,"description":"Optional named-agent sender override, created on first use."},"mentioned_actor_ids":{"type":"array","maxItems":100,"uniqueItems":true,"items":{"type":"string","format":"uuid"},"description":"Optional explicit mention identities; validated against this workspace."},"thread_id":{"type":"string","format":"uuid","description":"Reply in the thread under this message."}}}]}},"application/x-www-form-urlencoded":{"schema":{"oneOf":[{"type":"string","example":"Deployed api v1.42.1 to production"},{"type":"object","required":["text"],"properties":{"text":{"type":"string","maxLength":40000},"children":{"type":"array","maxItems":32,"description":"Optional message UI. Replaces the whole array on edit; [] clears it. At most 32 components and 40,000 combined characters, including info labels and children. Info contains text only and appears beside the preceding component. Loading expires 30 minutes after a children update.","items":{"oneOf":[{"type":"object","required":["type","text"],"additionalProperties":false,"properties":{"type":{"type":"string","enum":["text"]},"text":{"type":"string","minLength":1,"maxLength":40000}}},{"type":"object","required":["type","label"],"additionalProperties":false,"properties":{"type":{"type":"string","enum":["loading"]},"label":{"type":"string","minLength":1,"maxLength":200},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$","description":"Spinner/dot color. Defaults to the client accent; label uses the normal readable text color.","example":"#6366F1"}}},{"type":"object","required":["type","label","children"],"additionalProperties":false,"properties":{"type":{"type":"string","enum":["info"]},"label":{"type":"string","minLength":1,"maxLength":200,"description":"Accessible button label and popover heading."},"children":{"type":"array","minItems":1,"maxItems":31,"items":{"type":"object","required":["type","text"],"additionalProperties":false,"properties":{"type":{"type":"string","enum":["text"]},"text":{"type":"string","minLength":1,"maxLength":40000}}}}}}]}},"agent":{"type":"string","maxLength":80,"description":"Optional named-agent sender override, created on first use."},"mentioned_actor_ids":{"type":"array","maxItems":100,"uniqueItems":true,"items":{"type":"string","format":"uuid"},"description":"Optional explicit mention identities; validated against this workspace."},"thread_id":{"type":"string","format":"uuid","description":"Reply in the thread under this message."}}}]}},"application/json":{"schema":{"oneOf":[{"type":"string","example":"Deployed api v1.42.1 to production"},{"type":"object","required":["text"],"properties":{"text":{"type":"string","maxLength":40000},"children":{"type":"array","maxItems":32,"description":"Optional message UI. Replaces the whole array on edit; [] clears it. At most 32 components and 40,000 combined characters, including info labels and children. Info contains text only and appears beside the preceding component. Loading expires 30 minutes after a children update.","items":{"oneOf":[{"type":"object","required":["type","text"],"additionalProperties":false,"properties":{"type":{"type":"string","enum":["text"]},"text":{"type":"string","minLength":1,"maxLength":40000}}},{"type":"object","required":["type","label"],"additionalProperties":false,"properties":{"type":{"type":"string","enum":["loading"]},"label":{"type":"string","minLength":1,"maxLength":200},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$","description":"Spinner/dot color. Defaults to the client accent; label uses the normal readable text color.","example":"#6366F1"}}},{"type":"object","required":["type","label","children"],"additionalProperties":false,"properties":{"type":{"type":"string","enum":["info"]},"label":{"type":"string","minLength":1,"maxLength":200,"description":"Accessible button label and popover heading."},"children":{"type":"array","minItems":1,"maxItems":31,"items":{"type":"object","required":["type","text"],"additionalProperties":false,"properties":{"type":{"type":"string","enum":["text"]},"text":{"type":"string","minLength":1,"maxLength":40000}}}}}}]}},"agent":{"type":"string","maxLength":80,"description":"Optional named-agent sender override, created on first use."},"mentioned_actor_ids":{"type":"array","maxItems":100,"uniqueItems":true,"items":{"type":"string","format":"uuid"},"description":"Optional explicit mention identities; validated against this workspace."},"thread_id":{"type":"string","format":"uuid","description":"Reply in the thread under this message."}}}]}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InboundMessage"}}}},"400":{"description":"No text, an unknown field, or an invalid agent name or thread_id"},"404":{"description":"Unknown or revoked token, or thread_id not in this conversation"},"409":{"description":"The thread's first message has been deleted"},"429":{"description":"More than 60 requests a minute with this token"}},"summary":"Post to a channel or DM with your conversation token","tags":["Inbound"]}},"/in/{token}/messages/{message_id}":{"patch":{"description":"Only messages created using this exact token can be edited. Token rotation revokes access to earlier posts. Omitted fields stay unchanged; children replaces the whole array and [] clears it. Updating children renews loading for 30 minutes. Text is the notification/search fallback. No new message notification is sent.","operationId":"Inbound_update","parameters":[{"name":"token","required":true,"in":"path","description":"The conversation token used to create the message","schema":{"type":"string"}},{"name":"message_id","required":true,"in":"path","schema":{"format":"uuid","type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","minProperties":1,"additionalProperties":false,"properties":{"text":{"type":"string","minLength":1,"maxLength":40000},"children":{"type":"array","maxItems":32,"description":"Optional message UI. Replaces the whole array on edit; [] clears it. At most 32 components and 40,000 combined characters, including info labels and children. Info contains text only and appears beside the preceding component. Loading expires 30 minutes after a children update.","items":{"oneOf":[{"type":"object","required":["type","text"],"additionalProperties":false,"properties":{"type":{"type":"string","enum":["text"]},"text":{"type":"string","minLength":1,"maxLength":40000}}},{"type":"object","required":["type","label"],"additionalProperties":false,"properties":{"type":{"type":"string","enum":["loading"]},"label":{"type":"string","minLength":1,"maxLength":200},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$","description":"Spinner/dot color. Defaults to the client accent; label uses the normal readable text color.","example":"#6366F1"}}},{"type":"object","required":["type","label","children"],"additionalProperties":false,"properties":{"type":{"type":"string","enum":["info"]},"label":{"type":"string","minLength":1,"maxLength":200,"description":"Accessible button label and popover heading."},"children":{"type":"array","minItems":1,"maxItems":31,"items":{"type":"object","required":["type","text"],"additionalProperties":false,"properties":{"type":{"type":"string","enum":["text"]},"text":{"type":"string","minLength":1,"maxLength":40000}}}}}}]}},"mentioned_actor_ids":{"type":"array","maxItems":100,"uniqueItems":true,"items":{"type":"string","format":"uuid"}}}}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Message"}}}},"400":{"description":"Invalid or empty update"},"404":{"description":"Unknown/revoked token or message not created with this token"},"409":{"description":"Message has been deleted"},"429":{"description":"More than 60 updates a minute with this token"}},"summary":"Update a message posted with this conversation token","tags":["Inbound"]}},"/search/messages":{"get":{"operationId":"Search_listMessages","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"q","required":true,"in":"query","description":"Search text. Messages support words, quoted phrases, OR and exclusions. Channels and members match literal substrings, ignoring case.","schema":{"minLength":1,"maxLength":200,"type":"string"}},{"name":"cursor","required":false,"in":"query","description":"Opaque next_cursor from the same search. Results are ordered by ID descending (UUIDv7 creation order).","schema":{"maxLength":1000,"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"type":"integer"}},{"name":"conversation_id","required":false,"in":"query","description":"Restrict to a channel or direct conversation the caller can read.","schema":{"format":"uuid","type":"string"}},{"name":"author_actor_id","required":false,"in":"query","schema":{"format":"uuid","type":"string"}},{"name":"parent_message_id","required":false,"in":"query","description":"Restrict to replies to this root message. Omit to search roots and replies.","schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageSearchPage"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input\n\nInvalid search query or cursor"},"401":{"description":"Missing, expired or revoked session"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible\n\nWorkspace not found or membership not accepted"}},"security":[{"bearer":[]}],"tags":["Search"]}},"/search/channels":{"get":{"operationId":"Search_listChannels","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"q","required":true,"in":"query","description":"Search text. Messages support words, quoted phrases, OR and exclusions. Channels and members match literal substrings, ignoring case.","schema":{"minLength":1,"maxLength":200,"type":"string"}},{"name":"cursor","required":false,"in":"query","description":"Opaque next_cursor from the same search. Results are ordered by ID descending (UUIDv7 creation order).","schema":{"maxLength":1000,"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"type":"integer"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChannelSearchPage"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input\n\nInvalid search query or cursor"},"401":{"description":"Missing, expired or revoked session"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible\n\nWorkspace not found or membership not accepted"}},"security":[{"bearer":[]}],"tags":["Search"]}},"/search/members":{"get":{"operationId":"Search_listMembers","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"q","required":true,"in":"query","description":"Search text. Messages support words, quoted phrases, OR and exclusions. Channels and members match literal substrings, ignoring case.","schema":{"minLength":1,"maxLength":200,"type":"string"}},{"name":"cursor","required":false,"in":"query","description":"Opaque next_cursor from the same search. Results are ordered by ID descending (UUIDv7 creation order).","schema":{"maxLength":1000,"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"type":"integer"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberSearchPage"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input\n\nInvalid search query or cursor"},"401":{"description":"Missing, expired or revoked session"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible\n\nWorkspace not found or membership not accepted"}},"security":[{"bearer":[]}],"tags":["Search"]}},"/workspace/invites":{"post":{"operationId":"WorkspaceInvites_create","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddWorkspaceUser"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IssuedWorkspaceInvite"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible"}},"security":[{"bearer":[]}],"tags":["Workspace invitations"]},"get":{"operationId":"WorkspaceInvites_list","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WorkspaceInvite"}}}}},"400":{"description":"Missing or invalid workspace header, or invalid input"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible"}},"security":[{"bearer":[]}],"tags":["Workspace invitations"]}},"/workspace/invites/{id}":{"delete":{"operationId":"WorkspaceInvites_revoke","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""},"400":{"description":"Missing or invalid workspace header, or invalid input"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible"}},"security":[{"bearer":[]}],"tags":["Workspace invitations"]}},"/invites/preview":{"post":{"operationId":"InviteAcceptance_preview","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InviteToken"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvitePreview"}}}}},"tags":["Workspace invitations"]}},"/invites/accept":{"post":{"operationId":"InviteAcceptance_accept","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InviteToken"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Workspace"}}}}},"security":[{"bearer":[]}],"tags":["Workspace invitations"]}},"/activity":{"get":{"operationId":"Activity_list","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"unread","required":false,"in":"query","schema":{"default":false,"type":"boolean"}},{"name":"cursor","required":false,"in":"query","description":"Use next_cursor from the previous page.","schema":{"format":"uuid","type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":40,"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivityPage"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible"}},"security":[{"bearer":[]}],"tags":["Activity"]}},"/activity/summary":{"get":{"operationId":"Activity_summary","parameters":[{"name":"X-Workspace-Id","in":"header","description":"Workspace context. Required for current user sessions. Future workspace-scoped credentials may omit it; if supplied, it must match the authenticated token scope.","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivitySummary"}}}},"400":{"description":"Missing or invalid workspace header, or invalid input"},"403":{"description":"Insufficient permissions or workspace header does not match token scope"},"404":{"description":"Workspace or resource not found or inaccessible"}},"security":[{"bearer":[]}],"tags":["Activity"]}},"/push/registration":{"put":{"operationId":"Push_update","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PushRegistration"}}}},"responses":{"204":{"description":"Register this authenticated session for mobile push"}},"security":[{"bearer":[]}],"tags":["Push"]},"delete":{"operationId":"Push_remove","parameters":[],"responses":{"204":{"description":"Disable push for this session only"}},"security":[{"bearer":[]}],"tags":["Push"]}},"/unread/summary":{"get":{"operationId":"Unread_summary","parameters":[],"responses":{"200":{"description":"Totals across all accessible workspaces for this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnreadSummary"}}}}},"security":[{"bearer":[]}],"tags":["Unread"]}}},"info":{"title":"Fryll API","description":"Email/password authentication, workspace identities, channels and messages. Workspace-scoped operations require X-Workspace-Id with current user sessions. No email verification.","version":"1.0.0","contact":{}},"tags":[],"servers":[],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http","description":"Opaque session token returned by registration or login"}},"schemas":{"RealtimeConfiguration":{"type":"object","properties":{"protocol_version":{"type":"number","enum":[2],"description":"Version 2 pushes personalized API objects on the actor channel."},"enabled":{"type":"boolean"},"key":{"type":"string"},"cluster":{"type":"string"},"actor_channel":{"type":"string"},"workspace_channel":{"type":"string"}},"required":["protocol_version","enabled","key","cluster","actor_channel","workspace_channel"]},"AuthorizeRealtime":{"type":"object","properties":{"channel_name":{"type":"string","maxLength":164},"socket_id":{"type":"string","maxLength":100,"pattern":"^\\d+\\.\\d+$"}},"required":["channel_name","socket_id"]},"RealtimeAuthorization":{"type":"object","properties":{"auth":{"type":"string"}},"required":["auth"]},"RealtimeSocket":{"type":"object","properties":{"socket_id":{"type":"string","maxLength":100,"pattern":"^\\d+\\.\\d+$"}},"required":["socket_id"]},"RealtimeUserAuthorization":{"type":"object","properties":{"auth":{"type":"string"},"user_data":{"type":"string"}},"required":["auth","user_data"]},"ActorPresence":{"type":"object","properties":{"workspace_actor_id":{"type":"string","format":"uuid"},"is_online":{"type":"boolean","nullable":true,"description":"True when any device is connected; false when none are connected; null if unknown or last observation is older than 90 seconds."},"last_seen_at":{"type":"string","nullable":true,"format":"date-time"},"presence_observed_at":{"type":"string","nullable":true,"format":"date-time"}},"required":["workspace_actor_id","is_online","last_seen_at","presence_observed_at"]},"WorkspaceActor":{"type":"object","properties":{"id":{"type":"string","format":"uuid","readOnly":true,"description":"New records use UUID v7"},"created_at":{"type":"string","format":"date-time","readOnly":true},"updated_at":{"type":"string","format":"date-time","readOnly":true},"workspace_id":{"type":"string","format":"uuid"},"kind":{"enum":["user","agent"],"type":"string"},"workspace_user_id":{"type":"string","nullable":true,"format":"uuid"},"is_online":{"type":"boolean","nullable":true,"readOnly":true,"description":"Connected on at least one device. Null when presence has not been observed or is stale. Separate from activity or custom status."},"last_seen_at":{"type":"string","nullable":true,"format":"date-time","readOnly":true},"presence_observed_at":{"type":"string","nullable":true,"format":"date-time","readOnly":true,"description":"Last successful Pusher observation; expires after 90 seconds."},"avatar_id":{"type":"string","nullable":true,"format":"uuid","readOnly":true,"description":"Current avatar version; use the avatar upload endpoint to change it."},"display_name":{"type":"string","nullable":true,"minLength":1,"maxLength":200,"description":"Workspace display name. Null uses the account name for people or the agent name for agents."},"bio":{"type":"string","nullable":true,"minLength":1,"maxLength":1000,"description":"Biography visible in this workspace."},"position":{"type":"string","nullable":true,"minLength":1,"maxLength":120,"description":"Position or responsibility in this workspace."},"status_text":{"type":"string","nullable":true,"minLength":1,"maxLength":100,"description":"Custom status, separate from online presence."},"status_emoji":{"type":"string","nullable":true,"minLength":1,"maxLength":32},"agent_name":{"type":"string","nullable":true,"description":"The name an agent posts under; null for people.","example":"Triage"},"agent_handle":{"type":"string","nullable":true,"description":"The agent's lowercase handle; null for people.","example":"triage"}},"required":["id","created_at","updated_at","workspace_id","kind","workspace_user_id","is_online","last_seen_at","presence_observed_at","avatar_id","display_name","bio","position","status_text","status_emoji","agent_name","agent_handle"]},"UpdateActorProfile":{"type":"object","properties":{"display_name":{"type":"string","nullable":true,"minLength":1,"maxLength":200,"description":"Workspace display name. Null uses the account name for people or the agent name for agents."},"bio":{"type":"string","nullable":true,"minLength":1,"maxLength":1000,"description":"Biography visible in this workspace."},"position":{"type":"string","nullable":true,"minLength":1,"maxLength":120,"description":"Position or responsibility in this workspace."},"status_text":{"type":"string","nullable":true,"minLength":1,"maxLength":100,"description":"Custom status, separate from online presence."},"status_emoji":{"type":"string","nullable":true,"minLength":1,"maxLength":32}}},"AssetDownload":{"type":"object","properties":{"url":{"type":"string","description":"Signed CDN URL. Authorize again after expiry; never persist this URL."},"expires_at":{"type":"string","format":"date-time"}},"required":["url","expires_at"]},"AddWorkspaceUser":{"type":"object","properties":{"email":{"type":"string","maxLength":254,"format":"email"}},"required":["email"]},"WorkspaceUser":{"type":"object","properties":{"id":{"type":"string","format":"uuid","readOnly":true,"description":"New records use UUID v7"},"created_at":{"type":"string","format":"date-time","readOnly":true},"updated_at":{"type":"string","format":"date-time","readOnly":true},"workspace_id":{"type":"string","format":"uuid"},"user_id":{"type":"string","nullable":true,"format":"uuid"},"email":{"type":"string","format":"email"},"first_name":{"type":"string","nullable":true},"last_name":{"type":"string","nullable":true},"status":{"enum":["pending","accepted","removed"],"type":"string"},"role":{"enum":["owner","admin","member"],"type":"string"}},"required":["id","created_at","updated_at","workspace_id","user_id","email","first_name","last_name","status","role"]},"UpdateWorkspaceUserRole":{"type":"object","properties":{"role":{"type":"string","enum":["admin","member"]}},"required":["role"]},"SavedMessageState":{"type":"object","properties":{"saved_at":{"type":"string","nullable":true,"format":"date-time","description":"When the caller saved this message; null when not saved."}},"required":["saved_at"]},"MessageReaction":{"type":"object","properties":{"emoji":{"type":"string","example":"👍"},"actor_ids":{"description":"Workspace actor IDs, including the current actor if they reacted.","type":"array","items":{"type":"string"}}},"required":["emoji","actor_ids"]},"MessageReactions":{"type":"object","properties":{"reactions":{"type":"array","items":{"$ref":"#/components/schemas/MessageReaction"}},"reactions_version":{"type":"number","minimum":0,"description":"Monotonically increasing cache version for this message."}},"required":["reactions","reactions_version"]},"CreateMessage":{"type":"object","properties":{"body_text":{"type":"string","minLength":1,"maxLength":40000,"pattern":"\\S","description":"Plain-text content and preview/fallback for children."},"children":{"type":"array","maxItems":32,"description":"Optional message UI. Replaces the whole array on edit; [] clears it. At most 32 components and 40,000 combined characters, including info labels and children. Info contains text only and appears beside the preceding component. Loading expires 30 minutes after a children update.","items":{"oneOf":[{"type":"object","required":["type","text"],"additionalProperties":false,"properties":{"type":{"type":"string","enum":["text"]},"text":{"type":"string","minLength":1,"maxLength":40000}}},{"type":"object","required":["type","label"],"additionalProperties":false,"properties":{"type":{"type":"string","enum":["loading"]},"label":{"type":"string","minLength":1,"maxLength":200},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$","description":"Spinner/dot color. Defaults to the client accent; label uses the normal readable text color.","example":"#6366F1"}}},{"type":"object","required":["type","label","children"],"additionalProperties":false,"properties":{"type":{"type":"string","enum":["info"]},"label":{"type":"string","minLength":1,"maxLength":200,"description":"Accessible button label and popover heading."},"children":{"type":"array","minItems":1,"maxItems":31,"items":{"type":"object","required":["type","text"],"additionalProperties":false,"properties":{"type":{"type":"string","enum":["text"]},"text":{"type":"string","minLength":1,"maxLength":40000}}}}}}]}},"mentioned_actor_ids":{"uniqueItems":true,"maxItems":100,"type":"array","items":{"type":"string","format":"uuid"}},"asset_ids":{"uniqueItems":true,"maxItems":10,"type":"array","items":{"type":"string","format":"uuid"}},"parent_message_id":{"type":"string","nullable":true,"format":"uuid","description":"Root message ID for a thread reply; omit for a channel message."},"idempotency_key":{"type":"string","format":"uuid"}}},"AssetStatus":{"type":"string","enum":["pending","ready"]},"AssetPreviewKind":{"type":"string","enum":["image","text","file"]},"Asset":{"type":"object","properties":{"id":{"type":"string","format":"uuid","readOnly":true,"description":"New records use UUID v7"},"created_at":{"type":"string","format":"date-time","readOnly":true},"updated_at":{"type":"string","format":"date-time","readOnly":true},"conversation_id":{"type":"string","format":"uuid"},"message_id":{"type":"string","nullable":true,"format":"uuid"},"name":{"type":"string"},"size_bytes":{"type":"number"},"content_type":{"type":"string"},"status":{"allOf":[{"$ref":"#/components/schemas/AssetStatus"}]},"preview_kind":{"allOf":[{"$ref":"#/components/schemas/AssetPreviewKind"}]}},"required":["id","created_at","updated_at","conversation_id","message_id","name","size_bytes","content_type","status","preview_kind"]},"Message":{"type":"object","properties":{"id":{"type":"string","format":"uuid","readOnly":true,"description":"New records use UUID v7"},"created_at":{"type":"string","format":"date-time","readOnly":true},"updated_at":{"type":"string","format":"date-time","readOnly":true},"children":{"type":"array","maxItems":32,"description":"Optional message UI. Replaces the whole array on edit; [] clears it. At most 32 components and 40,000 combined characters, including info labels and children. Info contains text only and appears beside the preceding component. Loading expires 30 minutes after a children update.","items":{"oneOf":[{"type":"object","required":["type","text"],"additionalProperties":false,"properties":{"type":{"type":"string","enum":["text"]},"text":{"type":"string","minLength":1,"maxLength":40000}}},{"type":"object","required":["type","label"],"additionalProperties":false,"properties":{"type":{"type":"string","enum":["loading"]},"label":{"type":"string","minLength":1,"maxLength":200},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$","description":"Spinner/dot color. Defaults to the client accent; label uses the normal readable text color.","example":"#6366F1"}}},{"type":"object","required":["type","label","children"],"additionalProperties":false,"properties":{"type":{"type":"string","enum":["info"]},"label":{"type":"string","minLength":1,"maxLength":200,"description":"Accessible button label and popover heading."},"children":{"type":"array","minItems":1,"maxItems":31,"items":{"type":"object","required":["type","text"],"additionalProperties":false,"properties":{"type":{"type":"string","enum":["text"]},"text":{"type":"string","minLength":1,"maxLength":40000}}}}}}]}},"loading_expires_at":{"type":"string","nullable":true,"format":"date-time","readOnly":true,"description":"UTC expiry for loading indicators. Null when no loading component is present."},"saved_at":{"type":"string","nullable":true,"format":"date-time","description":"The caller’s private save timestamp; null when not saved."},"reply_count":{"type":"number","minimum":0,"readOnly":true,"description":"Number of non-deleted replies to this message. Zero for replies."},"reply_actor_ids":{"maxItems":4,"readOnly":true,"description":"First four distinct authors of non-deleted replies, in participation order.","type":"array","items":{"type":"string"}},"last_reply_at":{"type":"string","nullable":true,"format":"date-time","readOnly":true},"reactions":{"description":"Cached reactions; empty when nobody has reacted.","type":"array","items":{"$ref":"#/components/schemas/MessageReaction"}},"reactions_version":{"type":"number","minimum":0},"assets":{"type":"array","items":{"$ref":"#/components/schemas/Asset"}},"workspace_id":{"type":"string","format":"uuid"},"conversation_id":{"type":"string","format":"uuid"},"author_actor_id":{"type":"string","nullable":true,"format":"uuid","description":"Author actor; null if their workspace identity was removed."},"body_text":{"type":"string","nullable":true,"description":"Plain text, preserved as sent; null after deletion."},"mentioned_actor_ids":{"nullable":true,"description":"Mentioned workspace actor IDs captured at write time. Null only for legacy messages awaiting backfill.","type":"array","items":{"type":"string"}},"parent_message_id":{"type":"string","nullable":true,"format":"uuid"},"edited_at":{"type":"string","nullable":true,"format":"date-time","readOnly":true},"deleted_at":{"type":"string","nullable":true,"format":"date-time","readOnly":true}},"required":["id","created_at","updated_at","children","loading_expires_at","saved_at","reply_count","reactions","reactions_version","assets","workspace_id","conversation_id","author_actor_id","body_text","mentioned_actor_ids","parent_message_id","edited_at","deleted_at"]},"MessagePage":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Message"}},"next_cursor":{"type":"string","nullable":true,"format":"uuid"}},"required":["items","next_cursor"]},"UpdateMessage":{"type":"object","properties":{"body_text":{"type":"string","minLength":1,"maxLength":40000,"pattern":"\\S","description":"Plain-text content and preview/fallback for children."},"children":{"type":"array","maxItems":32,"description":"Optional message UI. Replaces the whole array on edit; [] clears it. At most 32 components and 40,000 combined characters, including info labels and children. Info contains text only and appears beside the preceding component. Loading expires 30 minutes after a children update.","items":{"oneOf":[{"type":"object","required":["type","text"],"additionalProperties":false,"properties":{"type":{"type":"string","enum":["text"]},"text":{"type":"string","minLength":1,"maxLength":40000}}},{"type":"object","required":["type","label"],"additionalProperties":false,"properties":{"type":{"type":"string","enum":["loading"]},"label":{"type":"string","minLength":1,"maxLength":200},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$","description":"Spinner/dot color. Defaults to the client accent; label uses the normal readable text color.","example":"#6366F1"}}},{"type":"object","required":["type","label","children"],"additionalProperties":false,"properties":{"type":{"type":"string","enum":["info"]},"label":{"type":"string","minLength":1,"maxLength":200,"description":"Accessible button label and popover heading."},"children":{"type":"array","minItems":1,"maxItems":31,"items":{"type":"object","required":["type","text"],"additionalProperties":false,"properties":{"type":{"type":"string","enum":["text"]},"text":{"type":"string","minLength":1,"maxLength":40000}}}}}}]}},"mentioned_actor_ids":{"uniqueItems":true,"maxItems":100,"type":"array","items":{"type":"string","format":"uuid"}}}},"SavedMessage":{"type":"object","properties":{"saved_at":{"type":"string","format":"date-time"},"message":{"$ref":"#/components/schemas/Message"}},"required":["saved_at","message"]},"SavedMessagePage":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/SavedMessage"}},"next_cursor":{"type":"string","nullable":true}},"required":["items","next_cursor"]},"CreateAsset":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":255,"pattern":"^[^/\\\\\\x00-\\x1f\\x7f]+$"},"size_bytes":{"type":"number","minimum":0,"maximum":10485760}},"required":["name","size_bytes"]},"CreateChannel":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":80,"pattern":"^[a-z0-9]+(-[a-z0-9]+)*$","example":"general","description":"Lowercased and trimmed; letters, numbers and single separating hyphens."},"description":{"type":"string","nullable":true,"maxLength":1000},"visibility":{"default":"public","enum":["public","private"],"type":"string"}},"required":["name"]},"Channel":{"type":"object","properties":{"id":{"type":"string","format":"uuid","readOnly":true,"description":"New records use UUID v7"},"created_at":{"type":"string","format":"date-time","readOnly":true},"updated_at":{"type":"string","format":"date-time","readOnly":true},"conversation_id":{"type":"string","format":"uuid"},"unread_message_count":{"type":"number","minimum":0,"description":"Unread messages from other actors after the read cursor; excludes deleted messages."},"unread_thread_count":{"type":"number","minimum":0,"description":"Followed threads with unread replies for the authenticated actor."},"workspace_id":{"type":"string","format":"uuid"},"description":{"type":"string","nullable":true},"visibility":{"enum":["public","private"],"type":"string"},"created_by":{"type":"string","nullable":true,"format":"uuid","description":"Creator workspace actor; null if the actor was removed."},"has_unread_messages":{"type":"boolean"},"name":{"type":"string"}},"required":["id","created_at","updated_at","conversation_id","unread_message_count","unread_thread_count","workspace_id","description","visibility","created_by","has_unread_messages","name"]},"ConversationReadState":{"type":"object","properties":{"conversation_id":{"type":"string","format":"uuid"},"workspace_actor_id":{"type":"string","format":"uuid"},"thread_root_id":{"type":"string","nullable":true,"format":"uuid"},"last_read_message_id":{"type":"string","nullable":true,"format":"uuid","description":"Null when no explicit acknowledgement was recorded, including a join-time baseline."},"unread_message_count":{"type":"number","minimum":0,"description":"Unread messages from other actors after the read cursor; excludes deleted messages."},"is_following":{"type":"boolean"},"has_unread_messages":{"type":"boolean"}},"required":["conversation_id","workspace_actor_id","thread_root_id","last_read_message_id","unread_message_count","is_following","has_unread_messages"]},"UpdateReadState":{"type":"object","properties":{"last_read_message_id":{"type":"string","format":"uuid","description":"Last displayed message. Acknowledgements only advance; GET requests never mark messages read."}},"required":["last_read_message_id"]},"UpdateThreadSubscription":{"type":"object","properties":{"is_following":{"type":"boolean"}},"required":["is_following"]},"Thread":{"type":"object","properties":{"root":{"$ref":"#/components/schemas/Message"},"reply_count":{"type":"number","minimum":0},"last_reply_at":{"type":"string","nullable":true,"format":"date-time"},"is_following":{"type":"boolean"},"has_unread_messages":{"type":"boolean"}},"required":["root","reply_count","last_reply_at","is_following","has_unread_messages"]},"ThreadPage":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Thread"}},"next_cursor":{"type":"string","nullable":true,"format":"uuid"}},"required":["items","next_cursor"]},"User":{"type":"object","properties":{"id":{"type":"string","format":"uuid","readOnly":true,"description":"New records use UUID v7"},"created_at":{"type":"string","format":"date-time","readOnly":true},"updated_at":{"type":"string","format":"date-time","readOnly":true},"email":{"type":"string","format":"email"},"first_name":{"type":"string","nullable":true,"minLength":1,"maxLength":100},"last_name":{"type":"string","nullable":true,"minLength":1,"maxLength":100}},"required":["id","created_at","updated_at","email","first_name","last_name"]},"AuthResponse":{"type":"object","properties":{"access_token":{"type":"string","description":"Opaque session token. Send as Authorization: Bearer <access_token>."},"token_type":{"enum":["Bearer"],"type":"string"},"expires_at":{"type":"string","nullable":true,"format":"date-time","description":"Null means the session remains valid until explicitly revoked."},"user":{"$ref":"#/components/schemas/User"}},"required":["access_token","token_type","expires_at","user"]},"EmailVerified":{"type":"object","properties":{"verified":{"type":"boolean","enum":[true]},"email":{"type":"string","format":"email"}},"required":["verified","email"]},"Register":{"type":"object","properties":{"first_name":{"type":"string","nullable":true,"minLength":1,"maxLength":100},"last_name":{"type":"string","nullable":true,"minLength":1,"maxLength":100},"invite_token":{"type":"string","pattern":"^[A-Za-z0-9_-]{43}$","writeOnly":true},"password":{"type":"string","minLength":12,"maxLength":128,"format":"password","writeOnly":true},"email":{"type":"string","maxLength":254,"format":"email"}},"required":["password","email"]},"EmailPending":{"type":"object","properties":{"email_sent":{"type":"boolean","enum":[true]}},"required":["email_sent"]},"EmailLink":{"type":"object","properties":{"first_name":{"type":"string","nullable":true,"minLength":1,"maxLength":100},"last_name":{"type":"string","nullable":true,"minLength":1,"maxLength":100},"invite_token":{"type":"string","pattern":"^[A-Za-z0-9_-]{43}$","writeOnly":true},"email":{"type":"string","maxLength":254,"format":"email"}},"required":["email"]},"RecoverAccount":{"type":"object","properties":{"email":{"type":"string","maxLength":254,"format":"email"}},"required":["email"]},"ResetPassword":{"type":"object","properties":{"token":{"type":"string","pattern":"^[A-Za-z0-9_-]{43}$","writeOnly":true},"password":{"type":"string","minLength":12,"maxLength":128,"format":"password","writeOnly":true}},"required":["token","password"]},"PasswordReset":{"type":"object","properties":{"reset":{"type":"boolean","enum":[true]},"user_id":{"type":"string","format":"uuid"},"email":{"type":"string","format":"email"}},"required":["reset","user_id","email"]},"EmailCodePending":{"type":"object","properties":{"email_sent":{"type":"boolean","enum":[true]},"challenge_id":{"type":"string","description":"Opaque challenge bound to this code request."}},"required":["email_sent","challenge_id"]},"VerifyEmailCode":{"type":"object","properties":{"challenge_id":{"type":"string","pattern":"^[A-Za-z0-9_-]{43}$","writeOnly":true},"code":{"type":"string","pattern":"^\\d{6}$","writeOnly":true,"example":"123456"}},"required":["challenge_id","code"]},"VerifyEmail":{"type":"object","properties":{"token":{"type":"string","minLength":43,"maxLength":43,"writeOnly":true}},"required":["token"]},"Login":{"type":"object","properties":{"password":{"type":"string","minLength":1,"maxLength":128,"format":"password","writeOnly":true},"email":{"type":"string","maxLength":254,"format":"email"}},"required":["password","email"]},"UpdateUser":{"type":"object","properties":{"first_name":{"type":"string","nullable":true,"minLength":1,"maxLength":100},"last_name":{"type":"string","nullable":true,"minLength":1,"maxLength":100}},"description":"Update your account name. At least one name must remain nonblank. A single full name can be stored in first_name with last_name null."},"CreateWorkspace":{"type":"object","properties":{"slug":{"type":"string","minLength":3,"maxLength":63,"pattern":"^[a-z0-9]+(-[a-z0-9]+)*$","example":"my-team","description":"Lowercased and trimmed; letters, numbers and single hyphens only."},"name":{"type":"string","minLength":1,"maxLength":100}},"required":["slug","name"]},"Workspace":{"type":"object","properties":{"id":{"type":"string","format":"uuid","readOnly":true,"description":"New records use UUID v7"},"created_at":{"type":"string","format":"date-time","readOnly":true},"updated_at":{"type":"string","format":"date-time","readOnly":true},"avatar_id":{"type":"string","nullable":true,"format":"uuid","readOnly":true,"description":"Current workspace avatar version; change it through the avatar endpoint."},"name":{"type":"string"},"slug":{"type":"string"}},"required":["id","created_at","updated_at","avatar_id","name","slug"]},"UpdateWorkspace":{"type":"object","properties":{"slug":{"type":"string","minLength":3,"maxLength":63,"pattern":"^[a-z0-9]+(-[a-z0-9]+)*$","example":"my-team","description":"Lowercased and trimmed; letters, numbers and single hyphens only."},"name":{"type":"string","minLength":1,"maxLength":100}}},"TransferWorkspaceOwnership":{"type":"object","properties":{"workspace_user_id":{"type":"string","format":"uuid"}},"required":["workspace_user_id"]},"AddChannelMember":{"type":"object","properties":{"workspace_actor_id":{"type":"string","format":"uuid"}},"required":["workspace_actor_id"]},"ChannelMember":{"type":"object","properties":{"id":{"type":"string","format":"uuid","readOnly":true,"description":"New records use UUID v7"},"created_at":{"type":"string","format":"date-time","readOnly":true},"updated_at":{"type":"string","format":"date-time","readOnly":true},"workspace_id":{"type":"string","format":"uuid"},"channel_id":{"type":"string","format":"uuid"},"workspace_actor_id":{"type":"string","format":"uuid"}},"required":["id","created_at","updated_at","workspace_id","channel_id","workspace_actor_id"]},"DirectConversation":{"type":"object","properties":{"id":{"type":"string","format":"uuid","readOnly":true,"description":"New records use UUID v7"},"created_at":{"type":"string","format":"date-time","readOnly":true},"updated_at":{"type":"string","format":"date-time","readOnly":true},"workspace_id":{"type":"string","format":"uuid"},"conversation_id":{"type":"string","format":"uuid"},"actor_low_id":{"type":"string","format":"uuid"},"actor_high_id":{"type":"string","format":"uuid","description":"Equals actor_low_id for a single-member self conversation."},"last_message_at":{"type":"string","nullable":true,"format":"date-time"},"unread_message_count":{"type":"number","minimum":0,"description":"Unread messages from other actors after the read cursor; excludes deleted messages."},"unread_thread_count":{"type":"number","minimum":0},"has_unread_messages":{"type":"boolean"}},"required":["id","created_at","updated_at","workspace_id","conversation_id","actor_low_id","actor_high_id","last_message_at","unread_message_count","unread_thread_count","has_unread_messages"]},"CreateDirectConversation":{"type":"object","properties":{"workspace_actor_id":{"type":"string","format":"uuid","description":"An active workspace actor, including your own actor for notes to self. The caller is resolved from authentication."}},"required":["workspace_actor_id"]},"ConversationToken":{"type":"object","properties":{"conversation_id":{"type":"string","format":"uuid"},"hint":{"type":"string","description":"The last four characters of the token, to tell tokens apart."},"created_at":{"type":"string","format":"date-time","readOnly":true,"description":"When this token was issued."},"last_used_at":{"type":"string","nullable":true,"format":"date-time","readOnly":true}},"required":["conversation_id","hint","created_at","last_used_at"]},"IssuedConversationToken":{"type":"object","properties":{"conversation_id":{"type":"string","format":"uuid"},"hint":{"type":"string","description":"The last four characters of the token, to tell tokens apart."},"created_at":{"type":"string","format":"date-time","readOnly":true,"description":"When this token was issued."},"last_used_at":{"type":"string","nullable":true,"format":"date-time","readOnly":true},"token":{"type":"string","description":"The token itself. It is shown only once; issue a new one if it is lost, which revokes this one.","example":"fry_9xWq2mF4dKp7LrT1vNc8BzYh3sJ6eQaU0gXiOlVkR5w"},"path":{"type":"string","description":"Where to send messages, relative to the API origin. POST plain text, a form field named text, or JSON.","example":"/in/fry_9xWq2mF4dKp7LrT1vNc8BzYh3sJ6eQaU0gXiOlVkR5w"}},"required":["conversation_id","hint","created_at","last_used_at","token","path"]},"InboundAgent":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The agent workspace actor used as author_actor_id."},"name":{"type":"string","example":"Triage"},"handle":{"type":"string","example":"triage","description":"Normalized name used to find the agent again."}},"required":["id","name","handle"]},"InboundMessage":{"type":"object","properties":{"id":{"type":"string","format":"uuid","readOnly":true,"description":"New records use UUID v7"},"created_at":{"type":"string","format":"date-time","readOnly":true},"updated_at":{"type":"string","format":"date-time","readOnly":true},"children":{"type":"array","maxItems":32,"description":"Optional message UI. Replaces the whole array on edit; [] clears it. At most 32 components and 40,000 combined characters, including info labels and children. Info contains text only and appears beside the preceding component. Loading expires 30 minutes after a children update.","items":{"oneOf":[{"type":"object","required":["type","text"],"additionalProperties":false,"properties":{"type":{"type":"string","enum":["text"]},"text":{"type":"string","minLength":1,"maxLength":40000}}},{"type":"object","required":["type","label"],"additionalProperties":false,"properties":{"type":{"type":"string","enum":["loading"]},"label":{"type":"string","minLength":1,"maxLength":200},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$","description":"Spinner/dot color. Defaults to the client accent; label uses the normal readable text color.","example":"#6366F1"}}},{"type":"object","required":["type","label","children"],"additionalProperties":false,"properties":{"type":{"type":"string","enum":["info"]},"label":{"type":"string","minLength":1,"maxLength":200,"description":"Accessible button label and popover heading."},"children":{"type":"array","minItems":1,"maxItems":31,"items":{"type":"object","required":["type","text"],"additionalProperties":false,"properties":{"type":{"type":"string","enum":["text"]},"text":{"type":"string","minLength":1,"maxLength":40000}}}}}}]}},"loading_expires_at":{"type":"string","nullable":true,"format":"date-time","readOnly":true,"description":"UTC expiry for loading indicators. Null when no loading component is present."},"saved_at":{"type":"string","nullable":true,"format":"date-time","description":"The caller’s private save timestamp; null when not saved."},"reply_count":{"type":"number","minimum":0,"readOnly":true,"description":"Number of non-deleted replies to this message. Zero for replies."},"reply_actor_ids":{"maxItems":4,"readOnly":true,"description":"First four distinct authors of non-deleted replies, in participation order.","type":"array","items":{"type":"string"}},"last_reply_at":{"type":"string","nullable":true,"format":"date-time","readOnly":true},"reactions":{"description":"Cached reactions; empty when nobody has reacted.","type":"array","items":{"$ref":"#/components/schemas/MessageReaction"}},"reactions_version":{"type":"number","minimum":0},"assets":{"type":"array","items":{"$ref":"#/components/schemas/Asset"}},"workspace_id":{"type":"string","format":"uuid"},"conversation_id":{"type":"string","format":"uuid"},"author_actor_id":{"type":"string","nullable":true,"format":"uuid","description":"Author actor; null if their workspace identity was removed."},"body_text":{"type":"string","nullable":true,"description":"Plain text, preserved as sent; null after deletion."},"mentioned_actor_ids":{"nullable":true,"description":"Mentioned workspace actor IDs captured at write time. Null only for legacy messages awaiting backfill.","type":"array","items":{"type":"string"}},"parent_message_id":{"type":"string","nullable":true,"format":"uuid"},"edited_at":{"type":"string","nullable":true,"format":"date-time","readOnly":true},"deleted_at":{"type":"string","nullable":true,"format":"date-time","readOnly":true},"agent":{"nullable":true,"description":"The optional sender override; null when posted as the token owner.","type":"object","allOf":[{"$ref":"#/components/schemas/InboundAgent"}]}},"required":["id","created_at","updated_at","children","loading_expires_at","saved_at","reply_count","reactions","reactions_version","assets","workspace_id","conversation_id","author_actor_id","body_text","mentioned_actor_ids","parent_message_id","edited_at","deleted_at","agent"]},"MessageSearchResult":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"conversation_id":{"type":"string","format":"uuid"},"author_actor_id":{"type":"string","nullable":true,"format":"uuid"},"parent_message_id":{"type":"string","nullable":true,"format":"uuid"},"body_text":{"type":"string","description":"Plain text; render as text, never as HTML."},"created_at":{"type":"string","format":"date-time"}},"required":["id","conversation_id","author_actor_id","parent_message_id","body_text","created_at"]},"MessageSearchPage":{"type":"object","properties":{"next_cursor":{"type":"string","nullable":true,"description":"Opaque cursor; null when there are no more results."},"items":{"type":"array","items":{"$ref":"#/components/schemas/MessageSearchResult"}}},"required":["next_cursor","items"]},"ChannelSearchResult":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"conversation_id":{"type":"string","format":"uuid"},"description":{"type":"string","nullable":true},"visibility":{"enum":["public","private"],"type":"string"},"name":{"type":"string"}},"required":["id","conversation_id","description","visibility","name"]},"ChannelSearchPage":{"type":"object","properties":{"next_cursor":{"type":"string","nullable":true,"description":"Opaque cursor; null when there are no more results."},"items":{"type":"array","items":{"$ref":"#/components/schemas/ChannelSearchResult"}}},"required":["next_cursor","items"]},"MemberSearchResult":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Workspace user ID."},"workspace_actor_id":{"type":"string","format":"uuid"},"display_name":{"type":"string","nullable":true,"description":"Workspace profile name."},"first_name":{"type":"string","nullable":true},"last_name":{"type":"string","nullable":true},"email":{"type":"string","format":"email"}},"required":["id","workspace_actor_id","display_name","first_name","last_name","email"]},"MemberSearchPage":{"type":"object","properties":{"next_cursor":{"type":"string","nullable":true,"description":"Opaque cursor; null when there are no more results."},"items":{"type":"array","items":{"$ref":"#/components/schemas/MemberSearchResult"}}},"required":["next_cursor","items"]},"IssuedWorkspaceInvite":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"email":{"type":"string","format":"email"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"url":{"type":"string","description":"Recipient-specific invitation URL. Only returned when issued."}},"required":["id","email","created_at","expires_at","url"]},"WorkspaceInvite":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"email":{"type":"string","format":"email"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"}},"required":["id","email","created_at","expires_at"]},"InviteToken":{"type":"object","properties":{"token":{"type":"string","pattern":"^[A-Za-z0-9_-]{43}$","writeOnly":true}},"required":["token"]},"InvitePreview":{"type":"object","properties":{"workspace_name":{"type":"string"},"workspace_slug":{"type":"string"},"email":{"type":"string","format":"email"},"expires_at":{"format":"date-time","type":"string"}},"required":["workspace_name","workspace_slug","email","expires_at"]},"ActivityItem":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"kind":{"enum":["mention","reply"],"type":"string"},"message":{"$ref":"#/components/schemas/Message"},"is_unread":{"type":"boolean"}},"required":["id","kind","message","is_unread"]},"ActivityPage":{"type":"object","properties":{"unread_count":{"type":"number","minimum":0},"items":{"type":"array","items":{"$ref":"#/components/schemas/ActivityItem"}},"next_cursor":{"type":"string","nullable":true,"format":"uuid"}},"required":["unread_count","items","next_cursor"]},"ActivitySummary":{"type":"object","properties":{"unread_count":{"type":"number","minimum":0}},"required":["unread_count"]},"PushPlatform":{"type":"string","enum":["ios","android"]},"PushRegistration":{"type":"object","properties":{"installation_id":{"type":"string","format":"uuid"},"token":{"type":"string","minLength":20,"maxLength":4096},"platform":{"allOf":[{"$ref":"#/components/schemas/PushPlatform"}]},"project_id":{"type":"string","minLength":1,"maxLength":100,"description":"Firebase project configured in this app build"},"account_id":{"type":"string","minLength":1,"maxLength":500,"description":"Opaque local account identifier returned in notification taps"}},"required":["installation_id","token","platform","project_id","account_id"]},"UnreadSummary":{"type":"object","properties":{"activity_unread_count":{"type":"integer","minimum":0},"unread_dm_count":{"type":"integer","minimum":0,"description":"Unread DM conversations, not individual messages"},"badge_count":{"type":"integer","minimum":0,"description":"Unread Activity items plus unread DM conversations"}},"required":["activity_unread_count","unread_dm_count","badge_count"]}}}}