{"openapi":"3.1.0","info":{"title":"LearnHouse","description":"LearnHouse is an open-source platform tailored for learning experiences.","version":"1.3.1"},"paths":{"/content/{file_path}":{"get":{"summary":"Serve a content file","description":"Streams a content file (videos, PDFs, images, etc.) from S3 storage. Supports HTTP Range requests for video/audio seeking. Access is enforced based on the path prefix: activity and podcast episode content require authentication and org membership for non-public resources, while course metadata and org branding are public.","operationId":"serve_content_file_content__file_path__get","parameters":[{"name":"file_path","in":"path","required":true,"schema":{"type":"string","title":"File Path"}}],"responses":{"200":{"description":"File streamed successfully","content":{"application/json":{"schema":{}}}},"206":{"description":"Partial content returned for a Range request"},"400":{"description":"Invalid or unsafe file path"},"401":{"description":"Authentication required to access this file"},"403":{"description":"User is not permitted to access this file"},"404":{"description":"File not found in storage"},"500":{"description":"Storage backend is not configured"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"head":{"summary":"Get content file metadata","description":"Returns metadata for a content file without the body. Used by clients to probe file size, MIME type, and Range support before issuing a GET.","operationId":"head_content_file_content__file_path__head","parameters":[{"name":"file_path","in":"path","required":true,"schema":{"type":"string","title":"File Path"}}],"responses":{"200":{"description":"File metadata returned via response headers","content":{"application/json":{"schema":{}}}},"400":{"description":"Invalid or unsafe file path"},"401":{"description":"Authentication required to access this file"},"403":{"description":"User is not permitted to access this file"},"404":{"description":"File not found in storage"},"500":{"description":"Storage backend is not configured"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/users/profile":{"get":{"tags":["users"],"summary":"Get current user profile","description":"Return the currently authenticated user, or an anonymous user object if no session is present.","operationId":"api_get_current_user_api_v1_users_profile_get","responses":{"200":{"description":"Current user profile (public or anonymous).","content":{"application/json":{"schema":{}}}}}}},"/api/v1/users/session":{"get":{"tags":["users"],"summary":"Get current user session","description":"Return the full session for the current user, including org memberships and roles. Cached in Redis for up to 10 minutes per user.","operationId":"api_get_current_user_session_api_v1_users_session_get","responses":{"200":{"description":"Full session info for the current user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserSession"}}}}}}},"/api/v1/users/authorize/ressource/{ressource_uuid}/action/{action}":{"get":{"tags":["users"],"summary":"Check authorization for resource action","description":"Check whether the current user is authorized to perform the given action (create/read/update/delete) on a specific resource.","operationId":"api_get_authorization_status_api_v1_users_authorize_ressource__ressource_uuid__action__action__get","parameters":[{"name":"ressource_uuid","in":"path","required":true,"schema":{"type":"string","title":"Ressource Uuid"}},{"name":"action","in":"path","required":true,"schema":{"enum":["create","read","update","delete"],"type":"string","title":"Action"}}],"responses":{"200":{"description":"Authorization decision for the requested resource and action.","content":{"application/json":{"schema":{}}}},"404":{"description":"Resource not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/users/{org_id}":{"post":{"tags":["users","users"],"summary":"Create user in organization","description":"Create a user and attach them to the given organization. Rejected if the organization is invite-only — use the invite-code endpoint instead.","operationId":"api_create_user_with_orgid_api_v1_users__org_id__post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserCreate"}}}},"responses":{"200":{"description":"User created and attached to the organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserRead"}}}},"403":{"description":"Organization is invite-only; an invite code is required"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/users/{org_id}/invite/{invite_code}":{"post":{"tags":["users","users"],"summary":"Create user with invite code","description":"Create a user and attach them to the given organization using an invite code. Only valid when the organization is configured as invite-only.","operationId":"api_create_user_with_orgid_and_invite_api_v1_users__org_id__invite__invite_code__post","parameters":[{"name":"invite_code","in":"path","required":true,"schema":{"type":"string","title":"Invite Code"}},{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserCreate"}}}},"responses":{"200":{"description":"User created and attached via invite code.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserRead"}}}},"403":{"description":"Organization does not require an invite code"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/users/":{"post":{"tags":["users","users"],"summary":"Create user without organization","description":"Create a user account that is not attached to any organization at creation time.","operationId":"api_create_user_without_org_api_v1_users__post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserCreate"}}},"required":true},"responses":{"200":{"description":"User account created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserRead"}}}},"400":{"description":"Password fails validation, email already registered, or username taken"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/users/id/{user_id}":{"get":{"tags":["users","users"],"summary":"Get user by ID","description":"Get a user by numeric ID. Requires authentication to prevent user enumeration attacks. Sensitive fields (`is_superadmin`, `signup_method`) are excluded.","operationId":"api_get_user_by_id_api_v1_users_id__user_id__get","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}}],"responses":{"200":{"description":"Public view of the user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserReadPublic"}}}},"401":{"description":"Authentication required"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/users/uuid/{user_uuid}":{"get":{"tags":["users","users"],"summary":"Get user by UUID","description":"Get a user by UUID. Requires authentication to prevent user enumeration attacks. Sensitive fields (`is_superadmin`, `signup_method`) are excluded.","operationId":"api_get_user_by_uuid_api_v1_users_uuid__user_uuid__get","parameters":[{"name":"user_uuid","in":"path","required":true,"schema":{"type":"string","title":"User Uuid"}}],"responses":{"200":{"description":"Public view of the user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserReadPublic"}}}},"401":{"description":"Authentication required"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/users/username/{username}":{"get":{"tags":["users","users"],"summary":"Get user by username","description":"Get a user by username. Requires authentication to prevent username enumeration attacks. Sensitive fields (`is_superadmin`, `signup_method`) are excluded.","operationId":"api_get_user_by_username_api_v1_users_username__username__get","parameters":[{"name":"username","in":"path","required":true,"schema":{"type":"string","title":"Username"}}],"responses":{"200":{"description":"Public view of the user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserReadPublic"}}}},"401":{"description":"Authentication required"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/users/{user_id}":{"put":{"tags":["users","users"],"summary":"Update user","description":"Update a user's profile fields. Invalidates the user's cached session so subsequent session reads reflect the change.","operationId":"api_update_user_api_v1_users__user_id__put","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserUpdate"}}}},"responses":{"200":{"description":"User updated successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserRead"}}}},"400":{"description":"Validation failed (duplicate email/username, invalid fields)"},"403":{"description":"Caller lacks permission to update this user"},"404":{"description":"User not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/users/update_avatar/{user_id}":{"put":{"tags":["users","users"],"summary":"Update user avatar","description":"Upload a new avatar image for a user. Users can only update their own avatar (the `user_id` in the URL must match the authenticated user's ID).","operationId":"api_update_avatar_user_api_v1_users_update_avatar__user_id__put","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_api_update_avatar_user_api_v1_users_update_avatar__user_id__put"}}}},"responses":{"200":{"description":"Avatar updated; cached session is invalidated so subsequent reads return the new image.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserRead"}}}},"403":{"description":"Attempted to update another user's avatar"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/users/change_password/{user_id}":{"put":{"tags":["users","users"],"summary":"Change user password","description":"Update a user's password. The authenticated user must either be the target user or otherwise authorized by the service layer.","operationId":"api_update_user_password_api_v1_users_change_password__user_id__put","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserUpdatePassword"}}}},"responses":{"200":{"description":"Password changed successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserRead"}}}},"400":{"description":"New password fails validation"},"401":{"description":"Wrong current password"},"403":{"description":"Caller cannot change this user's password"},"404":{"description":"User not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/users/reset_password/change_password":{"post":{"tags":["users","users"],"summary":"Change password with reset code","description":"Change a user's password using a reset code. Email, reset code and new password are all supplied in the request body so they never appear in server logs or browser history.","operationId":"api_change_password_with_reset_code_v2_api_v1_users_reset_password_change_password_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResetPasswordRequest"}}},"required":true},"responses":{"200":{"description":"Password updated successfully using the reset code.","content":{"application/json":{"schema":{}}}},"429":{"description":"Too many password reset attempts for this email"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/users/reset_password/change_password/{email}":{"post":{"tags":["users","users"],"summary":"Change password with reset code (legacy path)","description":"Deprecated: use /reset_password/change_password with email in the body. This path variant leaks the email into server access logs and exists only for backward compatibility.","operationId":"api_change_password_with_reset_code_api_v1_users_reset_password_change_password__email__post","deprecated":true,"parameters":[{"name":"email","in":"path","required":true,"schema":{"type":"string","format":"email","title":"Email"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResetPasswordRequest"}}}},"responses":{"200":{"description":"Password updated successfully using the reset code.","content":{"application/json":{"schema":{}}}},"429":{"description":"Too many password reset attempts for this email"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/users/reset_password/send_reset_code":{"post":{"tags":["users","users"],"summary":"Send password reset code","description":"Dispatch an org-scoped password reset code to the given email address (email supplied in body so it never appears in access logs). Returns a generic response regardless of whether the email exists to avoid user enumeration.","operationId":"api_send_password_reset_email_v2_api_v1_users_reset_password_send_reset_code_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendResetCodeRequest"}}},"required":true},"responses":{"200":{"description":"Reset code email dispatch requested.","content":{"application/json":{"schema":{}}}},"400":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/users/reset_password/send_reset_code/{email}":{"post":{"tags":["users","users"],"summary":"Send password reset code (legacy path)","description":"Deprecated: use /reset_password/send_reset_code with email in the body.","operationId":"api_send_password_reset_email_api_v1_users_reset_password_send_reset_code__email__post","deprecated":true,"parameters":[{"name":"email","in":"path","required":true,"schema":{"type":"string","format":"email","title":"Email"}},{"name":"org_id","in":"query","required":true,"schema":{"type":"integer","title":"Org Id"}}],"responses":{"200":{"description":"Reset code email dispatch requested.","content":{"application/json":{"schema":{}}}},"400":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/users/reset_password/platform/send_reset_code":{"post":{"tags":["users","users"],"summary":"Send platform password reset code","description":"Dispatch a platform-level password reset code (email supplied in body so it does not appear in access logs). Subject to rate limiting per email.","operationId":"api_send_password_reset_email_platform_v2_api_v1_users_reset_password_platform_send_reset_code_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendPlatformResetCodeRequest"}}},"required":true},"responses":{"200":{"description":"Reset code email dispatch requested.","content":{"application/json":{"schema":{}}}},"429":{"description":"Too many password reset attempts for this email"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/users/reset_password/platform/send_reset_code/{email}":{"post":{"tags":["users","users"],"summary":"Send platform password reset code (legacy path)","description":"Deprecated: use /reset_password/platform/send_reset_code with email in the body.","operationId":"api_send_password_reset_email_platform_api_v1_users_reset_password_platform_send_reset_code__email__post","deprecated":true,"parameters":[{"name":"email","in":"path","required":true,"schema":{"type":"string","format":"email","title":"Email"}}],"responses":{"200":{"description":"Reset code email dispatch requested.","content":{"application/json":{"schema":{}}}},"429":{"description":"Too many password reset attempts for this email"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/users/reset_password/platform/change_password":{"post":{"tags":["users","users"],"summary":"Change platform password with reset code","description":"Change a user's password at the platform level (email + reset code + new password all supplied in the body so none of them appear in server access logs).","operationId":"api_change_password_with_reset_code_platform_v2_api_v1_users_reset_password_platform_change_password_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlatformResetPasswordRequest"}}},"required":true},"responses":{"200":{"description":"Password updated successfully using the reset code.","content":{"application/json":{"schema":{}}}},"429":{"description":"Too many password reset attempts for this email"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/users/reset_password/platform/change_password/{email}":{"post":{"tags":["users","users"],"summary":"Change platform password with reset code (legacy path)","description":"Deprecated: use /reset_password/platform/change_password with email in the body.","operationId":"api_change_password_with_reset_code_platform_api_v1_users_reset_password_platform_change_password__email__post","deprecated":true,"parameters":[{"name":"email","in":"path","required":true,"schema":{"type":"string","format":"email","title":"Email"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlatformResetPasswordRequest"}}}},"responses":{"200":{"description":"Password updated successfully using the reset code.","content":{"application/json":{"schema":{}}}},"429":{"description":"Too many password reset attempts for this email"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/users/user_id/{user_id}":{"delete":{"tags":["users","users"],"summary":"Delete user","description":"Delete a user by ID. Invalidates the user's cached session so stale session data is not served.","operationId":"api_delete_user_api_v1_users_user_id__user_id__delete","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}}],"responses":{"200":{"description":"User deleted successfully.","content":{"application/json":{"schema":{}}}},"403":{"description":"Caller cannot delete this user"},"404":{"description":"User not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/users/{user_id}/courses":{"get":{"tags":["users","users"],"summary":"List courses for user","description":"List courses authored or contributed to by a user. Paginated; the maximum page size is 50 to prevent bulk data extraction.","operationId":"api_get_user_courses_api_v1_users__user_id__courses_get","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number","default":1,"title":"Page"},"description":"Page number"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"description":"Items per page (max 50)","default":10,"title":"Limit"},"description":"Items per page (max 50)"}],"responses":{"200":{"description":"Paginated list of the user's courses (max 50 per page).","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CourseRead"},"title":"Response Api Get User Courses Api V1 Users  User Id  Courses Get"}}}},"404":{"description":"User not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/usergroups/":{"post":{"tags":["usergroups","usergroups"],"summary":"Create a usergroup","description":"Create a new usergroup within an organization. Requires admin/maintainer permissions on the organization.","operationId":"api_create_usergroup_api_v1_usergroups__post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserGroupCreate"}}},"required":true},"responses":{"200":{"description":"Usergroup created successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserGroupRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to create usergroups"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/usergroups/{usergroup_id}":{"get":{"tags":["usergroups","usergroups"],"summary":"Get a usergroup","description":"Retrieve a usergroup by its numeric identifier.","operationId":"api_get_usergroup_api_v1_usergroups__usergroup_id__get","parameters":[{"name":"usergroup_id","in":"path","required":true,"schema":{"type":"integer","title":"Usergroup Id"}}],"responses":{"200":{"description":"Usergroup retrieved.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserGroupRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to view this usergroup"},"404":{"description":"Usergroup not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["usergroups","usergroups"],"summary":"Update a usergroup","description":"Update the name, description, or other attributes of a usergroup.","operationId":"api_update_usergroup_api_v1_usergroups__usergroup_id__put","parameters":[{"name":"usergroup_id","in":"path","required":true,"schema":{"type":"integer","title":"Usergroup Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserGroupUpdate"}}}},"responses":{"200":{"description":"Usergroup updated successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserGroupRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to update this usergroup"},"404":{"description":"Usergroup not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["usergroups","usergroups"],"summary":"Delete a usergroup","description":"Permanently delete a usergroup along with its user and resource links.","operationId":"api_delete_usergroup_api_v1_usergroups__usergroup_id__delete","parameters":[{"name":"usergroup_id","in":"path","required":true,"schema":{"type":"integer","title":"Usergroup Id"}}],"responses":{"200":{"description":"Usergroup deleted successfully.","content":{"application/json":{"schema":{"type":"string","title":"Response Api Delete Usergroup Api V1 Usergroups  Usergroup Id  Delete"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to delete this usergroup"},"404":{"description":"Usergroup not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/usergroups/{usergroup_id}/users":{"get":{"tags":["usergroups","usergroups"],"summary":"List users in a usergroup","description":"Retrieve the list of users that belong to a specific usergroup. Sensitive fields (is_superadmin, signup_method) are excluded.","operationId":"api_get_users_linked_to_usergroup_api_v1_usergroups__usergroup_id__users_get","parameters":[{"name":"usergroup_id","in":"path","required":true,"schema":{"type":"integer","title":"Usergroup Id"}}],"responses":{"200":{"description":"Users linked to the usergroup.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/UserReadPublic"},"title":"Response 200 Api Get Users Linked To Usergroup Api V1 Usergroups  Usergroup Id  Users Get"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to view usergroup members"},"404":{"description":"Usergroup not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/usergroups/org/{org_id}":{"get":{"tags":["usergroups","usergroups"],"summary":"List usergroups for an organization","description":"Retrieve every usergroup that belongs to a given organization.","operationId":"api_get_usergroups_api_v1_usergroups_org__org_id__get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"responses":{"200":{"description":"Usergroups for the organization.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/UserGroupRead"},"title":"Response 200 Api Get Usergroups Api V1 Usergroups Org  Org Id  Get"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to view usergroups for this organization"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/usergroups/{usergroup_id}/resources":{"get":{"tags":["usergroups","usergroups"],"summary":"List resources linked to a usergroup","description":"Return the UUIDs of resources (courses, folders, etc.) that are linked to a usergroup.","operationId":"api_get_resources_linked_to_usergroup_api_v1_usergroups__usergroup_id__resources_get","parameters":[{"name":"usergroup_id","in":"path","required":true,"schema":{"type":"integer","title":"Usergroup Id"}}],"responses":{"200":{"description":"Resource UUIDs linked to the usergroup.","content":{"application/json":{"schema":{"type":"array","items":{"type":"string"},"title":"Response 200 Api Get Resources Linked To Usergroup Api V1 Usergroups  Usergroup Id  Resources Get"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to view this usergroup"},"404":{"description":"Usergroup not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/usergroups/resource/{resource_uuid}":{"get":{"tags":["usergroups","usergroups"],"summary":"List usergroups linked to a resource","description":"Retrieve every usergroup that is linked to a given resource UUID.","operationId":"api_get_usergroupsby_resource_api_v1_usergroups_resource__resource_uuid__get","parameters":[{"name":"resource_uuid","in":"path","required":true,"schema":{"type":"string","title":"Resource Uuid"}}],"responses":{"200":{"description":"Usergroups linked to the resource.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/UserGroupRead"},"title":"Response 200 Api Get Usergroupsby Resource Api V1 Usergroups Resource  Resource Uuid  Get"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to view usergroups for this resource"},"404":{"description":"Resource not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/usergroups/{usergroup_id}/add_users":{"post":{"tags":["usergroups","usergroups"],"summary":"Add users to a usergroup","description":"Add one or more users to a usergroup. User IDs should be provided as a comma-separated string.","operationId":"api_add_users_to_usergroup_api_v1_usergroups__usergroup_id__add_users_post","parameters":[{"name":"usergroup_id","in":"path","required":true,"schema":{"type":"integer","title":"Usergroup Id"}},{"name":"user_ids","in":"query","required":true,"schema":{"type":"string","title":"User Ids"}}],"responses":{"200":{"description":"Users added to the usergroup.","content":{"application/json":{"schema":{"type":"string","title":"Response Api Add Users To Usergroup Api V1 Usergroups  Usergroup Id  Add Users Post"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to modify this usergroup"},"404":{"description":"Usergroup or user not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/usergroups/{usergroup_id}/remove_users":{"delete":{"tags":["usergroups","usergroups"],"summary":"Remove users from a usergroup","description":"Remove one or more users from a usergroup. User IDs should be provided as a comma-separated string.","operationId":"api_delete_users_from_usergroup_api_v1_usergroups__usergroup_id__remove_users_delete","parameters":[{"name":"usergroup_id","in":"path","required":true,"schema":{"type":"integer","title":"Usergroup Id"}},{"name":"user_ids","in":"query","required":true,"schema":{"type":"string","title":"User Ids"}}],"responses":{"200":{"description":"Users removed from the usergroup.","content":{"application/json":{"schema":{"type":"string","title":"Response Api Delete Users From Usergroup Api V1 Usergroups  Usergroup Id  Remove Users Delete"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to modify this usergroup"},"404":{"description":"Usergroup or user not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/usergroups/{usergroup_id}/add_resources":{"post":{"tags":["usergroups","usergroups"],"summary":"Add resources to a usergroup","description":"Link one or more resources (courses, folders, etc.) to a usergroup. Resource UUIDs should be provided as a comma-separated string.","operationId":"api_add_resources_to_usergroup_api_v1_usergroups__usergroup_id__add_resources_post","parameters":[{"name":"usergroup_id","in":"path","required":true,"schema":{"type":"integer","title":"Usergroup Id"}},{"name":"resource_uuids","in":"query","required":true,"schema":{"type":"string","title":"Resource Uuids"}}],"responses":{"200":{"description":"Resources linked to the usergroup.","content":{"application/json":{"schema":{"type":"string","title":"Response Api Add Resources To Usergroup Api V1 Usergroups  Usergroup Id  Add Resources Post"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to modify this usergroup"},"404":{"description":"Usergroup or resource not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/usergroups/{usergroup_id}/remove_resources":{"delete":{"tags":["usergroups","usergroups"],"summary":"Remove resources from a usergroup","description":"Unlink one or more resources from a usergroup. Resource UUIDs should be provided as a comma-separated string.","operationId":"api_delete_resources_from_usergroup_api_v1_usergroups__usergroup_id__remove_resources_delete","parameters":[{"name":"usergroup_id","in":"path","required":true,"schema":{"type":"integer","title":"Usergroup Id"}},{"name":"resource_uuids","in":"query","required":true,"schema":{"type":"string","title":"Resource Uuids"}}],"responses":{"200":{"description":"Resources unlinked from the usergroup.","content":{"application/json":{"schema":{"type":"string","title":"Response Api Delete Resources From Usergroup Api V1 Usergroups  Usergroup Id  Remove Resources Delete"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to modify this usergroup"},"404":{"description":"Usergroup or resource not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/refresh":{"get":{"tags":["auth"],"summary":"Refresh access token","description":"Validate the refresh token (read from the `refresh_token` httpOnly cookie) and issue a new access token. Subject to IP-based rate limiting.","operationId":"refresh_api_v1_auth_refresh_get","responses":{"200":{"description":"New access token issued and set as cookie; body contains the token and its expiry.","content":{"application/json":{"schema":{}}}},"401":{"description":"Refresh token is missing or invalid"},"429":{"description":"Too many refresh attempts from this IP"}}}},"/api/v1/auth/login":{"post":{"tags":["auth"],"summary":"Log in with email and password","description":"Authenticate a user with username (email) and password. On success, sets httpOnly access and refresh cookies and returns the user profile and tokens. Subject to IP-based rate limiting and account lockout after repeated failures. In SaaS mode, the account's email must be verified.","operationId":"login_api_v1_auth_login_post","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_login_api_v1_auth_login_post"}}},"required":true},"responses":{"200":{"description":"Login successful; cookies set and body contains user + tokens.","content":{"application/json":{"schema":{}}}},"401":{"description":"Incorrect email or password"},"403":{"description":"Email not verified (SaaS mode)"},"423":{"description":"Account is locked due to too many failed attempts"},"429":{"description":"Too many login attempts from this IP"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/oauth":{"post":{"tags":["auth"],"summary":"Log in via third-party provider","description":"Sign in or sign up using a third-party OAuth provider (currently Google). On success, sets httpOnly access and refresh cookies and returns the user profile and tokens.","operationId":"third_party_login_api_v1_auth_oauth_post","parameters":[{"name":"org_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ThirdPartyLogin"}}}},"responses":{"200":{"description":"OAuth login successful; cookies set and body contains user + tokens.","content":{"application/json":{"schema":{}}}},"401":{"description":"Third-party authentication failed"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/logout":{"delete":{"tags":["auth"],"summary":"Log out the current user","description":"Log out the current user by clearing the access and refresh cookies. Because JWTs are stored in httpOnly cookies, the frontend cannot clear them directly — the backend must respond with cookie-clearing headers.","operationId":"logout_api_v1_auth_logout_delete","responses":{"200":{"description":"Logout successful; auth cookies cleared.","content":{"application/json":{"schema":{}}}},"401":{"description":"No authenticated session was found"}}}},"/api/v1/auth/verify-email":{"post":{"tags":["auth"],"summary":"Verify user email","description":"Verify a user's email address using the token delivered via verification email. Rate limited to 5 attempts per 5 minutes per user_uuid.","operationId":"api_verify_email_api_v1_auth_verify_email_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyEmailRequest"}}},"required":true},"responses":{"200":{"description":"Email verified successfully.","content":{"application/json":{"schema":{}}}},"429":{"description":"Too many verification attempts for this user"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/resend-verification":{"post":{"tags":["auth"],"summary":"Resend verification email","description":"Resend the email-verification email for a user. The underlying service enforces its own rate limiting and will return a generic response whether or not an account exists.","operationId":"api_resend_verification_email_api_v1_auth_resend_verification_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResendVerificationRequest"}}},"required":true},"responses":{"200":{"description":"Verification email dispatch requested.","content":{"application/json":{"schema":{}}}},"429":{"description":"Too many verification email requests — rate limited"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/":{"post":{"tags":["orgs"],"summary":"Create an organization","description":"Create a new organization owned by the authenticated user.","operationId":"api_create_org_api_v1_orgs__post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationCreate"}}},"required":true},"responses":{"200":{"description":"Organization created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationRead"}}}},"401":{"description":"Not authenticated"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/withconfig/":{"post":{"tags":["orgs"],"summary":"Create an organization with config","description":"Create a new organization together with its base configuration in a single call (pre-alpha).","operationId":"api_create_org_withconfig_api_v1_orgs_withconfig__post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Body_api_create_org_withconfig_api_v1_orgs_withconfig__post"}}},"required":true},"responses":{"200":{"description":"Organization and configuration created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationRead"}}}},"401":{"description":"Not authenticated"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/uuid/{org_uuid}":{"get":{"tags":["orgs"],"summary":"Get organization by UUID","description":"Fetch a single organization by its UUID.","operationId":"api_get_org_by_uuid_api_v1_orgs_uuid__org_uuid__get","parameters":[{"name":"org_uuid","in":"path","required":true,"schema":{"type":"string","title":"Org Uuid"}}],"responses":{"200":{"description":"Organization matching the UUID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationRead"}}}},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/users/export":{"get":{"tags":["orgs"],"summary":"Export organization users as CSV","description":"Export organization users as a CSV file. Supports the same filters as the users listing endpoint. Requires authentication; anonymous access is rejected.","operationId":"api_export_org_users_api_v1_orgs__org_id__users_export_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"search","in":"query","required":false,"schema":{"type":"string","default":"","title":"Search"}},{"name":"usergroup_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Usergroup Id"}},{"name":"usergroup_filter","in":"query","required":false,"schema":{"anyOf":[{"enum":["in_group","not_in_group"],"type":"string"},{"type":"null"}],"title":"Usergroup Filter"}},{"name":"sort_order","in":"query","required":false,"schema":{"anyOf":[{"enum":["asc","desc"],"type":"string"},{"type":"null"}],"default":"desc","title":"Sort Order"}},{"name":"role_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Role Id"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"enum":["verified","unverified"],"type":"string"},{"type":"null"}],"title":"Status"}}],"responses":{"200":{"description":"CSV file of organization users matching the filters.","content":{"application/json":{"schema":{}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not a member of the organization"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/users":{"get":{"tags":["orgs"],"summary":"List organization users","description":"List organization users with pagination, search and filters. Requires authentication; anonymous access is rejected. The limit is capped at 100 to prevent data dumping.","operationId":"api_get_org_users_api_v1_orgs__org_id__users_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number","default":1,"title":"Page"},"description":"Page number"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Items per page (max 100)","default":20,"title":"Limit"},"description":"Items per page (max 100)"},{"name":"search","in":"query","required":false,"schema":{"type":"string","default":"","title":"Search"}},{"name":"usergroup_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Filter by usergroup membership","title":"Usergroup Id"},"description":"Filter by usergroup membership"},{"name":"usergroup_filter","in":"query","required":false,"schema":{"anyOf":[{"enum":["in_group","not_in_group"],"type":"string"},{"type":"null"}],"description":"Membership filter: 'in_group' or 'not_in_group'","title":"Usergroup Filter"},"description":"Membership filter: 'in_group' or 'not_in_group'"},{"name":"sort_order","in":"query","required":false,"schema":{"anyOf":[{"enum":["asc","desc"],"type":"string"},{"type":"null"}],"description":"Sort order for join date","default":"desc","title":"Sort Order"},"description":"Sort order for join date"},{"name":"role_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Filter by role ID","title":"Role Id"},"description":"Filter by role ID"},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"enum":["verified","unverified"],"type":"string"},{"type":"null"}],"description":"Filter by verification status","title":"Status"},"description":"Filter by verification status"}],"responses":{"200":{"description":"Paginated list of organization users.","content":{"application/json":{"schema":{}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not a member of the organization"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/join":{"post":{"tags":["orgs"],"summary":"Join an organization","description":"Join an existing organization, optionally consuming an invite code.","operationId":"api_join_an_org_api_v1_orgs_join_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JoinOrg"}}},"required":true},"responses":{"200":{"description":"Organization joined successfully.","content":{"application/json":{"schema":{}}}},"401":{"description":"Not authenticated"},"403":{"description":"Organization is invite-only or invite is invalid"},"404":{"description":"Organization or invite not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/users/{user_id}/role/{role_uuid}":{"put":{"tags":["orgs"],"summary":"Update user role in organization","description":"Update the role of a user within an organization by role UUID.","operationId":"api_update_user_role_api_v1_orgs__org_id__users__user_id__role__role_uuid__put","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}},{"name":"role_uuid","in":"path","required":true,"schema":{"type":"string","title":"Role Uuid"}}],"responses":{"200":{"description":"User role updated.","content":{"application/json":{"schema":{}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller lacks permission to change roles"},"404":{"description":"Organization, user, or role not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/users/batch/remove":{"delete":{"tags":["orgs"],"summary":"Remove multiple users from organization","description":"Remove a batch of users from the organization in a single call.","operationId":"api_remove_batch_users_from_org_api_v1_orgs__org_id__users_batch_remove_delete","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"user_ids","in":"query","required":true,"schema":{"type":"array","items":{"type":"integer"},"description":"List of user IDs to remove","title":"User Ids"},"description":"List of user IDs to remove"}],"responses":{"200":{"description":"Users removed from the organization.","content":{"application/json":{"schema":{}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller lacks permission to remove users"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/users/all":{"delete":{"tags":["orgs"],"summary":"Remove all users from organization","description":"Remove every member from the organization except the caller. The organization and its content are kept. Admin only.","operationId":"api_remove_all_users_from_org_api_v1_orgs__org_id__users_all_delete","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"responses":{"200":{"description":"All other users removed from the organization.","content":{"application/json":{"schema":{}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not an organization administrator"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/content":{"delete":{"tags":["orgs"],"summary":"Wipe all organization content","description":"Delete all courses (and their cascaded content) in the organization while keeping the organization and its members. Admin only.","operationId":"api_wipe_org_content_api_v1_orgs__org_id__content_delete","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"responses":{"200":{"description":"Organization content wiped.","content":{"application/json":{"schema":{}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not an organization administrator"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/users/{user_id}":{"delete":{"tags":["orgs"],"summary":"Remove a user from organization","description":"Remove a single user from the organization.","operationId":"api_remove_user_from_org_api_v1_orgs__org_id__users__user_id__delete","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}}],"responses":{"200":{"description":"User removed from the organization.","content":{"application/json":{"schema":{}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller lacks permission to remove users"},"404":{"description":"Organization or user not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/leave":{"delete":{"tags":["orgs"],"summary":"Leave an organization","description":"Remove the CURRENT (authenticated) user's own membership in the org — self-service, no admin rights required. The last remaining admin cannot leave (they must transfer ownership or delete the org).","operationId":"api_leave_org_api_v1_orgs__org_id__leave_delete","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"responses":{"200":{"description":"Left the organization.","content":{"application/json":{"schema":{}}}},"400":{"description":"You are the last admin"},"401":{"description":"Not authenticated"},"404":{"description":"Organization not found or you are not a member"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/signup_mechanism":{"put":{"tags":["orgs"],"summary":"Update organization signup mechanism","description":"Change whether the organization allows open signup or requires an invite code.","operationId":"api_get_org_signup_mechanism_api_v1_orgs__org_id__signup_mechanism_put","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"signup_mechanism","in":"query","required":true,"schema":{"enum":["open","inviteOnly"],"type":"string","title":"Signup Mechanism"}}],"responses":{"200":{"description":"Signup mechanism updated.","content":{"application/json":{"schema":{}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not an organization administrator"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/config/color":{"put":{"tags":["orgs"],"summary":"Update organization color","description":"Update the organization's primary color used for branding.","operationId":"api_update_org_color_config_api_v1_orgs__org_id__config_color_put","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"color","in":"query","required":false,"schema":{"type":"string","default":"","title":"Color"}}],"responses":{"200":{"description":"Color configuration updated.","content":{"application/json":{"schema":{}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not an organization administrator"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/config/font":{"put":{"tags":["orgs"],"summary":"Update organization font","description":"Update the organization's branding font family.","operationId":"api_update_org_font_config_api_v1_orgs__org_id__config_font_put","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"font","in":"query","required":false,"schema":{"type":"string","default":"","title":"Font"}}],"responses":{"200":{"description":"Font configuration updated.","content":{"application/json":{"schema":{}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not an organization administrator"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/config/footer_text":{"put":{"tags":["orgs"],"summary":"Update organization footer text","description":"Update the organization's footer text used across learner-facing pages.","operationId":"api_update_org_footer_text_config_api_v1_orgs__org_id__config_footer_text_put","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"footer_text","in":"query","required":false,"schema":{"type":"string","default":"","title":"Footer Text"}}],"responses":{"200":{"description":"Footer text configuration updated.","content":{"application/json":{"schema":{}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not an organization administrator"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/config/default_language":{"put":{"tags":["orgs"],"summary":"Update organization default language","description":"Update the organization's default language used for the public UI and outgoing emails. Admin only.","operationId":"api_update_org_default_language_config_api_v1_orgs__org_id__config_default_language_put","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"default_language","in":"query","required":true,"schema":{"type":"string","title":"Default Language"}}],"responses":{"200":{"description":"Default language updated.","content":{"application/json":{"schema":{}}}},"400":{"description":"Unsupported language code"},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not an organization administrator"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/config/watermark":{"put":{"tags":["orgs"],"summary":"Update organization watermark","description":"Enable or disable the watermark. Free plan organizations are not allowed to disable it.","operationId":"api_update_org_watermark_config_api_v1_orgs__org_id__config_watermark_put","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"watermark_enabled","in":"query","required":false,"schema":{"type":"boolean","default":true,"title":"Watermark Enabled"}}],"responses":{"200":{"description":"Watermark configuration updated.","content":{"application/json":{"schema":{}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not an admin or free plan cannot disable the watermark"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/config/auth_branding":{"put":{"tags":["orgs"],"summary":"Update auth page branding","description":"Update branding configuration for the organization's authentication pages.","operationId":"api_update_org_auth_branding_config_api_v1_orgs__org_id__config_auth_branding_put","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthBrandingConfig"}}}},"responses":{"200":{"description":"Auth branding configuration updated.","content":{"application/json":{"schema":{}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not an organization administrator"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/config/menu":{"put":{"tags":["orgs"],"summary":"Update public menu config","description":"Customize which links appear in the public organization navigation, their order, labels, and custom links.","operationId":"api_update_org_menu_config_api_v1_orgs__org_id__config_menu_put","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Menu Config"}}}},"responses":{"200":{"description":"Menu configuration updated.","content":{"application/json":{"schema":{}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not an organization administrator"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/auth_background":{"put":{"tags":["orgs"],"summary":"Upload auth page background","description":"Upload the background image shown on the organization's authentication pages.","operationId":"api_upload_org_auth_background_api_v1_orgs__org_id__auth_background_put","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_api_upload_org_auth_background_api_v1_orgs__org_id__auth_background_put"}}}},"responses":{"200":{"description":"Auth background image uploaded.","content":{"application/json":{"schema":{}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not an organization administrator"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/config/seo":{"put":{"tags":["orgs"],"summary":"Update organization SEO config","description":"Update SEO-related configuration such as titles, descriptions and keywords.","operationId":"api_update_org_seo_config_api_v1_orgs__org_id__config_seo_put","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SeoOrgConfig"}}}},"responses":{"200":{"description":"SEO configuration updated.","content":{"application/json":{"schema":{}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not an organization administrator"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/og_image":{"put":{"tags":["orgs"],"summary":"Upload OG image","description":"Upload the OpenGraph image used for social media sharing previews.","operationId":"api_upload_org_og_image_api_v1_orgs__org_id__og_image_put","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_api_upload_org_og_image_api_v1_orgs__org_id__og_image_put"}}}},"responses":{"200":{"description":"OG image uploaded.","content":{"application/json":{"schema":{}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not an organization administrator"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/invites":{"post":{"tags":["orgs"],"summary":"Create an invite code","description":"Create a new invite code for the organization, optionally linked to a usergroup.","operationId":"api_create_invite_code_api_v1_orgs__org_id__invites_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"usergroup_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Usergroup Id"}}],"responses":{"200":{"description":"Invite code created.","content":{"application/json":{"schema":{}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not an organization administrator"},"404":{"description":"Organization or usergroup not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["orgs"],"summary":"List invite codes","description":"List all invite codes for the organization.","operationId":"api_get_invite_codes_api_v1_orgs__org_id__invites_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"responses":{"200":{"description":"List of invite codes for the organization.","content":{"application/json":{"schema":{}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not an organization administrator"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/invites/code/{invite_code}":{"get":{"tags":["orgs"],"summary":"Get an invite code","description":"Fetch details for a single invite code.","operationId":"api_get_invite_code_api_v1_orgs__org_id__invites_code__invite_code__get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"invite_code","in":"path","required":true,"schema":{"type":"string","title":"Invite Code"}}],"responses":{"200":{"description":"Invite code details.","content":{"application/json":{"schema":{}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not an organization administrator"},"404":{"description":"Invite code not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/invites/{org_invite_code_uuid}":{"delete":{"tags":["orgs"],"summary":"Delete an invite code","description":"Delete an invite code by its UUID.","operationId":"api_delete_invite_code_api_v1_orgs__org_id__invites__org_invite_code_uuid__delete","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"org_invite_code_uuid","in":"path","required":true,"schema":{"type":"string","title":"Org Invite Code Uuid"}}],"responses":{"200":{"description":"Invite code deleted.","content":{"application/json":{"schema":{}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not an organization administrator"},"404":{"description":"Invite code not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/invites/users/batch":{"post":{"tags":["orgs"],"summary":"Invite a batch of users","description":"Invite multiple users by email in a single request, optionally using a specific invite code.","operationId":"api_invite_batch_users_api_v1_orgs__org_id__invites_users_batch_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"emails","in":"query","required":true,"schema":{"type":"string","title":"Emails"}},{"name":"invite_code_uuid","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Invite Code Uuid"}}],"responses":{"200":{"description":"Invitations queued for the supplied emails.","content":{"application/json":{"schema":{}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not an organization administrator"},"404":{"description":"Organization or invite code not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/invites/users":{"get":{"tags":["orgs"],"summary":"List invited users","description":"List users who have been invited to the organization but have not joined yet.","operationId":"api_get_org_users_invites_api_v1_orgs__org_id__invites_users_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"responses":{"200":{"description":"List of invited users.","content":{"application/json":{"schema":{}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not an organization administrator"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/invites/users/{email}":{"delete":{"tags":["orgs"],"summary":"Revoke an invited user","description":"Revoke a pending invitation for the user identified by email.","operationId":"api_delete_org_users_invites_api_v1_orgs__org_id__invites_users__email__delete","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"email","in":"path","required":true,"schema":{"type":"string","title":"Email"}}],"responses":{"200":{"description":"Invitation revoked.","content":{"application/json":{"schema":{}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not an organization administrator"},"404":{"description":"Invitation not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/slug/{org_slug}":{"get":{"tags":["orgs"],"summary":"Get organization by slug","description":"Fetch a single organization by its URL slug.","operationId":"api_get_org_by_slug_api_v1_orgs_slug__org_slug__get","parameters":[{"name":"org_slug","in":"path","required":true,"schema":{"type":"string","title":"Org Slug"}}],"responses":{"200":{"description":"Organization matching the slug.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationRead"}}}},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/logo":{"put":{"tags":["orgs"],"summary":"Update organization logo","description":"Upload a new logo image for the organization.","operationId":"api_update_org_logo_api_v1_orgs__org_id__logo_put","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_api_update_org_logo_api_v1_orgs__org_id__logo_put"}}}},"responses":{"200":{"description":"Logo updated.","content":{"application/json":{"schema":{}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not an organization administrator"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/favicon":{"put":{"tags":["orgs"],"summary":"Update organization favicon","description":"Upload a new favicon image for the organization.","operationId":"api_update_org_favicon_api_v1_orgs__org_id__favicon_put","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_api_update_org_favicon_api_v1_orgs__org_id__favicon_put"}}}},"responses":{"200":{"description":"Favicon updated.","content":{"application/json":{"schema":{}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not an organization administrator"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/thumbnail":{"put":{"tags":["orgs"],"summary":"Update organization thumbnail","description":"Upload a new thumbnail image for the organization.","operationId":"api_update_org_thumbnail_api_v1_orgs__org_id__thumbnail_put","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_api_update_org_thumbnail_api_v1_orgs__org_id__thumbnail_put"}}}},"responses":{"200":{"description":"Thumbnail updated.","content":{"application/json":{"schema":{}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not an organization administrator"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/preview":{"put":{"tags":["orgs"],"summary":"Update organization preview image","description":"Upload a new preview image used on the organization's landing page.","operationId":"api_update_org_preview_api_v1_orgs__org_id__preview_put","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_api_update_org_preview_api_v1_orgs__org_id__preview_put"}}}},"responses":{"200":{"description":"Preview image updated.","content":{"application/json":{"schema":{}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not an organization administrator"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/user/page/{page}/limit/{limit}":{"get":{"tags":["orgs"],"summary":"List organizations for current user","description":"Return a paginated list of organizations the current user belongs to.","operationId":"api_user_orgs_api_v1_orgs_user_page__page__limit__limit__get","parameters":[{"name":"page","in":"path","required":true,"schema":{"type":"integer","minimum":1,"description":"Page number (1-based)","title":"Page"},"description":"Page number (1-based)"},{"name":"limit","in":"path","required":true,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Items per page (max 100)","title":"Limit"},"description":"Items per page (max 100)"}],"responses":{"200":{"description":"Paginated organizations for the current user.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/OrganizationRead"},"title":"Response 200 Api User Orgs Api V1 Orgs User Page  Page  Limit  Limit  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/user_admin/page/{page}/limit/{limit}":{"get":{"tags":["orgs"],"summary":"List organizations the user administers","description":"Return a paginated list of organizations where the current user has admin rights.","operationId":"api_user_orgs_admin_api_v1_orgs_user_admin_page__page__limit__limit__get","parameters":[{"name":"page","in":"path","required":true,"schema":{"type":"integer","minimum":1,"description":"Page number (1-based)","title":"Page"},"description":"Page number (1-based)"},{"name":"limit","in":"path","required":true,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Items per page (max 100)","title":"Limit"},"description":"Items per page (max 100)"}],"responses":{"200":{"description":"Paginated organizations the current user administers.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/OrganizationRead"},"title":"Response 200 Api User Orgs Admin Api V1 Orgs User Admin Page  Page  Limit  Limit  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}":{"put":{"tags":["orgs"],"summary":"Update an organization","description":"Update an organization's core fields by ID.","operationId":"api_update_org_api_v1_orgs__org_id__put","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationUpdate"}}}},"responses":{"200":{"description":"Organization updated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationRead"}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not an organization administrator"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["orgs"],"summary":"Delete an organization","description":"Delete an organization by its ID. This action cannot be undone.","operationId":"api_delete_org_api_v1_orgs__org_id__delete","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"responses":{"200":{"description":"Organization deleted.","content":{"application/json":{"schema":{}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not an organization administrator"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/landing":{"put":{"tags":["orgs"],"summary":"Update organization landing page","description":"Update the organization's landing page content object.","operationId":"api_update_org_landing_api_v1_orgs__org_id__landing_put","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Landing Object"}}}},"responses":{"200":{"description":"Landing page updated.","content":{"application/json":{"schema":{}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not an organization administrator"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/landing/content":{"post":{"tags":["orgs"],"summary":"Upload landing page content","description":"Upload a content asset (image or file) to attach to the organization's landing page.","operationId":"api_upload_org_landing_content_api_v1_orgs__org_id__landing_content_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_api_upload_org_landing_content_api_v1_orgs__org_id__landing_content_post"}}}},"responses":{"200":{"description":"Landing page content uploaded.","content":{"application/json":{"schema":{}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not an organization administrator"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/usage":{"get":{"tags":["orgs"],"summary":"Get organization usage and limits","description":"Return current usage, plan limits, and remaining quota for the organization's plan-based features.","operationId":"api_get_org_usage_api_v1_orgs__org_id__usage_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"responses":{"200":{"description":"Usage, limits, and remaining quota for the organization.","content":{"application/json":{"schema":{}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not a member of the organization"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/config/ai":{"put":{"tags":["orgs","Feature Configuration"],"summary":"Update organization AI config","description":"Update the organization's AI feature configuration, including the Copilot toggle. Admin only.","operationId":"api_update_org_ai_config_api_v1_orgs__org_id__config_ai_put","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","description":"Organization ID","title":"Org Id"},"description":"Organization ID"},{"name":"ai_enabled","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Ai Enabled"}},{"name":"copilot_enabled","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Copilot Enabled"}}],"responses":{"200":{"description":"AI configuration updated.","content":{"application/json":{"schema":{}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not an organization administrator"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/config/communities":{"put":{"tags":["orgs","Feature Configuration"],"summary":"Update organization communities config","description":"Enable or disable the communities feature for the organization. Admin only.","operationId":"api_update_org_communities_config_api_v1_orgs__org_id__config_communities_put","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","description":"Organization ID","title":"Org Id"},"description":"Organization ID"},{"name":"communities_enabled","in":"query","required":true,"schema":{"type":"boolean","title":"Communities Enabled"}}],"responses":{"200":{"description":"Communities configuration updated.","content":{"application/json":{"schema":{}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not an organization administrator"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/config/payments":{"put":{"tags":["orgs","Feature Configuration"],"summary":"Update organization payments config","description":"Enable or disable the payments feature for the organization. Admin only.","operationId":"api_update_org_payments_config_api_v1_orgs__org_id__config_payments_put","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","description":"Organization ID","title":"Org Id"},"description":"Organization ID"},{"name":"payments_enabled","in":"query","required":true,"schema":{"type":"boolean","title":"Payments Enabled"}}],"responses":{"200":{"description":"Payments configuration updated.","content":{"application/json":{"schema":{}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not an organization administrator"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/config/courses":{"put":{"tags":["orgs","Feature Configuration"],"summary":"Update organization courses config","description":"Enable or disable the courses feature for the organization. Admin only.","operationId":"api_update_org_courses_config_api_v1_orgs__org_id__config_courses_put","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","description":"Organization ID","title":"Org Id"},"description":"Organization ID"},{"name":"courses_enabled","in":"query","required":true,"schema":{"type":"boolean","title":"Courses Enabled"}}],"responses":{"200":{"description":"Courses configuration updated.","content":{"application/json":{"schema":{}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not an organization administrator"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/config/folders":{"put":{"tags":["orgs","Feature Configuration"],"summary":"Update organization folders config","description":"Enable or disable the folders feature for the organization. Admin only.","operationId":"api_update_org_folders_config_api_v1_orgs__org_id__config_folders_put","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","description":"Organization ID","title":"Org Id"},"description":"Organization ID"},{"name":"folders_enabled","in":"query","required":true,"schema":{"type":"boolean","title":"Folders Enabled"}}],"responses":{"200":{"description":"Folders configuration updated.","content":{"application/json":{"schema":{}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not an organization administrator"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/config/folders-sort":{"put":{"tags":["orgs","Feature Configuration"],"summary":"Update organization library folders sort mode","description":"Set the library folder ordering mode (name_asc | name_desc | newest | oldest | manual). Admin only.","operationId":"api_update_org_folders_sort_config_api_v1_orgs__org_id__config_folders_sort_put","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","description":"Organization ID","title":"Org Id"},"description":"Organization ID"},{"name":"sort_mode","in":"query","required":true,"schema":{"type":"string","title":"Sort Mode"}}],"responses":{"200":{"description":"Folders sort mode updated.","content":{"application/json":{"schema":{}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not an organization administrator"},"404":{"description":"Organization not found"},"422":{"description":"Invalid sort mode"}}}},"/api/v1/orgs/{org_id}/config/podcasts":{"put":{"tags":["orgs","Feature Configuration"],"summary":"Update organization podcasts config","description":"Enable or disable the podcasts feature for the organization. Admin only.","operationId":"api_update_org_podcasts_config_api_v1_orgs__org_id__config_podcasts_put","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","description":"Organization ID","title":"Org Id"},"description":"Organization ID"},{"name":"podcasts_enabled","in":"query","required":true,"schema":{"type":"boolean","title":"Podcasts Enabled"}}],"responses":{"200":{"description":"Podcasts configuration updated.","content":{"application/json":{"schema":{}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not an organization administrator"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/config/boards":{"put":{"tags":["orgs","Feature Configuration"],"summary":"Update organization boards config","description":"Enable or disable the boards feature for the organization. Admin only.","operationId":"api_update_org_boards_config_api_v1_orgs__org_id__config_boards_put","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","description":"Organization ID","title":"Org Id"},"description":"Organization ID"},{"name":"boards_enabled","in":"query","required":true,"schema":{"type":"boolean","title":"Boards Enabled"}}],"responses":{"200":{"description":"Boards configuration updated.","content":{"application/json":{"schema":{}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not an organization administrator"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/config/playgrounds":{"put":{"tags":["orgs","Feature Configuration"],"summary":"Update organization playgrounds config","description":"Enable or disable the playgrounds feature for the organization. Admin only.","operationId":"api_update_org_playgrounds_config_api_v1_orgs__org_id__config_playgrounds_put","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","description":"Organization ID","title":"Org Id"},"description":"Organization ID"},{"name":"playgrounds_enabled","in":"query","required":true,"schema":{"type":"boolean","title":"Playgrounds Enabled"}}],"responses":{"200":{"description":"Playgrounds configuration updated.","content":{"application/json":{"schema":{}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not an organization administrator"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/ai-credits":{"get":{"tags":["ai-credits"],"summary":"Get AI credits summary","description":"Return the AI credits summary for an organization, including base, purchased, used, and remaining credits. The caller must be a member of the organization.","operationId":"get_org_ai_credits_api_v1_orgs__org_id__ai_credits_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"responses":{"200":{"description":"AI credits summary for the organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AICreditsSummary"}}}},"403":{"description":"User is not a member of this organization"},"404":{"description":"Organization not found or credits summary unavailable"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/ai-credits/add":{"post":{"tags":["ai-credits"],"summary":"Add purchased AI credits (superadmin only)","description":"Add purchased AI credits to an organization. Restricted to superadmins because it grants paid quota with no payment verification; the amount must be a positive integer.","operationId":"add_org_ai_credits_api_v1_orgs__org_id__ai_credits_add_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddCreditsRequest"}}}},"responses":{"200":{"description":"Credits added and new purchased total returned.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddCreditsResponse"}}}},"400":{"description":"Credit amount must be a positive number"},"403":{"description":"Superadmin access required"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/ai-credits/reset":{"post":{"tags":["ai-credits"],"summary":"Reset AI credits usage (superadmin only)","description":"Reset AI credits usage for an organization. Typically used at the start of a new billing period. Restricted to superadmins because it clears metered usage and would otherwise let a tenant bypass its quota.","operationId":"reset_org_ai_credits_api_v1_orgs__org_id__ai_credits_reset_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"responses":{"200":{"description":"AI credits usage reset to zero.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResetCreditsResponse"}}}},"403":{"description":"Superadmin access required"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/ai-credits/set":{"post":{"tags":["ai-credits"],"summary":"Set purchased AI credits (superadmin only)","description":"Overwrite the org's purchased AI credit balance to an absolute value. Restricted to superadmins; bypasses the additive /add flow so it can grant, correct, or zero out credits in one call.","operationId":"set_org_ai_credits_api_v1_orgs__org_id__ai_credits_set_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetCreditsRequest"}}}},"responses":{"200":{"description":"Credits set; returns the new purchased total.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetCreditsResponse"}}}},"400":{"description":"Credit amount must be non-negative"},"403":{"description":"Superadmin access required"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/roles/org/{org_id}":{"post":{"tags":["roles"],"summary":"Create role","description":"Create a new role for a specific organization. Requires the Pro plan feature flag.","operationId":"api_create_role_api_v1_roles_org__org_id__post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleCreate"}}}},"responses":{"200":{"description":"Role created successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"Plan does not permit creating roles, or caller lacks permission"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["roles"],"summary":"List roles for organization","description":"Get all roles for a specific organization, including global roles available to every org.","operationId":"api_get_roles_by_organization_api_v1_roles_org__org_id__get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"responses":{"200":{"description":"List of roles (custom + global) available to the organization.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/RoleRead"},"title":"Response Api Get Roles By Organization Api V1 Roles Org  Org Id  Get"}}}},"401":{"description":"Authentication required"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/roles/{role_id}":{"get":{"tags":["roles"],"summary":"Get role","description":"Get a single role by its role_id.","operationId":"api_get_role_api_v1_roles__role_id__get","parameters":[{"name":"role_id","in":"path","required":true,"schema":{"type":"integer","title":"Role Id"}}],"responses":{"200":{"description":"Role details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleRead"}}}},"401":{"description":"Authentication required"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["roles"],"summary":"Update role","description":"Update a role by its role_id. The role_id path parameter must be numeric.","operationId":"api_update_role_api_v1_roles__role_id__put","parameters":[{"name":"role_id","in":"path","required":true,"schema":{"type":"integer","title":"Role Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleUpdate"}}}},"responses":{"200":{"description":"Role updated successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleRead"}}}},"400":{"description":"Invalid role ID format (must be numeric)"},"401":{"description":"Authentication required"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["roles"],"summary":"Delete role","description":"Delete a role by its role_id. Deletion is permanent.","operationId":"api_delete_role_api_v1_roles__role_id__delete","parameters":[{"name":"role_id","in":"path","required":true,"schema":{"type":"integer","title":"Role Id"}}],"responses":{"200":{"description":"Role deleted successfully.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/api-tokens":{"post":{"tags":["api-tokens"],"summary":"Create API token","description":"Create a new API token for an organization. The full token value is only returned once upon creation — store it securely, as it cannot be retrieved later. Requires the user to have `roles.action_create` permission in the organization.","operationId":"api_create_api_token_api_v1_orgs__org_id__api_tokens_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APITokenCreate"}}}},"responses":{"200":{"description":"Token created; the full secret is included in the response (only time it is returned).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APITokenCreatedResponse"}}}},"401":{"description":"Authentication required"},"429":{"description":"Rate limit exceeded for token creation"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["api-tokens"],"summary":"List API tokens","description":"List all API tokens for an organization. Returns token metadata including the prefix, but never the full token secret. Requires `roles.action_read` permission.","operationId":"api_list_api_tokens_api_v1_orgs__org_id__api_tokens_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"responses":{"200":{"description":"List of API tokens for the organization (metadata only).","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/APITokenRead"},"title":"Response Api List Api Tokens Api V1 Orgs  Org Id  Api Tokens Get"}}}},"401":{"description":"Authentication required"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/api-tokens/{token_uuid}":{"get":{"tags":["api-tokens"],"summary":"Get API token","description":"Get details of a specific API token. Returns token metadata, but never the full token secret.","operationId":"api_get_api_token_api_v1_orgs__org_id__api_tokens__token_uuid__get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"token_uuid","in":"path","required":true,"schema":{"type":"string","title":"Token Uuid"}}],"responses":{"200":{"description":"API token metadata.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APITokenRead"}}}},"401":{"description":"Authentication required"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["api-tokens"],"summary":"Update API token","description":"Update an API token's name, description, rights, or expiration. The token secret cannot be changed here — use the regenerate endpoint for that. Requires `roles.action_update` permission.","operationId":"api_update_api_token_api_v1_orgs__org_id__api_tokens__token_uuid__put","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"token_uuid","in":"path","required":true,"schema":{"type":"string","title":"Token Uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APITokenUpdate"}}}},"responses":{"200":{"description":"Token metadata updated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APITokenRead"}}}},"401":{"description":"Authentication required"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["api-tokens"],"summary":"Revoke API token","description":"Revoke an API token. The token will immediately stop working and this action cannot be undone. Requires `roles.action_delete` permission.","operationId":"api_revoke_api_token_api_v1_orgs__org_id__api_tokens__token_uuid__delete","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"token_uuid","in":"path","required":true,"schema":{"type":"string","title":"Token Uuid"}}],"responses":{"200":{"description":"Token revoked successfully.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Api Revoke Api Token Api V1 Orgs  Org Id  Api Tokens  Token Uuid  Delete"}}}},"401":{"description":"Authentication required"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/api-tokens/{token_uuid}/regenerate":{"post":{"tags":["api-tokens"],"summary":"Regenerate API token secret","description":"Regenerate the secret for an API token. The old token will immediately stop working. The new full token value is only returned once — store it securely. Requires `roles.action_update` permission.","operationId":"api_regenerate_api_token_api_v1_orgs__org_id__api_tokens__token_uuid__regenerate_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"token_uuid","in":"path","required":true,"schema":{"type":"string","title":"Token Uuid"}}],"responses":{"200":{"description":"Token secret regenerated; new full secret is returned.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APITokenCreatedResponse"}}}},"401":{"description":"Authentication required"},"429":{"description":"Rate limit exceeded for token regeneration"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/webhooks/events":{"get":{"tags":["webhooks"],"summary":"List available webhook event types","description":"Returns the catalogue of webhook event types supported by LearnHouse along with their descriptions.","operationId":"api_list_webhook_events_api_v1_orgs__org_id__webhooks_events_get","responses":{"200":{"description":"Dictionary of event types and their descriptions","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Api List Webhook Events Api V1 Orgs  Org Id  Webhooks Events Get"}}}}}}},"/api/v1/orgs/{org_id}/webhooks":{"post":{"tags":["webhooks"],"summary":"Create a webhook endpoint","description":"Creates a new webhook endpoint for the organization. The signing secret is only returned once upon creation and cannot be retrieved later; store it securely.","operationId":"api_create_webhook_endpoint_api_v1_orgs__org_id__webhooks_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointCreate"}}}},"responses":{"200":{"description":"Webhook endpoint created; signing secret included","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointCreatedResponse"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to manage webhooks for this organization"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["webhooks"],"summary":"List webhook endpoints","description":"Returns all webhook endpoints configured for the given organization.","operationId":"api_list_webhook_endpoints_api_v1_orgs__org_id__webhooks_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"responses":{"200":{"description":"List of webhook endpoints","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEndpointRead"},"title":"Response 200 Api List Webhook Endpoints Api V1 Orgs  Org Id  Webhooks Get"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to view webhooks for this organization"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/webhooks/{webhook_uuid}":{"get":{"tags":["webhooks"],"summary":"Get a webhook endpoint","description":"Returns details of a specific webhook endpoint by its UUID.","operationId":"api_get_webhook_endpoint_api_v1_orgs__org_id__webhooks__webhook_uuid__get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"webhook_uuid","in":"path","required":true,"schema":{"type":"string","title":"Webhook Uuid"}}],"responses":{"200":{"description":"Webhook endpoint details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to view this webhook"},"404":{"description":"Webhook endpoint not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["webhooks"],"summary":"Update a webhook endpoint","description":"Updates mutable fields of a webhook endpoint (URL, subscribed events, active flag).","operationId":"api_update_webhook_endpoint_api_v1_orgs__org_id__webhooks__webhook_uuid__put","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"webhook_uuid","in":"path","required":true,"schema":{"type":"string","title":"Webhook Uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointUpdate"}}}},"responses":{"200":{"description":"Webhook endpoint updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to modify this webhook"},"404":{"description":"Webhook endpoint not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["webhooks"],"summary":"Delete a webhook endpoint","description":"Deletes a webhook endpoint along with all of its delivery logs.","operationId":"api_delete_webhook_endpoint_api_v1_orgs__org_id__webhooks__webhook_uuid__delete","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"webhook_uuid","in":"path","required":true,"schema":{"type":"string","title":"Webhook Uuid"}}],"responses":{"200":{"description":"Webhook endpoint deleted","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Api Delete Webhook Endpoint Api V1 Orgs  Org Id  Webhooks  Webhook Uuid  Delete"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to delete this webhook"},"404":{"description":"Webhook endpoint not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/webhooks/{webhook_uuid}/regenerate-secret":{"post":{"tags":["webhooks"],"summary":"Regenerate a webhook signing secret","description":"Regenerates the signing secret for a webhook endpoint. The new secret is only returned once and must be stored securely.","operationId":"api_regenerate_webhook_secret_api_v1_orgs__org_id__webhooks__webhook_uuid__regenerate_secret_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"webhook_uuid","in":"path","required":true,"schema":{"type":"string","title":"Webhook Uuid"}}],"responses":{"200":{"description":"Webhook signing secret regenerated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointCreatedResponse"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to manage this webhook"},"404":{"description":"Webhook endpoint not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/webhooks/{webhook_uuid}/test":{"post":{"tags":["webhooks"],"summary":"Send a test webhook event","description":"Sends a synthetic 'ping' event to the webhook endpoint to verify it is reachable and correctly configured.","operationId":"api_send_test_event_api_v1_orgs__org_id__webhooks__webhook_uuid__test_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"webhook_uuid","in":"path","required":true,"schema":{"type":"string","title":"Webhook Uuid"}}],"responses":{"200":{"description":"Test event delivered (or attempted) successfully","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Api Send Test Event Api V1 Orgs  Org Id  Webhooks  Webhook Uuid  Test Post"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to manage this webhook"},"404":{"description":"Webhook endpoint not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/webhooks/{webhook_uuid}/deliveries":{"get":{"tags":["webhooks"],"summary":"List webhook delivery logs","description":"Returns recent webhook delivery attempts and their outcomes for the specified endpoint, up to the requested limit.","operationId":"api_get_webhook_deliveries_api_v1_orgs__org_id__webhooks__webhook_uuid__deliveries_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"webhook_uuid","in":"path","required":true,"schema":{"type":"string","title":"Webhook Uuid"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"List of webhook delivery log entries","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WebhookDeliveryLogRead"},"title":"Response 200 Api Get Webhook Deliveries Api V1 Orgs  Org Id  Webhooks  Webhook Uuid  Deliveries Get"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to view this webhook"},"404":{"description":"Webhook endpoint not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/integrations/zapier/me":{"get":{"tags":["integrations","zapier"],"summary":"Identify Zapier caller","description":"Return the organization and token identity for the current Zapier API token. Used by Zapier as the auth test endpoint.","operationId":"zapier_me_api_v1_integrations_zapier_me_get","responses":{"200":{"description":"Organization and token identity for the current Zapier caller.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ZapierMeResponse"}}}},"401":{"description":"Missing or invalid API token"},"403":{"description":"Organization plan does not include Zapier integration (Pro+ required)"},"404":{"description":"Organization not found for this token"}}}},"/api/v1/integrations/zapier/events":{"get":{"tags":["integrations","zapier"],"summary":"List webhook events","description":"List every webhook event name a Zap can subscribe to.","operationId":"zapier_list_events_api_v1_integrations_zapier_events_get","responses":{"200":{"description":"Dictionary with `events`: the full list of supported event names.","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Zapier List Events Api V1 Integrations Zapier Events Get"}}}},"401":{"description":"Missing or invalid API token"},"403":{"description":"Organization plan does not include Zapier integration (Pro+ required)"}}}},"/api/v1/integrations/zapier/courses":{"get":{"tags":["integrations","zapier"],"summary":"List courses for Zapier","description":"List courses in the caller's organization for use as Zapier trigger samples. Maximum 500 rows.","operationId":"zapier_list_courses_api_v1_integrations_zapier_courses_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"title":"Limit"}}],"responses":{"200":{"description":"List of courses in the caller's organization.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ZapierCourseItem"},"title":"Response Zapier List Courses Api V1 Integrations Zapier Courses Get"}}}},"401":{"description":"Missing or invalid API token"},"403":{"description":"Organization plan does not include Zapier integration (Pro+ required)"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/integrations/zapier/users":{"get":{"tags":["integrations","zapier"],"summary":"List users for Zapier","description":"List users that belong to the caller's organization for use as Zapier trigger samples. Maximum 500 rows.","operationId":"zapier_list_users_api_v1_integrations_zapier_users_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"title":"Limit"}}],"responses":{"200":{"description":"List of users in the caller's organization.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ZapierUserItem"},"title":"Response Zapier List Users Api V1 Integrations Zapier Users Get"}}}},"401":{"description":"Missing or invalid API token"},"403":{"description":"Organization plan does not include Zapier integration (Pro+ required)"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/integrations/zapier/usergroups":{"get":{"tags":["integrations","zapier"],"summary":"List user groups for Zapier","description":"List cohorts / user groups in the caller's organization. Maximum 500 rows.","operationId":"zapier_list_usergroups_api_v1_integrations_zapier_usergroups_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"title":"Limit"}}],"responses":{"200":{"description":"List of user groups in the caller's organization.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ZapierUserGroupItem"},"title":"Response Zapier List Usergroups Api V1 Integrations Zapier Usergroups Get"}}}},"401":{"description":"Missing or invalid API token"},"403":{"description":"Organization plan does not include Zapier integration (Pro+ required)"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/integrations/zapier/subscriptions":{"get":{"tags":["integrations","zapier"],"summary":"List Zap subscriptions","description":"List every active Zapier REST Hook subscription for the caller's organization.","operationId":"zapier_list_subscriptions_api_v1_integrations_zapier_subscriptions_get","responses":{"200":{"description":"List of Zapier subscriptions for the caller's organization.","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ZapierSubscriptionResponse"},"type":"array","title":"Response Zapier List Subscriptions Api V1 Integrations Zapier Subscriptions Get"}}}},"401":{"description":"Missing or invalid API token"},"403":{"description":"Organization plan does not include Zapier integration (Pro+ required)"}}},"post":{"tags":["integrations","zapier"],"summary":"Create Zap subscription","description":"Register a Zapier REST Hook subscription. Called by Zapier when a Zap is enabled. Creates a webhook endpoint tagged `source=\"zapier\"` that the dispatcher will deliver events to.","operationId":"zapier_create_subscription_api_v1_integrations_zapier_subscriptions_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ZapierSubscriptionCreate"}}},"required":true},"responses":{"201":{"description":"Subscription created — webhook endpoint registered for the given event.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ZapierSubscriptionResponse"}}}},"400":{"description":"Unknown event name or invalid target URL (SSRF guard)"},"401":{"description":"Missing or invalid API token"},"403":{"description":"Organization plan does not include Zapier integration (Pro+ required)"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/integrations/zapier/subscriptions/{subscription_id}":{"delete":{"tags":["integrations","zapier"],"summary":"Delete Zap subscription","description":"Delete a Zapier REST Hook subscription. Called by Zapier when a Zap is disabled or deleted.","operationId":"zapier_delete_subscription_api_v1_integrations_zapier_subscriptions__subscription_id__delete","parameters":[{"name":"subscription_id","in":"path","required":true,"schema":{"type":"integer","title":"Subscription Id"}}],"responses":{"200":{"description":"Subscription deleted.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Zapier Delete Subscription Api V1 Integrations Zapier Subscriptions  Subscription Id  Delete"}}}},"401":{"description":"Missing or invalid API token"},"403":{"description":"Organization plan does not include Zapier integration (Pro+ required)"},"404":{"description":"Subscription not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/domains":{"post":{"tags":["custom-domains"],"summary":"Add a custom domain","description":"Add a new custom domain to an organization. This generates a verification token and returns DNS instructions. Only organization administrators can add custom domains.","operationId":"api_add_custom_domain_api_v1_orgs__org_id__domains_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomDomainCreate"}}}},"responses":{"200":{"description":"Custom domain registered with DNS verification instructions.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomDomainRead"}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not an organization administrator"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["custom-domains"],"summary":"List custom domains","description":"List all custom domains for an organization, including their verification status.","operationId":"api_list_custom_domains_api_v1_orgs__org_id__domains_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"responses":{"200":{"description":"List of custom domains for the organization.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CustomDomainRead"},"title":"Response 200 Api List Custom Domains Api V1 Orgs  Org Id  Domains Get"}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not a member of the organization"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/domains/{domain_uuid}":{"get":{"tags":["custom-domains"],"summary":"Get a custom domain","description":"Get details of a single custom domain by its UUID, including verification status.","operationId":"api_get_custom_domain_api_v1_orgs__org_id__domains__domain_uuid__get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"domain_uuid","in":"path","required":true,"schema":{"type":"string","title":"Domain Uuid"}}],"responses":{"200":{"description":"Custom domain details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomDomainRead"}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not a member of the organization"},"404":{"description":"Organization or custom domain not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["custom-domains"],"summary":"Delete a custom domain","description":"Delete a custom domain. This action cannot be undone. Only organization administrators can delete custom domains.","operationId":"api_delete_custom_domain_api_v1_orgs__org_id__domains__domain_uuid__delete","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"domain_uuid","in":"path","required":true,"schema":{"type":"string","title":"Domain Uuid"}}],"responses":{"200":{"description":"Custom domain deleted.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Api Delete Custom Domain Api V1 Orgs  Org Id  Domains  Domain Uuid  Delete"}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not an organization administrator"},"404":{"description":"Organization or custom domain not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/domains/{domain_uuid}/verification-info":{"get":{"tags":["custom-domains"],"summary":"Get DNS verification info","description":"Return the DNS records (TXT and CNAME) that must be configured at the domain provider in order to verify the custom domain.","operationId":"api_get_domain_verification_info_api_v1_orgs__org_id__domains__domain_uuid__verification_info_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"domain_uuid","in":"path","required":true,"schema":{"type":"string","title":"Domain Uuid"}}],"responses":{"200":{"description":"DNS verification instructions for the custom domain.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomDomainVerificationInfo"}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not a member of the organization"},"404":{"description":"Organization or custom domain not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/domains/{domain_uuid}/verify":{"post":{"tags":["custom-domains"],"summary":"Verify custom domain DNS","description":"Verify the DNS configuration for a custom domain by checking that the expected TXT verification record is in place. Only organization administrators can verify domains.","operationId":"api_verify_custom_domain_api_v1_orgs__org_id__domains__domain_uuid__verify_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"domain_uuid","in":"path","required":true,"schema":{"type":"string","title":"Domain Uuid"}}],"responses":{"200":{"description":"DNS verification result for the custom domain.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Api Verify Custom Domain Api V1 Orgs  Org Id  Domains  Domain Uuid  Verify Post"}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not an organization administrator"},"404":{"description":"Organization or custom domain not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/domains/{domain_uuid}/ssl-status":{"get":{"tags":["custom-domains"],"summary":"Check custom domain SSL status","description":"Check the SSL certificate status for a custom domain by performing a TLS handshake to determine whether a certificate has been provisioned.","operationId":"api_check_domain_ssl_status_api_v1_orgs__org_id__domains__domain_uuid__ssl_status_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"domain_uuid","in":"path","required":true,"schema":{"type":"string","title":"Domain Uuid"}}],"responses":{"200":{"description":"SSL certificate status for the custom domain.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Api Check Domain Ssl Status Api V1 Orgs  Org Id  Domains  Domain Uuid  Ssl Status Get"}}}},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not a member of the organization"},"404":{"description":"Organization or custom domain not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/resolve/domain/{domain}":{"get":{"tags":["custom-domains"],"summary":"Resolve custom domain to organization","description":"Public endpoint used by the frontend proxy to route custom domain requests to the correct organization. Returns 404 if the domain is not registered or not verified.","operationId":"api_resolve_domain_api_v1_orgs_resolve_domain__domain__get","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","title":"Domain"}}],"responses":{"200":{"description":"Organization that owns the requested custom domain.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomDomainResolveResponse"}}}},"404":{"description":"Domain not found or not verified"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/domains/check":{"get":{"tags":["custom-domains"],"summary":"Check whether a custom domain is registered and verified","description":"Returns 200 if `domain` is registered against an organization and has status `verified` or `active`; 404 otherwise. Takes the hostname as a query parameter so the endpoint composes cleanly with reverse proxies that want a lightweight allow/deny gate (e.g. for on-demand TLS provisioning) without needing path rewriting.","operationId":"api_check_domain_api_v1_orgs_domains_check_get","parameters":[{"name":"domain","in":"query","required":true,"schema":{"type":"string","title":"Domain"}}],"responses":{"200":{"description":"Domain is registered and verified.","content":{"application/json":{"schema":{}}}},"404":{"description":"Domain is not registered or not verified."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/internal/domains/verified":{"get":{"tags":["custom-domains-internal"],"summary":"List all verified custom domains","description":"Return every verified custom domain across all organizations. Protected by an internal API key and used by the domain sync CronJob.","operationId":"api_list_all_verified_domains_api_v1_internal_domains_verified_get","parameters":[{"name":"x-internal-key","in":"header","required":true,"schema":{"type":"string","title":"X-Internal-Key"}}],"responses":{"200":{"description":"List of every verified custom domain across organizations.","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true},"title":"Response Api List All Verified Domains Api V1 Internal Domains Verified Get"}}}},"403":{"description":"Invalid internal API key"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/internal/packs/{org_id}/activate":{"post":{"tags":["packs-internal"],"summary":"Activate a pack for an organization","description":"Internal endpoint used by the billing platform to activate a pack on an organization after a successful purchase. Requires a valid platform API key.","operationId":"api_activate_pack_api_v1_internal_packs__org_id__activate_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"x-platform-key","in":"header","required":true,"schema":{"type":"string","title":"X-Platform-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivatePackRequest"}}}},"responses":{"200":{"description":"Pack activated for the organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgPackRead"}}}},"403":{"description":"Invalid platform API key"},"500":{"description":"LEARNHOUSE_PLATFORM_API_KEY is not configured on the server"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/internal/packs/{org_id}/mark-canceling":{"patch":{"tags":["packs-internal"],"summary":"Mark a pack as canceling","description":"Internal endpoint used by the billing platform to mark a pack as pending cancellation for the given subscription. Requires a valid platform API key.","operationId":"api_mark_pack_canceling_api_v1_internal_packs__org_id__mark_canceling_patch","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"x-platform-key","in":"header","required":true,"schema":{"type":"string","title":"X-Platform-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarkCancelingRequest"}}}},"responses":{"200":{"description":"Pack marked as canceling.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgPackRead"}}}},"403":{"description":"Invalid platform API key"},"500":{"description":"LEARNHOUSE_PLATFORM_API_KEY is not configured on the server"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/internal/packs/{org_id}/deactivate":{"delete":{"tags":["packs-internal"],"summary":"Deactivate a pack","description":"Internal endpoint used by the billing platform to deactivate a single pack tied to a subscription ID. Requires a valid platform API key.","operationId":"api_deactivate_pack_api_v1_internal_packs__org_id__deactivate_delete","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"x-platform-key","in":"header","required":true,"schema":{"type":"string","title":"X-Platform-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeactivatePackRequest"}}}},"responses":{"200":{"description":"Pack deactivated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgPackRead"}}}},"403":{"description":"Invalid platform API key"},"500":{"description":"LEARNHOUSE_PLATFORM_API_KEY is not configured on the server"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/internal/packs/{org_id}/deactivate-all":{"delete":{"tags":["packs-internal"],"summary":"Deactivate all packs for an organization","description":"Internal endpoint used by the billing platform to deactivate every pack currently attached to the organization. Requires a valid platform API key.","operationId":"api_deactivate_all_packs_api_v1_internal_packs__org_id__deactivate_all_delete","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"x-platform-key","in":"header","required":true,"schema":{"type":"string","title":"X-Platform-Key"}}],"responses":{"200":{"description":"All packs deactivated; returns the number of packs affected.","content":{"application/json":{"schema":{}}}},"403":{"description":"Invalid platform API key"},"500":{"description":"LEARNHOUSE_PLATFORM_API_KEY is not configured on the server"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/packs":{"get":{"tags":["packs"],"summary":"List active and available packs","description":"Return the organization's active packs along with the full catalog of available packs. Only organization admins can view packs.","operationId":"api_get_org_packs_api_v1_orgs__org_id__packs_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"responses":{"200":{"description":"Active packs and available pack catalog.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgPacksResponse"}}}},"403":{"description":"Only organization admins can view packs"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/orgs/{org_id}/packs/summary":{"get":{"tags":["packs"],"summary":"Get pack totals summary","description":"Return aggregated totals from the organization's active packs (AI credits, member seats, and active pack count). Only organization admins can view the summary.","operationId":"api_get_org_pack_summary_api_v1_orgs__org_id__packs_summary_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"responses":{"200":{"description":"Aggregated pack totals for the organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PackSummaryResponse"}}}},"403":{"description":"Only organization admins can view pack summary"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/cloud_internal/update_org_plan":{"put":{"tags":["cloud_internal"],"summary":"Update an organization plan","description":"Update an organization's plan. Only changes the plan string; all feature limits and enabled flags are resolved at runtime from the plan name via plans.py. Requires the internal cloud key header.","operationId":"update_org_plan_api_v1_cloud_internal_update_org_plan_put","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateOrgPlanRequest"}}},"required":true},"responses":{"200":{"description":"Plan updated successfully.","content":{"application/json":{"schema":{}}}},"400":{"description":"Unknown plan name"},"403":{"description":"Missing or invalid CloudInternalKey header"},"404":{"description":"Organization or organization config not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/cloud_internal/reconcile_loops_admins":{"post":{"tags":["cloud-internal"],"summary":"Backfill existing org admins into the Loops marketing audience","description":"Enumerate every current org ADMIN (role_id=1) across all organizations and ensure each is on the Loops mailing list. Idempotent — Loops contact upsert means re-running is safe. Protected by the internal cloud key (X-Internal-Key header). Best-effort & SaaS-only; a no-op when LOOPS_API_KEY is unset. The sync itself is fire-and-forget, so a 200 means the sync was scheduled for each admin, not that Loops acknowledged every contact.","operationId":"api_reconcile_loops_admins_api_v1_cloud_internal_reconcile_loops_admins_post","parameters":[{"name":"x-internal-key","in":"header","required":true,"schema":{"type":"string","title":"X-Internal-Key"}}],"responses":{"200":{"description":"Reconcile scheduled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReconcileAdminsResponse"}}}},"403":{"description":"Invalid internal API key"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/blocks/image":{"post":{"tags":["blocks"],"summary":"Create image block","description":"Upload an image file and create a new image block attached to the given activity.","operationId":"api_create_image_file_block_api_v1_blocks_image_post","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_api_create_image_file_block_api_v1_blocks_image_post"}}}},"responses":{"200":{"description":"Image block created and returned.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlockRead"}}}},"401":{"description":"Authentication required"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["blocks"],"summary":"Get image block","description":"Retrieve an image block by its UUID.","operationId":"api_get_image_file_block_api_v1_blocks_image_get","parameters":[{"name":"block_uuid","in":"query","required":true,"schema":{"type":"string","title":"Block Uuid"}}],"responses":{"200":{"description":"Image block returned.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlockRead"}}}},"401":{"description":"Authentication required"},"404":{"description":"Image block not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/blocks/video":{"post":{"tags":["blocks"],"summary":"Create video block","description":"Upload a video file and create a new video block attached to the given activity.","operationId":"api_create_video_file_block_api_v1_blocks_video_post","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_api_create_video_file_block_api_v1_blocks_video_post"}}}},"responses":{"200":{"description":"Video block created and returned.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlockRead"}}}},"401":{"description":"Authentication required"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["blocks"],"summary":"Get video block","description":"Retrieve a video block by its UUID.","operationId":"api_get_video_file_block_api_v1_blocks_video_get","parameters":[{"name":"block_uuid","in":"query","required":true,"schema":{"type":"string","title":"Block Uuid"}}],"responses":{"200":{"description":"Video block returned.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlockRead"}}}},"401":{"description":"Authentication required"},"404":{"description":"Video block not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/blocks/pdf":{"post":{"tags":["blocks"],"summary":"Create PDF block","description":"Upload a PDF file and create a new PDF block attached to the given activity.","operationId":"api_create_pdf_file_block_api_v1_blocks_pdf_post","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_api_create_pdf_file_block_api_v1_blocks_pdf_post"}}}},"responses":{"200":{"description":"PDF block created and returned.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlockRead"}}}},"401":{"description":"Authentication required"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["blocks"],"summary":"Get PDF block","description":"Retrieve a PDF block by its UUID.","operationId":"api_get_pdf_file_block_api_v1_blocks_pdf_get","parameters":[{"name":"block_uuid","in":"query","required":true,"schema":{"type":"string","title":"Block Uuid"}}],"responses":{"200":{"description":"PDF block returned.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlockRead"}}}},"401":{"description":"Authentication required"},"404":{"description":"PDF block not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/blocks/audio":{"post":{"tags":["blocks"],"summary":"Create audio block","description":"Upload an audio file and create a new audio block attached to the given activity.","operationId":"api_create_audio_file_block_api_v1_blocks_audio_post","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_api_create_audio_file_block_api_v1_blocks_audio_post"}}}},"responses":{"200":{"description":"Audio block created and returned.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlockRead"}}}},"401":{"description":"Authentication required"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["blocks"],"summary":"Get audio block","description":"Retrieve an audio block by its UUID.","operationId":"api_get_audio_file_block_api_v1_blocks_audio_get","parameters":[{"name":"block_uuid","in":"query","required":true,"schema":{"type":"string","title":"Block Uuid"}}],"responses":{"200":{"description":"Audio block returned.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlockRead"}}}},"401":{"description":"Authentication required"},"404":{"description":"Audio block not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/{org_slug}/auth/token":{"post":{"tags":["admin"],"summary":"Issue a user token","description":"Issue a JWT access token on behalf of a user. The user must belong to the organization matching the org_slug. Requires `users.action_read` permission.","operationId":"api_admin_issue_token_api_v1_admin__org_slug__auth_token_post","parameters":[{"name":"org_slug","in":"path","required":true,"schema":{"type":"string","title":"Org Slug"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IssueTokenRequest"}}}},"responses":{"200":{"description":"Access token minted on behalf of the target user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenResponse"}}}},"403":{"description":"API token lacks permission, user not in org, or org_slug mismatch"},"404":{"description":"User or organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/{org_slug}/courses/{course_uuid}/access/{user_id}":{"get":{"tags":["admin"],"summary":"Check user course access","description":"Check if a user can access a specific course. Returns enrollment status and whether the course is public. Requires `courses.action_read` permission.","operationId":"api_admin_check_course_access_api_v1_admin__org_slug__courses__course_uuid__access__user_id__get","parameters":[{"name":"org_slug","in":"path","required":true,"schema":{"type":"string","title":"Org Slug"}},{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","title":"Course Uuid"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}}],"responses":{"200":{"description":"Access check result — whether the user can view the course.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CourseAccessResponse"}}}},"404":{"description":"Course not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/{org_slug}/enrollments/bulk/unenroll":{"post":{"tags":["admin"],"summary":"Bulk unenroll users from a course","description":"Mirror of bulk enroll. Users not currently enrolled are reported in `not_enrolled`.","operationId":"api_admin_bulk_unenroll_api_v1_admin__org_slug__enrollments_bulk_unenroll_post","parameters":[{"name":"org_slug","in":"path","required":true,"schema":{"type":"string","title":"Org Slug"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkUnenrollRequest"}}}},"responses":{"200":{"description":"Per-user unenroll summary: unenrolled, not_enrolled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkUnenrollResponse"}}}},"404":{"description":"Course not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/{org_slug}/enrollments/{user_id}/{course_uuid}":{"post":{"tags":["admin"],"summary":"Enroll user in course","description":"Enroll a user in a course on their behalf. Creates the learning trail and trail run. The user must belong to the organization. Requires `courses.action_read` permission.","operationId":"api_admin_enroll_user_api_v1_admin__org_slug__enrollments__user_id___course_uuid__post","parameters":[{"name":"org_slug","in":"path","required":true,"schema":{"type":"string","title":"Org Slug"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}},{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","title":"Course Uuid"}}],"responses":{"200":{"description":"User enrolled — returns the user's updated trail with all runs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrailRead"}}}},"400":{"description":"User is already enrolled"},"404":{"description":"User or course not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["admin"],"summary":"Unenroll user from course","description":"Unenroll a user from a course. Removes the enrollment and all associated progress (trail steps). Requires `courses.action_read` permission.","operationId":"api_admin_unenroll_user_api_v1_admin__org_slug__enrollments__user_id___course_uuid__delete","parameters":[{"name":"org_slug","in":"path","required":true,"schema":{"type":"string","title":"Org Slug"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}},{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","title":"Course Uuid"}}],"responses":{"200":{"description":"User unenrolled — trail steps for this course are deleted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnenrollResponse"}}}},"404":{"description":"Enrollment not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/{org_slug}/enrollments/{user_id}":{"get":{"tags":["admin"],"summary":"Get user enrollments","description":"Get all course enrollments for a user in the organization, including trail runs and steps. Requires `courses.action_read` permission.","operationId":"api_admin_get_user_enrollments_api_v1_admin__org_slug__enrollments__user_id__get","parameters":[{"name":"org_slug","in":"path","required":true,"schema":{"type":"string","title":"Org Slug"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}}],"responses":{"200":{"description":"The user's trail with every course enrollment and step.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrailRead"}}}},"404":{"description":"User not found or not a member of this organization"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/{org_slug}/progress/{user_id}/{course_uuid}":{"get":{"tags":["admin"],"summary":"Get user progress in course","description":"Get a user's progress in a specific course including completion percentage and list of completed activity IDs. Requires `courses.action_read` permission.","operationId":"api_admin_get_user_progress_api_v1_admin__org_slug__progress__user_id___course_uuid__get","parameters":[{"name":"org_slug","in":"path","required":true,"schema":{"type":"string","title":"Org Slug"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}},{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","title":"Course Uuid"}}],"responses":{"200":{"description":"Progress summary (completion percentage + completed activity ids).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProgressResponse"}}}},"404":{"description":"Course not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/{org_slug}/progress/{user_id}/activities/{activity_uuid}/complete":{"post":{"tags":["admin"],"summary":"Mark activity as completed","description":"Mark an activity as completed on behalf of a user. Automatically creates enrollment if needed. If this completes the entire course, a certificate is awarded (if configured). Requires `courses.action_read` permission.","operationId":"api_admin_complete_activity_api_v1_admin__org_slug__progress__user_id__activities__activity_uuid__complete_post","parameters":[{"name":"org_slug","in":"path","required":true,"schema":{"type":"string","title":"Org Slug"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}},{"name":"activity_uuid","in":"path","required":true,"schema":{"type":"string","title":"Activity Uuid"}}],"responses":{"200":{"description":"Activity marked complete; includes whether this completed the course.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivityCompletionResponse"}}}},"404":{"description":"Activity not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["admin"],"summary":"Undo activity completion","description":"Remove a user's activity completion. Does not revoke certificates. Requires `courses.action_read` permission.","operationId":"api_admin_uncomplete_activity_api_v1_admin__org_slug__progress__user_id__activities__activity_uuid__complete_delete","parameters":[{"name":"org_slug","in":"path","required":true,"schema":{"type":"string","title":"Org Slug"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}},{"name":"activity_uuid","in":"path","required":true,"schema":{"type":"string","title":"Activity Uuid"}}],"responses":{"200":{"description":"Activity completion removed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivityUncompletionResponse"}}}},"404":{"description":"Activity not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/{org_slug}/progress/{user_id}/{course_uuid}/complete":{"post":{"tags":["admin"],"summary":"Mark entire course as completed","description":"Mark all activities in a course as completed for a user. Skips activities that are already completed. Awards a certificate if configured. Requires `courses.action_read` permission.","operationId":"api_admin_complete_course_api_v1_admin__org_slug__progress__user_id___course_uuid__complete_post","parameters":[{"name":"org_slug","in":"path","required":true,"schema":{"type":"string","title":"Org Slug"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}},{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","title":"Course Uuid"}}],"responses":{"200":{"description":"All activities marked complete; indicates whether a certificate was awarded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CourseCompletionResponse"}}}},"404":{"description":"Course not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/{org_slug}/progress/{user_id}":{"get":{"tags":["admin"],"summary":"Get all user progress","description":"Get a progress summary across all courses a user is enrolled in. Returns completion percentage and status for each enrollment. Requires `courses.action_read` permission.","operationId":"api_admin_get_all_user_progress_api_v1_admin__org_slug__progress__user_id__get","parameters":[{"name":"org_slug","in":"path","required":true,"schema":{"type":"string","title":"Org Slug"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}}],"responses":{"200":{"description":"One row per course enrollment with completion percentage and status.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ProgressSummaryItem"},"title":"Response Api Admin Get All User Progress Api V1 Admin  Org Slug  Progress  User Id  Get"}}}},"404":{"description":"User not found or not a member of this organization"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/{org_slug}/trails/{user_id}":{"get":{"tags":["admin"],"summary":"Get user trail with full progress breakdown","description":"Return the user's trail in the organization with a full chapter-by-chapter and activity-by-activity progress breakdown for every course they are enrolled in. Each activity carries its completion state, teacher verification flag, grade, and completion timestamp. Requires `courses.action_read` permission.","operationId":"api_admin_get_user_trail_detail_api_v1_admin__org_slug__trails__user_id__get","parameters":[{"name":"org_slug","in":"path","required":true,"schema":{"type":"string","title":"Org Slug"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}}],"responses":{"200":{"description":"Full trail breakdown grouped by course → chapter → activity.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserTrailDetail"}}}},"403":{"description":"API token lacks access to this organization"},"404":{"description":"User not found or not a member of this organization"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/{org_slug}/trails/{user_id}/courses/{course_uuid}":{"get":{"tags":["admin"],"summary":"Get user trail breakdown for a single course","description":"Return the user's full chapter-by-chapter and activity-by-activity progress breakdown for a single course. Surfaces progress even when the user has no explicit enrollment row (status will be null in that case). Requires `courses.action_read` permission.","operationId":"api_admin_get_user_course_trail_detail_api_v1_admin__org_slug__trails__user_id__courses__course_uuid__get","parameters":[{"name":"org_slug","in":"path","required":true,"schema":{"type":"string","title":"Org Slug"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}},{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","title":"Course Uuid"}}],"responses":{"200":{"description":"Full breakdown for the requested course only.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserTrailDetail"}}}},"403":{"description":"API token lacks access to this organization"},"404":{"description":"Course or user not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/{org_slug}/certifications/{user_id}":{"get":{"tags":["admin"],"summary":"Get user certificates","description":"Get all certificates awarded to a user in the organization. Includes certification details and course information. Requires `certifications.action_read` permission.","operationId":"api_admin_get_user_certificates_api_v1_admin__org_slug__certifications__user_id__get","parameters":[{"name":"org_slug","in":"path","required":true,"schema":{"type":"string","title":"Org Slug"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}}],"responses":{"200":{"description":"All certificates awarded to the user in this org.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CertificateItem"},"title":"Response Api Admin Get User Certificates Api V1 Admin  Org Slug  Certifications  User Id  Get"}}}},"404":{"description":"User not found or not a member of this organization"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/{org_slug}/users":{"post":{"tags":["admin"],"summary":"Provision a user","description":"Create a user and attach them to the organization in one call. Designed for SSO/JIT provisioning — the user's email is auto-verified and the normal email-verification flow is skipped. If a user with the given email already exists in another organization, they are attached to this org (idempotent); the password/username/name fields in the request are ignored in that case.","operationId":"api_admin_provision_user_api_v1_admin__org_slug__users_post","parameters":[{"name":"org_slug","in":"path","required":true,"schema":{"type":"string","title":"Org Slug"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProvisionUserRequest"}}}},"responses":{"200":{"description":"User created or attached to the org. Returns the user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserRead"}}}},"400":{"description":"Email already in this org, duplicate username, weak password, or invalid role_id"},"403":{"description":"Member limit reached, feature disabled, role belongs to another org, role is elevated (Admin/Maintainer), or token creator lacks privilege"},"429":{"description":"Too many provisioning requests for this token"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/{org_slug}/users/{user_id}":{"delete":{"tags":["admin"],"summary":"Remove a user from the organization","description":"Remove a user's organization membership. The user account itself is preserved (it may belong to other orgs). Blocks removing the last admin.","operationId":"api_admin_remove_user_api_v1_admin__org_slug__users__user_id__delete","parameters":[{"name":"org_slug","in":"path","required":true,"schema":{"type":"string","title":"Org Slug"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}}],"responses":{"200":{"description":"Membership removed. The user account is preserved.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemoveUserResponse"}}}},"400":{"description":"User is the last admin"},"404":{"description":"User not in org"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["admin"],"summary":"Update a user's profile","description":"Update profile fields of an org member. Supports partial updates — only fields present in the request body are changed. Duplicate email/username is rejected.","operationId":"api_admin_update_user_profile_api_v1_admin__org_slug__users__user_id__patch","parameters":[{"name":"org_slug","in":"path","required":true,"schema":{"type":"string","title":"Org Slug"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateUserRequest"}}}},"responses":{"200":{"description":"Updated user profile.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserRead"}}}},"400":{"description":"Duplicate email or username"},"404":{"description":"User not in org"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/{org_slug}/users/by-email/{email}":{"get":{"tags":["admin"],"summary":"Look up a user by email","description":"Find a user by email within the organization. Returns 404 if the user does not exist or is not a member of this org.","operationId":"api_admin_get_user_by_email_api_v1_admin__org_slug__users_by_email__email__get","parameters":[{"name":"org_slug","in":"path","required":true,"schema":{"type":"string","title":"Org Slug"}},{"name":"email","in":"path","required":true,"schema":{"type":"string","description":"URL-encoded email address","title":"Email"},"description":"URL-encoded email address"}],"responses":{"200":{"description":"The user matching the given email within this org.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserRead"}}}},"404":{"description":"User not found in this organization"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/{org_slug}/auth/magic-link":{"post":{"tags":["admin"],"summary":"Issue a magic sign-in link","description":"Generate a short-lived URL that, when opened in a browser, will log the target user in and optionally redirect them to a specific path. Token lifetime is clamped to 60–900 seconds.","operationId":"api_admin_issue_magic_link_api_v1_admin__org_slug__auth_magic_link_post","parameters":[{"name":"org_slug","in":"path","required":true,"schema":{"type":"string","title":"Org Slug"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MagicLinkRequest"}}}},"responses":{"200":{"description":"Magic sign-in URL and underlying JWT. Token lifetime is already clamped.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MagicLinkResponse"}}}},"400":{"description":"redirect_to is not a same-origin path"},"403":{"description":"User not in this org"},"404":{"description":"User not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/{org_slug}/auth/magic-consume":{"get":{"tags":["admin"],"summary":"Consume a magic sign-in link (browser-facing)","description":"Public endpoint — no API token required. Validates the magic-link JWT from the query string, sets authentication cookies, and redirects to the target path. On error, renders a friendly HTML page with a support link instead of a raw JSON error.","operationId":"api_admin_magic_consume_api_v1_admin__org_slug__auth_magic_consume_get","parameters":[{"name":"org_slug","in":"path","required":true,"schema":{"type":"string","title":"Org Slug"}},{"name":"token","in":"query","required":true,"schema":{"type":"string","description":"Magic-link JWT","title":"Token"},"description":"Magic-link JWT"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"302":{"description":"Success — cookies set and redirect to target"},"410":{"description":"Token invalid, expired, or user no longer a member (HTML page)"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/{org_slug}/enrollments/bulk":{"post":{"tags":["admin"],"summary":"Bulk enroll users in a course","description":"Enroll a batch of users into a single course. Users who are already enrolled are reported in `already_enrolled`. Users who are not members of the org are reported in `skipped`.","operationId":"api_admin_bulk_enroll_api_v1_admin__org_slug__enrollments_bulk_post","parameters":[{"name":"org_slug","in":"path","required":true,"schema":{"type":"string","title":"Org Slug"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkEnrollRequest"}}}},"responses":{"200":{"description":"Per-user enrollment summary: enrolled, already_enrolled, skipped.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkEnrollResponse"}}}},"404":{"description":"Course not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/{org_slug}/courses/{course_uuid}/enrollments":{"get":{"tags":["admin"],"summary":"List users enrolled in a course","description":"Reverse lookup: get all users currently enrolled in a course, with pagination. Returns enrollment status and enrolled_at per user.","operationId":"api_admin_list_course_enrollments_api_v1_admin__org_slug__courses__course_uuid__enrollments_get","parameters":[{"name":"org_slug","in":"path","required":true,"schema":{"type":"string","title":"Org Slug"}},{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","title":"Course Uuid"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":25,"title":"Limit"}}],"responses":{"200":{"description":"One row per enrolled user in this course, with status and enrolled_at.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CourseEnrollmentItem"},"title":"Response Api Admin List Course Enrollments Api V1 Admin  Org Slug  Courses  Course Uuid  Enrollments Get"}}}},"404":{"description":"Course not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/{org_slug}/progress/{user_id}/{course_uuid}/reset":{"post":{"tags":["admin"],"summary":"Reset a user's progress in a course","description":"Delete all of a user's trail steps for a course, keeping the enrollment intact. The user can retake the course from scratch.","operationId":"api_admin_reset_user_progress_api_v1_admin__org_slug__progress__user_id___course_uuid__reset_post","parameters":[{"name":"org_slug","in":"path","required":true,"schema":{"type":"string","title":"Org Slug"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}},{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","title":"Course Uuid"}}],"responses":{"200":{"description":"Returns the number of trail steps deleted for this user/course.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResetProgressResponse"}}}},"404":{"description":"User or course not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/{org_slug}/certifications/{user_id}/{course_uuid}/award":{"post":{"tags":["admin"],"summary":"Manually award a certificate","description":"Award a certificate to a user bypassing the normal completion gate. Useful for migrations and manual overrides. The course must have a certification configured.","operationId":"api_admin_award_certificate_api_v1_admin__org_slug__certifications__user_id___course_uuid__award_post","parameters":[{"name":"org_slug","in":"path","required":true,"schema":{"type":"string","title":"Org Slug"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}},{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","title":"Course Uuid"}}],"responses":{"200":{"description":"Certificate awarded; returns the new user_certification_uuid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AwardCertificateResponse"}}}},"400":{"description":"User already has a certificate for this course"},"404":{"description":"Course or certification not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/{org_slug}/certifications/{user_id}/{user_certification_uuid}":{"delete":{"tags":["admin"],"summary":"Revoke a user's certificate","description":"Delete a certificate row. Does not affect course enrollment or progress.","operationId":"api_admin_revoke_certificate_api_v1_admin__org_slug__certifications__user_id___user_certification_uuid__delete","parameters":[{"name":"org_slug","in":"path","required":true,"schema":{"type":"string","title":"Org Slug"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}},{"name":"user_certification_uuid","in":"path","required":true,"schema":{"type":"string","title":"User Certification Uuid"}}],"responses":{"200":{"description":"Certificate revoked. The cert row is hard-deleted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RevokeCertificateResponse"}}}},"404":{"description":"Certificate not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/{org_slug}/usergroups/{usergroup_uuid}/members/{user_id}":{"post":{"tags":["admin"],"summary":"Add a user to a user group","description":"Add a user to a cohort/group. Both must belong to the token's org.","operationId":"api_admin_add_usergroup_member_api_v1_admin__org_slug__usergroups__usergroup_uuid__members__user_id__post","parameters":[{"name":"org_slug","in":"path","required":true,"schema":{"type":"string","title":"Org Slug"}},{"name":"usergroup_uuid","in":"path","required":true,"schema":{"type":"string","title":"Usergroup Uuid"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}}],"responses":{"200":{"description":"User added to the cohort.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserGroupMemberResponse"}}}},"400":{"description":"User is already in this group"},"404":{"description":"User or group not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["admin"],"summary":"Remove a user from a user group","description":"Remove a user's membership from a cohort/group. The user account itself is preserved.","operationId":"api_admin_remove_usergroup_member_api_v1_admin__org_slug__usergroups__usergroup_uuid__members__user_id__delete","parameters":[{"name":"org_slug","in":"path","required":true,"schema":{"type":"string","title":"Org Slug"}},{"name":"usergroup_uuid","in":"path","required":true,"schema":{"type":"string","title":"Usergroup Uuid"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}}],"responses":{"200":{"description":"User removed from the cohort.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserGroupMemberResponse"}}}},"404":{"description":"User, group, or membership not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/{org_slug}/users/{user_id}/role":{"patch":{"tags":["admin"],"summary":"Change a user's org role","description":"Change the user's role within the organization. Blocks demoting the last admin. The target role must belong to this org or be a global role.","operationId":"api_admin_change_user_role_api_v1_admin__org_slug__users__user_id__role_patch","parameters":[{"name":"org_slug","in":"path","required":true,"schema":{"type":"string","title":"Org Slug"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangeRoleRequest"}}}},"responses":{"200":{"description":"User role updated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangeRoleResponse"}}}},"400":{"description":"Cannot demote the last admin"},"403":{"description":"Role does not belong to this organization"},"404":{"description":"User or role not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/{org_slug}/usergroups":{"post":{"tags":["admin"],"summary":"Create a user group","description":"Create a cohort/user group owned by the organization.","operationId":"api_admin_create_usergroup_api_v1_admin__org_slug__usergroups_post","parameters":[{"name":"org_slug","in":"path","required":true,"schema":{"type":"string","title":"Org Slug"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserGroupRequest"}}}},"responses":{"200":{"description":"The newly created cohort.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserGroupResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/{org_slug}/usergroups/{usergroup_uuid}":{"delete":{"tags":["admin"],"summary":"Delete a user group","description":"Delete a user group and all its memberships and course links. The underlying users and courses are untouched.","operationId":"api_admin_delete_usergroup_api_v1_admin__org_slug__usergroups__usergroup_uuid__delete","parameters":[{"name":"org_slug","in":"path","required":true,"schema":{"type":"string","title":"Org Slug"}},{"name":"usergroup_uuid","in":"path","required":true,"schema":{"type":"string","title":"Usergroup Uuid"}}],"responses":{"200":{"description":"Cohort and all its memberships/course links deleted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteUserGroupResponse"}}}},"404":{"description":"UserGroup not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/{org_slug}/usergroups/{usergroup_uuid}/members":{"get":{"tags":["admin"],"summary":"List members of a user group","description":"Reverse lookup: list users belonging to a cohort, with pagination.","operationId":"api_admin_list_usergroup_members_api_v1_admin__org_slug__usergroups__usergroup_uuid__members_get","parameters":[{"name":"org_slug","in":"path","required":true,"schema":{"type":"string","title":"Org Slug"}},{"name":"usergroup_uuid","in":"path","required":true,"schema":{"type":"string","title":"Usergroup Uuid"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":25,"title":"Limit"}}],"responses":{"200":{"description":"Members of the cohort, paginated.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/UserGroupMemberListItem"},"title":"Response Api Admin List Usergroup Members Api V1 Admin  Org Slug  Usergroups  Usergroup Uuid  Members Get"}}}},"404":{"description":"UserGroup not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/{org_slug}/users/{user_id}/groups":{"get":{"tags":["admin"],"summary":"List user groups a user belongs to","description":"Reverse lookup: which cohorts is this user a member of?","operationId":"api_admin_get_user_groups_api_v1_admin__org_slug__users__user_id__groups_get","parameters":[{"name":"org_slug","in":"path","required":true,"schema":{"type":"string","title":"Org Slug"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}}],"responses":{"200":{"description":"Cohorts the user belongs to within this org.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/UserUserGroupItem"},"title":"Response Api Admin Get User Groups Api V1 Admin  Org Slug  Users  User Id  Groups Get"}}}},"404":{"description":"User not in org"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/{org_slug}/usergroups/{usergroup_uuid}/courses/{course_uuid}":{"post":{"tags":["admin"],"summary":"Grant a cohort access to a course","description":"Link a course to a user group — all members of the group gain the access rights configured for that group.","operationId":"api_admin_add_course_to_usergroup_api_v1_admin__org_slug__usergroups__usergroup_uuid__courses__course_uuid__post","parameters":[{"name":"org_slug","in":"path","required":true,"schema":{"type":"string","title":"Org Slug"}},{"name":"usergroup_uuid","in":"path","required":true,"schema":{"type":"string","title":"Usergroup Uuid"}},{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","title":"Course Uuid"}}],"responses":{"200":{"description":"Course linked to the cohort.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserGroupCourseResponse"}}}},"400":{"description":"Course already linked to this group"},"404":{"description":"Group or course not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["admin"],"summary":"Revoke a cohort's access to a course","description":"Unlink a course from a user group. Members of the cohort lose access unless granted through another path.","operationId":"api_admin_remove_course_from_usergroup_api_v1_admin__org_slug__usergroups__usergroup_uuid__courses__course_uuid__delete","parameters":[{"name":"org_slug","in":"path","required":true,"schema":{"type":"string","title":"Org Slug"}},{"name":"usergroup_uuid","in":"path","required":true,"schema":{"type":"string","title":"Usergroup Uuid"}},{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","title":"Course Uuid"}}],"responses":{"200":{"description":"Course unlinked from the cohort.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserGroupCourseResponse"}}}},"404":{"description":"Group or link not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/{org_slug}/users/{user_id}/export":{"get":{"tags":["admin"],"summary":"Full GDPR data export for a user","description":"Return a JSON bundle containing the user's profile, org memberships, trails, runs, steps, certificates, and cohort memberships. Intended for GDPR Article 15 (Right of Access) compliance. All sub-collections are scoped to the caller's org.","operationId":"api_admin_export_user_data_api_v1_admin__org_slug__users__user_id__export_get","parameters":[{"name":"org_slug","in":"path","required":true,"schema":{"type":"string","title":"Org Slug"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}}],"responses":{"200":{"description":"Bundle of all user data scoped to this org.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserDataExportResponse"}}}},"404":{"description":"User not in org"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/{org_slug}/users/{user_id}/anonymize":{"post":{"tags":["admin"],"summary":"GDPR right-to-be-forgotten","description":"Scrub a user's PII (email, name, avatar, bio, details, profile, password). Delete API tokens the user created. Keeps trails and certificates so course analytics remain accurate. Invalidates session cache.","operationId":"api_admin_anonymize_user_api_v1_admin__org_slug__users__user_id__anonymize_post","parameters":[{"name":"org_slug","in":"path","required":true,"schema":{"type":"string","title":"Org Slug"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}}],"responses":{"200":{"description":"User PII scrubbed; reports how many API tokens were revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnonymizeUserResponse"}}}},"404":{"description":"User not in org"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/{org_slug}/courses/{course_uuid}/analytics":{"get":{"tags":["admin"],"summary":"Aggregate stats for a course","description":"Returns enrollment/completion counts, average completion percentage across all enrollees, and total certificates awarded.","operationId":"api_admin_get_course_analytics_api_v1_admin__org_slug__courses__course_uuid__analytics_get","parameters":[{"name":"org_slug","in":"path","required":true,"schema":{"type":"string","title":"Org Slug"}},{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","title":"Course Uuid"}}],"responses":{"200":{"description":"Aggregate course stats: enrollment, completion, certificates, etc.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CourseAnalyticsResponse"}}}},"404":{"description":"Course not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/courses/export/batch":{"post":{"tags":["courses"],"summary":"Export multiple courses as ZIP","description":"Export multiple courses (up to 20 per request) as a single ZIP archive. All specified courses must belong to the same organization and the caller must have read access to each course.","operationId":"api_export_courses_batch_api_v1_courses_export_batch_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchExportRequest"}}},"required":true},"responses":{"200":{"description":"ZIP archive containing the exported courses","content":{"application/json":{"schema":{}},"application/zip":{}}},"403":{"description":"User lacks read permission on one of the courses"},"404":{"description":"One or more of the requested courses was not found"},"422":{"description":"Validation error (empty list or more than 20 courses requested)"}}}},"/api/v1/courses/import/analyze":{"post":{"tags":["courses"],"summary":"Analyze a course import package","description":"Upload and analyze a LearnHouse course export ZIP. Validates the package, extracts its contents, and returns a list of courses available for import along with a temp_id to use with the subsequent import endpoint.","operationId":"api_analyze_import_package_api_v1_courses_import_analyze_post","parameters":[{"name":"org_id","in":"query","required":true,"schema":{"type":"integer","title":"Org Id"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_api_analyze_import_package_api_v1_courses_import_analyze_post"}}}},"responses":{"200":{"description":"Package analyzed successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportAnalysisResponse"}}}},"400":{"description":"Invalid or malformed export package"},"403":{"description":"User lacks permission to create courses in the organization"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/courses/import":{"post":{"tags":["courses"],"summary":"Import courses from an analyzed package","description":"Import previously analyzed courses into an organization. Uses the temp_id returned by the analyze step along with the list of course UUIDs to import. Up to 20 courses can be imported per request.","operationId":"api_import_courses_api_v1_courses_import_post","parameters":[{"name":"org_id","in":"query","required":true,"schema":{"type":"integer","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportRequest"}}}},"responses":{"200":{"description":"Courses imported successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportResult"}}}},"400":{"description":"Invalid temp_id or course_uuids not present in the package"},"403":{"description":"User lacks permission to create courses in the organization"},"404":{"description":"Organization or temporary package not found"},"422":{"description":"Validation error (empty list or more than 20 courses)"}}}},"/api/v1/courses/":{"post":{"tags":["courses"],"summary":"Create course","description":"Create a new course in the specified organization. Accepts multipart form data with course metadata and an optional thumbnail image or video.","operationId":"api_create_course_api_v1_courses__post","parameters":[{"name":"org_id","in":"query","required":true,"schema":{"type":"integer","title":"Org Id"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_api_create_course_api_v1_courses__post"}}}},"responses":{"200":{"description":"Course created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CourseRead"}}}},"403":{"description":"User lacks permission to create courses in the organization"},"404":{"description":"Organization not found"},"422":{"description":"Invalid form data"}}}},"/api/v1/courses/{course_uuid}/thumbnail":{"put":{"tags":["courses"],"summary":"Update course thumbnail","description":"Replace the thumbnail image or video for an existing course.","operationId":"api_create_course_thumbnail_api_v1_courses__course_uuid__thumbnail_put","parameters":[{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","title":"Course Uuid"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_api_create_course_thumbnail_api_v1_courses__course_uuid__thumbnail_put"}}}},"responses":{"200":{"description":"Thumbnail updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CourseRead"}}}},"403":{"description":"User lacks permission to update the course"},"404":{"description":"Course not found"},"422":{"description":"Invalid thumbnail file"}}}},"/api/v1/courses/{course_uuid}":{"get":{"tags":["courses"],"summary":"Get course by UUID","description":"Retrieve a single course by its UUID.","operationId":"api_get_course_api_v1_courses__course_uuid__get","parameters":[{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","title":"Course Uuid"}}],"responses":{"200":{"description":"Course retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CourseRead"}}}},"403":{"description":"User lacks read access to this course"},"404":{"description":"Course not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["courses"],"summary":"Update course","description":"Update course metadata (name, description, about, tags, visibility, etc.) by UUID.","operationId":"api_update_course_api_v1_courses__course_uuid__put","parameters":[{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","title":"Course Uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CourseUpdate"}}}},"responses":{"200":{"description":"Course updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CourseRead"}}}},"403":{"description":"User lacks permission to update the course"},"404":{"description":"Course not found"},"422":{"description":"Invalid update payload"}}},"delete":{"tags":["courses"],"summary":"Delete course","description":"Permanently delete a course and all of its content by UUID.","operationId":"api_delete_course_api_v1_courses__course_uuid__delete","parameters":[{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","title":"Course Uuid"}}],"responses":{"200":{"description":"Course deleted successfully","content":{"application/json":{"schema":{}}}},"403":{"description":"User lacks permission to delete the course"},"404":{"description":"Course not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/courses/id/{course_id}":{"get":{"tags":["courses"],"summary":"Get course by ID","description":"Retrieve a single course by its numeric database ID.","operationId":"api_get_course_by_id_api_v1_courses_id__course_id__get","parameters":[{"name":"course_id","in":"path","required":true,"schema":{"type":"integer","title":"Course Id"}}],"responses":{"200":{"description":"Course retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CourseRead"}}}},"403":{"description":"User lacks read access to this course"},"404":{"description":"Course not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/courses/{course_uuid}/meta":{"get":{"tags":["courses"],"summary":"Get course metadata","description":"Retrieve full course metadata including chapters and activities. Use slim=true to exclude heavy activity content/details, useful for navigation menus.","operationId":"api_get_course_meta_api_v1_courses__course_uuid__meta_get","parameters":[{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","title":"Course Uuid"}},{"name":"with_unpublished_activities","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"With Unpublished Activities"}},{"name":"slim","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Slim"}}],"responses":{"200":{"description":"Course metadata retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FullCourseRead"}}}},"403":{"description":"User lacks read access to this course"},"404":{"description":"Course not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/courses/org_slug/{org_slug}/page/{page}/limit/{limit}":{"get":{"tags":["courses"],"summary":"List courses for an organization","description":"Paginated list of courses for an organization identified by slug. Set include_unpublished=true to include unpublished courses (requires update permission on the organization).","operationId":"api_get_course_by_orgslug_api_v1_courses_org_slug__org_slug__page__page__limit__limit__get","parameters":[{"name":"page","in":"path","required":true,"schema":{"type":"integer","title":"Page"}},{"name":"limit","in":"path","required":true,"schema":{"type":"integer","title":"Limit"}},{"name":"org_slug","in":"path","required":true,"schema":{"type":"string","title":"Org Slug"}},{"name":"include_unpublished","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Unpublished"}}],"responses":{"200":{"description":"Paginated list of courses","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CourseRead"},"title":"Response 200 Api Get Course By Orgslug Api V1 Courses Org Slug  Org Slug  Page  Page  Limit  Limit  Get"}}}},"403":{"description":"User lacks permission to list unpublished courses"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/courses/org_slug/{org_slug}/count":{"get":{"tags":["courses"],"summary":"Count courses in an organization","description":"Return the total number of courses for the organization identified by slug.","operationId":"api_get_courses_count_api_v1_courses_org_slug__org_slug__count_get","parameters":[{"name":"org_slug","in":"path","required":true,"schema":{"type":"string","title":"Org Slug"}}],"responses":{"200":{"description":"Total course count","content":{"application/json":{"schema":{"type":"integer","title":"Response Api Get Courses Count Api V1 Courses Org Slug  Org Slug  Count Get"}}}},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/courses/org_slug/{org_slug}/search":{"get":{"tags":["courses"],"summary":"Search courses","description":"Full-text search courses by title and description within an organization. Query length is capped at 200 characters and results are paginated with a maximum page size of 50 to prevent data dumping.","operationId":"api_search_courses_api_v1_courses_org_slug__org_slug__search_get","parameters":[{"name":"org_slug","in":"path","required":true,"schema":{"type":"string","title":"Org Slug"}},{"name":"query","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":200,"description":"Search query","title":"Query"},"description":"Search query"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number","default":1,"title":"Page"},"description":"Page number"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"description":"Items per page (max 50)","default":10,"title":"Limit"},"description":"Items per page (max 50)"}],"responses":{"200":{"description":"Paginated list of matching courses","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CourseRead"},"title":"Response 200 Api Search Courses Api V1 Courses Org Slug  Org Slug  Search Get"}}}},"404":{"description":"Organization not found"},"422":{"description":"Invalid query or pagination parameters"}}}},"/api/v1/courses/{course_uuid}/clone":{"post":{"tags":["courses"],"summary":"Clone course","description":"Create a complete copy of a course including chapters, activities, blocks and all associated files. The cloned course gets a new UUID, is set to private by default, and has the current user as the creator.","operationId":"api_clone_course_api_v1_courses__course_uuid__clone_post","parameters":[{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","title":"Course Uuid"}}],"responses":{"200":{"description":"Cloned course","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CourseRead"}}}},"403":{"description":"User lacks read access to the source course or cannot create courses"},"404":{"description":"Source course not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/courses/{course_uuid}/export":{"get":{"tags":["courses"],"summary":"Export course as ZIP","description":"Export a single course and all its content (chapters, activities, blocks, and files) as a ZIP archive following the LearnHouse export format.","operationId":"api_export_course_api_v1_courses__course_uuid__export_get","parameters":[{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","title":"Course Uuid"}}],"responses":{"200":{"description":"ZIP archive containing the exported course","content":{"application/json":{"schema":{}},"application/zip":{}}},"403":{"description":"User lacks read access to the course"},"404":{"description":"Course not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/courses/{course_uuid}/apply-contributor":{"post":{"tags":["courses"],"summary":"Apply as course contributor","description":"Submit an application for the current user to become a contributor on the given course.","operationId":"api_apply_course_contributor_api_v1_courses__course_uuid__apply_contributor_post","parameters":[{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","title":"Course Uuid"}}],"responses":{"200":{"description":"Application submitted","content":{"application/json":{"schema":{}}}},"403":{"description":"Course is not open to contributors"},"404":{"description":"Course not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/courses/{course_uuid}/updates":{"get":{"tags":["courses"],"summary":"List course updates","description":"Return all course update posts for a given course.","operationId":"api_get_course_updates_api_v1_courses__course_uuid__updates_get","parameters":[{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","title":"Course Uuid"}}],"responses":{"200":{"description":"List of course update posts","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CourseUpdateRead"},"title":"Response 200 Api Get Course Updates Api V1 Courses  Course Uuid  Updates Get"}}}},"403":{"description":"User lacks read access to the course"},"404":{"description":"Course not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["courses"],"summary":"Create course update","description":"Create a new course update post associated with the given course.","operationId":"api_create_course_update_api_v1_courses__course_uuid__updates_post","parameters":[{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","title":"Course Uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CourseUpdateCreate"}}}},"responses":{"200":{"description":"Course update created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CourseUpdateRead"}}}},"403":{"description":"User lacks permission to create updates for this course"},"404":{"description":"Course not found"},"422":{"description":"Invalid update payload"}}}},"/api/v1/courses/{course_uuid}/update/{courseupdate_uuid}":{"put":{"tags":["courses"],"summary":"Update course update","description":"Edit an existing course update post identified by its UUID.","operationId":"api_update_course_update_api_v1_courses__course_uuid__update__courseupdate_uuid__put","parameters":[{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","title":"Course Uuid"}},{"name":"courseupdate_uuid","in":"path","required":true,"schema":{"type":"string","title":"Courseupdate Uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CourseUpdateUpdate"}}}},"responses":{"200":{"description":"Course update modified","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CourseUpdateRead"}}}},"403":{"description":"User lacks permission to modify updates on this course"},"404":{"description":"Course or course update not found"},"422":{"description":"Invalid update payload"}}},"delete":{"tags":["courses"],"summary":"Delete course update","description":"Delete a course update post by its UUID.","operationId":"api_delete_course_update_api_v1_courses__course_uuid__update__courseupdate_uuid__delete","parameters":[{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","title":"Course Uuid"}},{"name":"courseupdate_uuid","in":"path","required":true,"schema":{"type":"string","title":"Courseupdate Uuid"}}],"responses":{"200":{"description":"Course update deleted","content":{"application/json":{"schema":{}}}},"403":{"description":"User lacks permission to delete updates on this course"},"404":{"description":"Course or course update not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/courses/{course_uuid}/contributors":{"get":{"tags":["courses"],"summary":"List course contributors","description":"Return all contributors attached to a given course along with their authorship role and status.","operationId":"api_get_course_contributors_api_v1_courses__course_uuid__contributors_get","parameters":[{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","title":"Course Uuid"}}],"responses":{"200":{"description":"List of course contributors","content":{"application/json":{"schema":{}}}},"403":{"description":"User lacks permission to view contributors"},"404":{"description":"Course not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/courses/{course_uuid}/contributors/{contributor_user_id}":{"put":{"tags":["courses"],"summary":"Update course contributor","description":"Update a course contributor's authorship role and status. Only course administrators or maintainers can perform this action.","operationId":"api_update_course_contributor_api_v1_courses__course_uuid__contributors__contributor_user_id__put","parameters":[{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","title":"Course Uuid"}},{"name":"contributor_user_id","in":"path","required":true,"schema":{"type":"integer","title":"Contributor User Id"}},{"name":"authorship","in":"query","required":true,"schema":{"$ref":"#/components/schemas/ResourceAuthorshipEnum"}},{"name":"authorship_status","in":"query","required":true,"schema":{"$ref":"#/components/schemas/ResourceAuthorshipStatusEnum"}}],"responses":{"200":{"description":"Contributor updated","content":{"application/json":{"schema":{}}}},"403":{"description":"User lacks permission to manage contributors"},"404":{"description":"Course or contributor not found"},"422":{"description":"Invalid authorship or status value"}}}},"/api/v1/courses/{course_uuid}/bulk-add-contributors":{"post":{"tags":["courses"],"summary":"Bulk add course contributors","description":"Add multiple contributors to a course by their usernames in a single call. Only course administrators can perform this action.","operationId":"api_add_bulk_course_contributors_api_v1_courses__course_uuid__bulk_add_contributors_post","parameters":[{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","title":"Course Uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"array","items":{"type":"string"},"title":"Usernames"}}}},"responses":{"200":{"description":"Contributors added","content":{"application/json":{"schema":{}}}},"403":{"description":"User lacks permission to manage contributors"},"404":{"description":"Course or one of the specified users not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/courses/{course_uuid}/bulk-remove-contributors":{"put":{"tags":["courses"],"summary":"Bulk remove course contributors","description":"Remove multiple contributors from a course by their usernames in a single call.","operationId":"api_remove_bulk_course_contributors_api_v1_courses__course_uuid__bulk_remove_contributors_put","parameters":[{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","title":"Course Uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"array","items":{"type":"string"},"title":"Usernames"}}}},"responses":{"200":{"description":"Contributors removed","content":{"application/json":{"schema":{}}}},"403":{"description":"User lacks permission to manage contributors"},"404":{"description":"Course or one of the specified users not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/courses/{course_uuid}/rights":{"get":{"tags":["courses"],"summary":"Get course user rights","description":"Return the current user's detailed rights on a course (permissions, ownership, roles). Intended for UI-level feature gating; anonymous users only see rights for public courses.","operationId":"api_get_course_user_rights_api_v1_courses__course_uuid__rights_get","parameters":[{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","title":"Course Uuid"}}],"responses":{"200":{"description":"Rights object describing permissions, ownership and roles","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Api Get Course User Rights Api V1 Courses  Course Uuid  Rights Get"}}}},"404":{"description":"Course not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/courses/migrate/upload":{"post":{"tags":["migration"],"summary":"Upload migration files","description":"Upload files for content migration from another LMS. Pass an existing `temp_id` to append additional files to a prior upload.","operationId":"api_upload_migration_files_api_v1_courses_migrate_upload_post","parameters":[{"name":"org_id","in":"query","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"temp_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Temp Id"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_api_upload_migration_files_api_v1_courses_migrate_upload_post"}}}},"responses":{"200":{"description":"Files uploaded; returns the temporary upload id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MigrationUploadResponse"}}}},"400":{"description":"Uploaded files are invalid or unsupported"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/courses/migrate/suggest":{"post":{"tags":["migration"],"summary":"Suggest migration structure","description":"Use AI to suggest a course structure from previously uploaded migration files.","operationId":"api_suggest_structure_api_v1_courses_migrate_suggest_post","parameters":[{"name":"org_id","in":"query","required":true,"schema":{"type":"integer","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuggestStructureRequest"}}}},"responses":{"200":{"description":"Suggested course tree structure based on the uploaded files.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MigrationTreeStructure"}}}},"404":{"description":"Temporary upload id not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/courses/migrate/create":{"post":{"tags":["migration"],"summary":"Create course from migration","description":"Create a course from the finalized migration tree structure returned by the suggest endpoint.","operationId":"api_create_from_migration_api_v1_courses_migrate_create_post","parameters":[{"name":"org_id","in":"query","required":true,"schema":{"type":"integer","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateFromMigrationRequest"}}}},"responses":{"200":{"description":"Course created from the migration payload; returns ids of created resources.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MigrationCreateResult"}}}},"400":{"description":"Invalid structure payload"},"403":{"description":"Caller lacks permission to create courses in this org"},"404":{"description":"Temporary upload id or referenced resources not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/search/org_slug/{org_slug}":{"get":{"tags":["search"],"summary":"Search within an organization","description":"Performs a paginated search across courses, folders, and users within the given organization. Query length and page size are capped to prevent data dumping. Requires authentication.","operationId":"api_search_across_org_api_v1_search_org_slug__org_slug__get","parameters":[{"name":"org_slug","in":"path","required":true,"schema":{"type":"string","title":"Org Slug"}},{"name":"query","in":"query","required":true,"schema":{"type":"string","minLength":3,"maxLength":200,"description":"Search query","title":"Query"},"description":"Search query"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number","default":1,"title":"Page"},"description":"Page number"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"description":"Items per page (max 50)","default":10,"title":"Limit"},"description":"Items per page (max 50)"}],"responses":{"200":{"description":"Search results grouped by resource type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchResult"}}}},"401":{"description":"Authentication required"},"403":{"description":"User is not permitted to search this organization"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assignments/":{"post":{"tags":["assignments"],"summary":"Create assignment","description":"Create a new assignment attached to an activity. The authenticated user must have permission to edit the parent course.","operationId":"api_create_assignments_api_v1_assignments__post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssignmentCreate"}}},"required":true},"responses":{"200":{"description":"Assignment created and returned.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssignmentRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to create assignments in this course"},"404":{"description":"Parent activity or course not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assignments/{assignment_uuid}":{"get":{"tags":["assignments"],"summary":"Get assignment","description":"Read an assignment by its UUID.","operationId":"api_read_assignment_api_v1_assignments__assignment_uuid__get","parameters":[{"name":"assignment_uuid","in":"path","required":true,"schema":{"type":"string","title":"Assignment Uuid"}}],"responses":{"200":{"description":"Assignment returned.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssignmentRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to view this assignment"},"404":{"description":"Assignment not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["assignments"],"summary":"Update assignment","description":"Update an assignment by its UUID. The authenticated user must have permission to edit the parent course.","operationId":"api_update_assignment_api_v1_assignments__assignment_uuid__put","parameters":[{"name":"assignment_uuid","in":"path","required":true,"schema":{"type":"string","title":"Assignment Uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssignmentUpdate"}}}},"responses":{"200":{"description":"Assignment updated and returned.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssignmentRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to update this assignment"},"404":{"description":"Assignment not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["assignments"],"summary":"Delete assignment","description":"Delete an assignment by its UUID. The authenticated user must have permission to edit the parent course.","operationId":"api_delete_assignment_api_v1_assignments__assignment_uuid__delete","parameters":[{"name":"assignment_uuid","in":"path","required":true,"schema":{"type":"string","title":"Assignment Uuid"}}],"responses":{"200":{"description":"Assignment deleted.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to delete this assignment"},"404":{"description":"Assignment not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assignments/activity/{activity_uuid}":{"get":{"tags":["assignments"],"summary":"Get assignment by activity","description":"Read the assignment attached to a given activity UUID.","operationId":"api_read_assignment_from_activity_api_v1_assignments_activity__activity_uuid__get","parameters":[{"name":"activity_uuid","in":"path","required":true,"schema":{"type":"string","title":"Activity Uuid"}}],"responses":{"200":{"description":"Assignment returned.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssignmentRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to view this assignment"},"404":{"description":"Activity or assignment not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["assignments"],"summary":"Delete assignment by activity","description":"Delete the assignment attached to the given activity UUID.","operationId":"api_delete_assignment_from_activity_api_v1_assignments_activity__activity_uuid__delete","parameters":[{"name":"activity_uuid","in":"path","required":true,"schema":{"type":"string","title":"Activity Uuid"}}],"responses":{"200":{"description":"Assignment deleted.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to delete this assignment"},"404":{"description":"Activity or assignment not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assignments/{assignment_uuid}/tasks":{"post":{"tags":["assignments"],"summary":"Create assignment task","description":"Create a new task under an assignment. The authenticated user must have permission to edit the parent course.","operationId":"api_create_assignment_tasks_api_v1_assignments__assignment_uuid__tasks_post","parameters":[{"name":"assignment_uuid","in":"path","required":true,"schema":{"type":"string","title":"Assignment Uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssignmentTaskCreate"}}}},"responses":{"200":{"description":"Assignment task created.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to edit this assignment"},"404":{"description":"Assignment not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["assignments"],"summary":"List assignment tasks","description":"Read all tasks for the given assignment.","operationId":"api_read_assignment_tasks_api_v1_assignments__assignment_uuid__tasks_get","parameters":[{"name":"assignment_uuid","in":"path","required":true,"schema":{"type":"string","title":"Assignment Uuid"}}],"responses":{"200":{"description":"List of assignment tasks.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to view this assignment"},"404":{"description":"Assignment not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assignments/task/{assignment_task_uuid}":{"get":{"tags":["assignments"],"summary":"Get assignment task","description":"Read a single assignment task by its UUID.","operationId":"api_read_assignment_task_api_v1_assignments_task__assignment_task_uuid__get","parameters":[{"name":"assignment_task_uuid","in":"path","required":true,"schema":{"type":"string","title":"Assignment Task Uuid"}}],"responses":{"200":{"description":"Assignment task returned.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to view this task"},"404":{"description":"Assignment task not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assignments/{assignment_uuid}/tasks/{assignment_task_uuid}":{"put":{"tags":["assignments"],"summary":"Update assignment task","description":"Update an assignment task by its UUID. The authenticated user must have permission to edit the parent course.","operationId":"api_update_assignment_tasks_api_v1_assignments__assignment_uuid__tasks__assignment_task_uuid__put","parameters":[{"name":"assignment_task_uuid","in":"path","required":true,"schema":{"type":"string","title":"Assignment Task Uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssignmentTaskUpdate"}}}},"responses":{"200":{"description":"Assignment task updated.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to edit this task"},"404":{"description":"Assignment task not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["assignments"],"summary":"Delete assignment task","description":"Delete an assignment task by its UUID. The authenticated user must have permission to edit the parent course.","operationId":"api_delete_assignment_tasks_api_v1_assignments__assignment_uuid__tasks__assignment_task_uuid__delete","parameters":[{"name":"assignment_task_uuid","in":"path","required":true,"schema":{"type":"string","title":"Assignment Task Uuid"}}],"responses":{"200":{"description":"Assignment task deleted.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to delete this task"},"404":{"description":"Assignment task not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assignments/{assignment_uuid}/tasks/{assignment_task_uuid}/ref_file":{"post":{"tags":["assignments"],"summary":"Upload task reference file","description":"Upload or replace the reference file for an assignment task. Instructors use this to attach a canonical solution or prompt attachment.","operationId":"api_put_assignment_task_ref_file_api_v1_assignments__assignment_uuid__tasks__assignment_task_uuid__ref_file_post","parameters":[{"name":"assignment_task_uuid","in":"path","required":true,"schema":{"type":"string","title":"Assignment Task Uuid"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_api_put_assignment_task_ref_file_api_v1_assignments__assignment_uuid__tasks__assignment_task_uuid__ref_file_post"}}}},"responses":{"200":{"description":"Reference file stored.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to edit this task"},"404":{"description":"Assignment task not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assignments/{assignment_uuid}/tasks/{assignment_task_uuid}/sub_file":{"post":{"tags":["assignments"],"summary":"Upload task submission file","description":"Upload or replace the submission file for an assignment task on behalf of the current user.","operationId":"api_put_assignment_task_sub_file_api_v1_assignments__assignment_uuid__tasks__assignment_task_uuid__sub_file_post","parameters":[{"name":"assignment_task_uuid","in":"path","required":true,"schema":{"type":"string","title":"Assignment Task Uuid"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_api_put_assignment_task_sub_file_api_v1_assignments__assignment_uuid__tasks__assignment_task_uuid__sub_file_post"}}}},"responses":{"200":{"description":"Submission file stored.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to submit to this task"},"404":{"description":"Assignment task not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assignments/{assignment_uuid}/tasks/{assignment_task_uuid}/submissions":{"put":{"tags":["assignments"],"summary":"Upsert assignment task submission","description":"Create or update the current user's submission for an assignment task.","operationId":"api_handle_assignment_task_submissions_api_v1_assignments__assignment_uuid__tasks__assignment_task_uuid__submissions_put","parameters":[{"name":"assignment_task_uuid","in":"path","required":true,"schema":{"type":"string","title":"Assignment Task Uuid"}},{"name":"on_behalf_of_user_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"On Behalf Of User Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssignmentTaskSubmissionUpdate"}}}},"responses":{"200":{"description":"Task submission stored.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to submit to this task"},"404":{"description":"Assignment task not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["assignments"],"summary":"List task submissions","description":"Read all submissions for a given assignment task (instructor view).","operationId":"api_read_assignment_task_submissions_api_v1_assignments__assignment_uuid__tasks__assignment_task_uuid__submissions_get","parameters":[{"name":"assignment_task_uuid","in":"path","required":true,"schema":{"type":"string","title":"Assignment Task Uuid"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"List of task submissions.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to view these submissions"},"404":{"description":"Assignment task not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assignments/{assignment_uuid}/tasks/{assignment_task_uuid}/submissions/user/{user_id}":{"get":{"tags":["assignments"],"summary":"List task submissions for user","description":"Read the task submissions made by a specific user for the given assignment task.","operationId":"api_read_user_assignment_task_submissions_api_v1_assignments__assignment_uuid__tasks__assignment_task_uuid__submissions_user__user_id__get","parameters":[{"name":"assignment_task_uuid","in":"path","required":true,"schema":{"type":"string","title":"Assignment Task Uuid"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}}],"responses":{"200":{"description":"List of task submissions for the user.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to view these submissions"},"404":{"description":"Assignment task or user not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assignments/{assignment_uuid}/tasks/submissions/me":{"get":{"tags":["assignments"],"summary":"Batch read current user's task submissions","description":"Read all current-user task submissions for an assignment in one round trip. Returns a map keyed by assignment_task_uuid (value is null if no submission). Registered before the per-task variant so the literal submissions path segment isn't shadowed.","operationId":"api_read_user_assignment_task_submissions_me_batch_api_v1_assignments__assignment_uuid__tasks_submissions_me_get","parameters":[{"name":"assignment_uuid","in":"path","required":true,"schema":{"type":"string","title":"Assignment Uuid"}}],"responses":{"200":{"description":"Map of task_uuid -> submission (or null).","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to view this assignment"},"404":{"description":"Assignment not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assignments/{assignment_uuid}/tasks/{assignment_task_uuid}/submissions/me":{"get":{"tags":["assignments"],"summary":"Get current user's task submission","description":"Read the current user's submission for a specific assignment task. Returns 404 if the user has no submission yet.","operationId":"api_read_user_assignment_task_submissions_me_api_v1_assignments__assignment_uuid__tasks__assignment_task_uuid__submissions_me_get","parameters":[{"name":"assignment_task_uuid","in":"path","required":true,"schema":{"type":"string","title":"Assignment Task Uuid"}}],"responses":{"200":{"description":"Current user's task submission.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"404":{"description":"Assignment Task Submission not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assignments/{assignment_uuid}/tasks/{assignment_task_uuid}/submissions/{assignment_task_submission_uuid}":{"delete":{"tags":["assignments"],"summary":"Delete task submission","description":"Delete a specific task submission by its UUID.","operationId":"api_delete_assignment_task_submissions_api_v1_assignments__assignment_uuid__tasks__assignment_task_uuid__submissions__assignment_task_submission_uuid__delete","parameters":[{"name":"assignment_task_submission_uuid","in":"path","required":true,"schema":{"type":"string","title":"Assignment Task Submission Uuid"}}],"responses":{"200":{"description":"Task submission deleted.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to delete this submission"},"404":{"description":"Task submission not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assignments/{assignment_uuid}/submissions":{"post":{"tags":["assignments"],"summary":"Create assignment submission","description":"Create a new assignment-level submission for the current user on the given assignment.","operationId":"api_create_assignment_submissions_api_v1_assignments__assignment_uuid__submissions_post","parameters":[{"name":"assignment_uuid","in":"path","required":true,"schema":{"type":"string","title":"Assignment Uuid"}},{"name":"on_behalf_of_user_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"On Behalf Of User Id"}}],"responses":{"200":{"description":"Assignment submission created.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to submit to this assignment"},"404":{"description":"Assignment not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["assignments"],"summary":"List assignment submissions","description":"Read all assignment-level submissions for the given assignment (instructor view).","operationId":"api_read_assignment_submissions_api_v1_assignments__assignment_uuid__submissions_get","parameters":[{"name":"assignment_uuid","in":"path","required":true,"schema":{"type":"string","title":"Assignment Uuid"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"List of assignment submissions.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to view these submissions"},"404":{"description":"Assignment not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assignments/{assignment_uuid}/submissions/me":{"get":{"tags":["assignments"],"summary":"Get current user's assignment submission","description":"Read the current user's assignment-level submission for the given assignment.","operationId":"api_read_user_assignment_submission_me_api_v1_assignments__assignment_uuid__submissions_me_get","parameters":[{"name":"assignment_uuid","in":"path","required":true,"schema":{"type":"string","title":"Assignment Uuid"}}],"responses":{"200":{"description":"Current user's assignment submission.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to view this assignment"},"404":{"description":"Assignment or submission not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assignments/{assignment_uuid}/submissions/{user_id}":{"get":{"tags":["assignments"],"summary":"Get assignment submission for user","description":"Read the assignment-level submission for a specific user on the given assignment (instructor view).","operationId":"api_read_user_assignment_submissions_api_v1_assignments__assignment_uuid__submissions__user_id__get","parameters":[{"name":"assignment_uuid","in":"path","required":true,"schema":{"type":"string","title":"Assignment Uuid"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}}],"responses":{"200":{"description":"Assignment submission for the user.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to view this submission"},"404":{"description":"Assignment, user, or submission not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["assignments"],"summary":"Update assignment submission for user","description":"Update a user's assignment-level submission on the given assignment.","operationId":"api_update_user_assignment_submissions_api_v1_assignments__assignment_uuid__submissions__user_id__put","parameters":[{"name":"assignment_uuid","in":"path","required":true,"schema":{"type":"string","title":"Assignment Uuid"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssignmentUserSubmissionCreate"}}}},"responses":{"200":{"description":"Assignment submission updated.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to update this submission"},"404":{"description":"Assignment, user, or submission not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["assignments"],"summary":"Delete assignment submission for user","description":"Delete a user's assignment-level submission on the given assignment.","operationId":"api_delete_user_assignment_submissions_api_v1_assignments__assignment_uuid__submissions__user_id__delete","parameters":[{"name":"assignment_uuid","in":"path","required":true,"schema":{"type":"string","title":"Assignment Uuid"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}}],"responses":{"200":{"description":"Assignment submission deleted.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to delete this submission"},"404":{"description":"Assignment, user, or submission not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assignments/{assignment_uuid}/submissions/{user_id}/grade":{"get":{"tags":["assignments"],"summary":"Get assignment submission grade","description":"Read the computed grade for a user's assignment submission.","operationId":"api_get_submission_grade_api_v1_assignments__assignment_uuid__submissions__user_id__grade_get","parameters":[{"name":"assignment_uuid","in":"path","required":true,"schema":{"type":"string","title":"Assignment Uuid"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}}],"responses":{"200":{"description":"Grade information for the submission.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to view this grade"},"404":{"description":"Assignment, user, or submission not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["assignments"],"summary":"Finalize assignment submission grade","description":"Compute and store the final grade for an assignment submission. Accepts an optional overall_feedback note that will be stored alongside the grade.","operationId":"api_final_grade_submission_api_v1_assignments__assignment_uuid__submissions__user_id__grade_post","parameters":[{"name":"assignment_uuid","in":"path","required":true,"schema":{"type":"string","title":"Assignment Uuid"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/GradeSubmissionBody"},{"type":"null"}],"title":"Body"}}}},"responses":{"200":{"description":"Final grade stored.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to grade this submission"},"404":{"description":"Assignment, user, or submission not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assignments/{assignment_uuid}/submissions/me/retry":{"post":{"tags":["assignments"],"summary":"Retry assignment for current user","description":"Reset the current user's submission so they can attempt the assignment again. Only allowed when the assignment has allow_retries=true, the existing submission is in GRADED state, and the attempt counter is still below max_retries (0 means unlimited). Wipes per-task submissions, resets the trail step, and revokes any course certificate.","operationId":"api_retry_assignment_submission_api_v1_assignments__assignment_uuid__submissions_me_retry_post","parameters":[{"name":"assignment_uuid","in":"path","required":true,"schema":{"type":"string","title":"Assignment Uuid"}}],"responses":{"200":{"description":"Submission reset; returns the new attempt info.","content":{"application/json":{"schema":{}}}},"400":{"description":"Submission is not in a retryable state"},"401":{"description":"Authentication required"},"403":{"description":"Retries disabled or attempt limit reached"},"404":{"description":"Assignment or submission not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assignments/{assignment_uuid}/submissions/{user_id}/done":{"post":{"tags":["assignments"],"summary":"Mark assignment as done for user","description":"Mark the underlying activity as completed for a user once their assignment submission is accepted.","operationId":"api_submission_mark_as_done_api_v1_assignments__assignment_uuid__submissions__user_id__done_post","parameters":[{"name":"assignment_uuid","in":"path","required":true,"schema":{"type":"string","title":"Assignment Uuid"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}}],"responses":{"200":{"description":"Activity marked as done for the user.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to mark this submission as done"},"404":{"description":"Assignment, user, or submission not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assignments/course/{course_uuid}":{"get":{"tags":["assignments"],"summary":"List course assignments","description":"Get all assignments attached to activities within the given course.","operationId":"api_get_assignments_api_v1_assignments_course__course_uuid__get","parameters":[{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","title":"Course Uuid"}}],"responses":{"200":{"description":"List of assignments for the course.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to view this course"},"404":{"description":"Course not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/chapters/":{"post":{"tags":["chapters"],"summary":"Create chapter","description":"Create a new chapter inside an existing course.","operationId":"api_create_coursechapter_api_v1_chapters__post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChapterCreate"}}},"required":true},"responses":{"200":{"description":"Chapter created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChapterRead"}}}},"403":{"description":"User lacks permission to create chapters on this course"},"404":{"description":"Course not found"},"422":{"description":"Invalid chapter payload"}}}},"/api/v1/chapters/{chapter_id}":{"get":{"tags":["chapters"],"summary":"Get chapter by ID","description":"Retrieve a single chapter by its numeric ID.","operationId":"api_get_coursechapter_api_v1_chapters__chapter_id__get","parameters":[{"name":"chapter_id","in":"path","required":true,"schema":{"type":"integer","title":"Chapter Id"}}],"responses":{"200":{"description":"Chapter retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChapterRead"}}}},"403":{"description":"User lacks read access to this chapter"},"404":{"description":"Chapter not found"},"409":{"description":"Chapter does not exist"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["chapters"],"summary":"Update chapter","description":"Update the name or other metadata of a chapter by its ID.","operationId":"api_update_coursechapter_api_v1_chapters__chapter_id__put","parameters":[{"name":"chapter_id","in":"path","required":true,"schema":{"type":"integer","title":"Chapter Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChapterUpdate"}}}},"responses":{"200":{"description":"Chapter updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChapterRead"}}}},"403":{"description":"User lacks permission to modify this chapter"},"404":{"description":"Chapter not found"},"409":{"description":"Chapter does not exist"},"422":{"description":"Invalid chapter payload"}}},"delete":{"tags":["chapters"],"summary":"Delete chapter","description":"Delete a chapter and detach its activities from the course.","operationId":"api_delete_coursechapter_api_v1_chapters__chapter_id__delete","parameters":[{"name":"chapter_id","in":"path","required":true,"schema":{"type":"integer","title":"Chapter Id"}}],"responses":{"200":{"description":"Chapter deleted successfully","content":{"application/json":{"schema":{}}}},"403":{"description":"User lacks permission to delete this chapter"},"404":{"description":"Chapter not found"},"409":{"description":"Chapter does not exist"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/chapters/course/{course_uuid}/meta":{"get":{"tags":["chapters"],"summary":"Get chapters metadata (deprecated)","description":"Deprecated endpoint returning chapter metadata for a course. Use /course/{course_uuid}/meta on the courses router instead.","operationId":"api_get_chapter_meta_api_v1_chapters_course__course_uuid__meta_get","deprecated":true,"parameters":[{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","title":"Course Uuid"}}],"responses":{"200":{"description":"Chapter metadata","content":{"application/json":{"schema":{}}}},"403":{"description":"User lacks read access to the course"},"404":{"description":"Course not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/chapters/course/{course_uuid}/order":{"put":{"tags":["chapters"],"summary":"Reorder chapters and activities","description":"Update the ordering of chapters and the activities nested inside them for a given course.","operationId":"api_update_chapter_meta_api_v1_chapters_course__course_uuid__order_put","parameters":[{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","title":"Course Uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChapterUpdateOrder"}}}},"responses":{"200":{"description":"Order updated successfully","content":{"application/json":{"schema":{}}}},"403":{"description":"User lacks permission to modify this course"},"404":{"description":"Course not found"},"409":{"description":"Course does not exist"},"422":{"description":"Invalid order payload"}}}},"/api/v1/chapters/course/{course_id}/page/{page}/limit/{limit}":{"get":{"tags":["chapters"],"summary":"List course chapters","description":"Paginated list of chapters for the specified course.","operationId":"api_get_chapter_by_api_v1_chapters_course__course_id__page__page__limit__limit__get","parameters":[{"name":"course_id","in":"path","required":true,"schema":{"type":"integer","title":"Course Id"}},{"name":"page","in":"path","required":true,"schema":{"type":"integer","title":"Page"}},{"name":"limit","in":"path","required":true,"schema":{"type":"integer","title":"Limit"}}],"responses":{"200":{"description":"Paginated list of chapters","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ChapterRead"},"title":"Response 200 Api Get Chapter By Api V1 Chapters Course  Course Id  Page  Page  Limit  Limit  Get"}}}},"403":{"description":"User lacks read access to the course"},"404":{"description":"Course not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/chapters/{chapter_uuid}/usergroups":{"get":{"tags":["chapters"],"summary":"List user groups assigned to a locked chapter","description":"Return the user groups that can access this chapter when lock_type is 'restricted'.","operationId":"api_list_chapter_usergroups_api_v1_chapters__chapter_uuid__usergroups_get","parameters":[{"name":"chapter_uuid","in":"path","required":true,"schema":{"type":"string","title":"Chapter Uuid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/chapters/{chapter_uuid}/usergroups/{usergroup_uuid}":{"post":{"tags":["chapters"],"summary":"Grant a user group access to a locked chapter","description":"Associate a user group with this chapter so its members can access it when lock_type is 'restricted'.","operationId":"api_add_chapter_usergroup_api_v1_chapters__chapter_uuid__usergroups__usergroup_uuid__post","parameters":[{"name":"chapter_uuid","in":"path","required":true,"schema":{"type":"string","title":"Chapter Uuid"}},{"name":"usergroup_uuid","in":"path","required":true,"schema":{"type":"string","title":"Usergroup Uuid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["chapters"],"summary":"Revoke a user group's access to a locked chapter","description":"Remove the association between a user group and this chapter.","operationId":"api_remove_chapter_usergroup_api_v1_chapters__chapter_uuid__usergroups__usergroup_uuid__delete","parameters":[{"name":"chapter_uuid","in":"path","required":true,"schema":{"type":"string","title":"Chapter Uuid"}},{"name":"usergroup_uuid","in":"path","required":true,"schema":{"type":"string","title":"Usergroup Uuid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/activities/":{"post":{"tags":["activities"],"summary":"Create activity","description":"Create a new activity inside a chapter. The authenticated user must have permission to edit the parent course.","operationId":"api_create_activity_api_v1_activities__post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivityCreate"}}},"required":true},"responses":{"200":{"description":"Activity created and returned.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivityRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to create activities in this chapter"},"404":{"description":"Parent chapter or course not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/activities/{activity_uuid}/versions":{"get":{"tags":["activities"],"summary":"List activity versions","description":"Get the version history for an activity, ordered newest first. Supports pagination via limit and offset.","operationId":"api_get_activity_versions_api_v1_activities__activity_uuid__versions_get","parameters":[{"name":"activity_uuid","in":"path","required":true,"schema":{"type":"string","title":"Activity Uuid"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"List of activity versions.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ActivityVersionRead"},"title":"Response 200 Api Get Activity Versions Api V1 Activities  Activity Uuid  Versions Get"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to view this activity's versions"},"404":{"description":"Activity not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/activities/{activity_uuid}/versions/{version_number}":{"get":{"tags":["activities"],"summary":"Get activity version","description":"Get a specific historical version of an activity by its version number.","operationId":"api_get_activity_version_api_v1_activities__activity_uuid__versions__version_number__get","parameters":[{"name":"activity_uuid","in":"path","required":true,"schema":{"type":"string","title":"Activity Uuid"}},{"name":"version_number","in":"path","required":true,"schema":{"type":"integer","title":"Version Number"}}],"responses":{"200":{"description":"Activity version returned.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivityVersionRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to view this activity version"},"404":{"description":"Activity or version not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/activities/{activity_uuid}/state":{"get":{"tags":["activities"],"summary":"Get activity state","description":"Get the current state of an activity for conflict detection. Returns lightweight info (update_date, current_version, last_modified_by) used by the frontend to detect remote changes.","operationId":"api_get_activity_state_api_v1_activities__activity_uuid__state_get","parameters":[{"name":"activity_uuid","in":"path","required":true,"schema":{"type":"string","title":"Activity Uuid"}}],"responses":{"200":{"description":"Current activity state.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivityStateRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to view this activity"},"404":{"description":"Activity not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/activities/{activity_uuid}/versions/{version_number}/restore":{"post":{"tags":["activities"],"summary":"Restore activity version","description":"Restore an activity to a previous version. Creates a new version with the restored content rather than rewriting history.","operationId":"api_restore_activity_version_api_v1_activities__activity_uuid__versions__version_number__restore_post","parameters":[{"name":"activity_uuid","in":"path","required":true,"schema":{"type":"string","title":"Activity Uuid"}},{"name":"version_number","in":"path","required":true,"schema":{"type":"integer","title":"Version Number"}}],"responses":{"200":{"description":"Activity restored; returns the updated activity.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivityRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to restore this activity"},"404":{"description":"Activity or version not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/activities/{activity_uuid}/editor-bootstrap":{"get":{"tags":["activities"],"summary":"Editor bootstrap payload","description":"Single-roundtrip payload for the activity editor: activity + minimal course + org with resolved features.","operationId":"api_get_editor_bootstrap_api_v1_activities__activity_uuid__editor_bootstrap_get","parameters":[{"name":"activity_uuid","in":"path","required":true,"schema":{"type":"string","title":"Activity Uuid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EditorBootstrapResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/activities/{activity_uuid}":{"get":{"tags":["activities"],"summary":"Get activity by UUID","description":"Get a single activity by its UUID.","operationId":"api_get_activity_api_v1_activities__activity_uuid__get","parameters":[{"name":"activity_uuid","in":"path","required":true,"schema":{"type":"string","title":"Activity Uuid"}}],"responses":{"200":{"description":"Activity returned.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivityRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to view this activity"},"404":{"description":"Activity not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["activities"],"summary":"Update activity","description":"Update an activity's fields by its UUID. Creates a new version when content changes.","operationId":"api_update_activity_api_v1_activities__activity_uuid__put","parameters":[{"name":"activity_uuid","in":"path","required":true,"schema":{"type":"string","title":"Activity Uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivityUpdate"}}}},"responses":{"200":{"description":"Activity updated and returned.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivityRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to update this activity"},"404":{"description":"Activity not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["activities"],"summary":"Delete activity","description":"Delete an activity by its UUID. The authenticated user must have permission to edit the parent course.","operationId":"api_delete_activity_api_v1_activities__activity_uuid__delete","parameters":[{"name":"activity_uuid","in":"path","required":true,"schema":{"type":"string","title":"Activity Uuid"}}],"responses":{"200":{"description":"Activity deleted.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to delete this activity"},"404":{"description":"Activity not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/activities/id/{activity_id}":{"get":{"tags":["activities"],"summary":"Get activity by ID","description":"Get a single activity by its numeric database ID.","operationId":"api_get_activityby_id_api_v1_activities_id__activity_id__get","parameters":[{"name":"activity_id","in":"path","required":true,"schema":{"type":"integer","title":"Activity Id"}}],"responses":{"200":{"description":"Activity returned.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivityRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to view this activity"},"404":{"description":"Activity not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/activities/chapter/{chapter_id}":{"get":{"tags":["activities"],"summary":"List chapter activities","description":"Get all activities that belong to the given chapter, in their configured order.","operationId":"api_get_chapter_activities_api_v1_activities_chapter__chapter_id__get","parameters":[{"name":"chapter_id","in":"path","required":true,"schema":{"type":"integer","title":"Chapter Id"}}],"responses":{"200":{"description":"List of activities for the chapter.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ActivityRead"},"title":"Response 200 Api Get Chapter Activities Api V1 Activities Chapter  Chapter Id  Get"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to view this chapter"},"404":{"description":"Chapter not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/activities/video":{"post":{"tags":["activities"],"summary":"Create video activity","description":"Create a new video activity by uploading a video file. The video is stored and attached to the given chapter.","operationId":"api_create_video_activity_api_v1_activities_video_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_api_create_video_activity_api_v1_activities_video_post"}}},"required":true},"responses":{"200":{"description":"Video activity created and returned.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivityRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to create activities in this chapter"},"404":{"description":"Chapter not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/activities/external_video":{"post":{"tags":["activities"],"summary":"Create external video activity","description":"Create a new activity that embeds an externally hosted video (e.g. YouTube, Vimeo) instead of uploading a file.","operationId":"api_create_external_video_activity_api_v1_activities_external_video_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExternalVideo"}}},"required":true},"responses":{"200":{"description":"External video activity created and returned.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivityRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to create activities in this chapter"},"404":{"description":"Chapter not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/activities/documentpdf":{"post":{"tags":["activities"],"summary":"Create PDF document activity","description":"Create a new activity by uploading a PDF document. The file is stored and attached to the given chapter.","operationId":"api_create_documentpdf_activity_api_v1_activities_documentpdf_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_api_create_documentpdf_activity_api_v1_activities_documentpdf_post"}}},"required":true},"responses":{"200":{"description":"PDF activity created and returned.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivityRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to create activities in this chapter"},"404":{"description":"Chapter not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/activities/video/{activity_uuid}":{"put":{"tags":["activities"],"summary":"Update hosted video activity","operationId":"api_update_video_activity_api_v1_activities_video__activity_uuid__put","parameters":[{"name":"activity_uuid","in":"path","required":true,"schema":{"type":"string","title":"Activity Uuid"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_api_update_video_activity_api_v1_activities_video__activity_uuid__put"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivityRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/activities/video/{activity_uuid}/captions":{"post":{"tags":["activities"],"summary":"Configure AI closed captions for a hosted video activity","description":"Enable/disable AI-generated captions and choose the target languages (any of the platform's languages, or custom BCP-47 codes). When enabled, queues generation on the AI captions pipeline (metered against the org's AI credits). Returns the stored captions metadata.","operationId":"api_configure_video_captions_api_v1_activities_video__activity_uuid__captions_post","parameters":[{"name":"activity_uuid","in":"path","required":true,"schema":{"type":"string","title":"Activity Uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CaptionsConfigIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Api Configure Video Captions Api V1 Activities Video  Activity Uuid  Captions Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/activities/external_video/{activity_uuid}":{"put":{"tags":["activities"],"summary":"Update external video activity","operationId":"api_update_external_video_activity_api_v1_activities_external_video__activity_uuid__put","parameters":[{"name":"activity_uuid","in":"path","required":true,"schema":{"type":"string","title":"Activity Uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExternalVideoUpdateBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivityRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/activities/documentpdf/{activity_uuid}":{"put":{"tags":["activities"],"summary":"Update PDF document activity","operationId":"api_update_documentpdf_activity_api_v1_activities_documentpdf__activity_uuid__put","parameters":[{"name":"activity_uuid","in":"path","required":true,"schema":{"type":"string","title":"Activity Uuid"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_api_update_documentpdf_activity_api_v1_activities_documentpdf__activity_uuid__put"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivityRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/activities/{activity_uuid}/usergroups":{"get":{"tags":["activities"],"summary":"List user groups assigned to a locked activity","description":"Return the user groups that can access this activity when lock_type is 'restricted'.","operationId":"api_list_activity_usergroups_api_v1_activities__activity_uuid__usergroups_get","parameters":[{"name":"activity_uuid","in":"path","required":true,"schema":{"type":"string","title":"Activity Uuid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/activities/{activity_uuid}/usergroups/{usergroup_uuid}":{"post":{"tags":["activities"],"summary":"Grant a user group access to a locked activity","description":"Associate a user group with this activity so its members can access it when lock_type is 'restricted'.","operationId":"api_add_activity_usergroup_api_v1_activities__activity_uuid__usergroups__usergroup_uuid__post","parameters":[{"name":"activity_uuid","in":"path","required":true,"schema":{"type":"string","title":"Activity Uuid"}},{"name":"usergroup_uuid","in":"path","required":true,"schema":{"type":"string","title":"Usergroup Uuid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["activities"],"summary":"Revoke a user group's access to a locked activity","description":"Remove the association between a user group and this activity.","operationId":"api_remove_activity_usergroup_api_v1_activities__activity_uuid__usergroups__usergroup_uuid__delete","parameters":[{"name":"activity_uuid","in":"path","required":true,"schema":{"type":"string","title":"Activity Uuid"}},{"name":"usergroup_uuid","in":"path","required":true,"schema":{"type":"string","title":"Usergroup Uuid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/folders/":{"post":{"tags":["folders"],"summary":"Create folder","description":"Create a new folder (optionally nested under a parent folder) within an organization.","operationId":"api_create_folder_api_v1_folders__post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FolderCreate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FolderRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/folders/{folder_uuid}":{"get":{"tags":["folders"],"summary":"Get folder","description":"Get a single folder by its UUID, including its sub-folders, items and breadcrumbs.","operationId":"api_get_folder_api_v1_folders__folder_uuid__get","parameters":[{"name":"folder_uuid","in":"path","required":true,"schema":{"type":"string","title":"Folder Uuid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FolderRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["folders"],"summary":"Update folder","description":"Update a folder by its UUID. Pass `parent_folder_uuid` to move it (use empty/'root' to move to root).","operationId":"api_update_folder_api_v1_folders__folder_uuid__put","parameters":[{"name":"folder_uuid","in":"path","required":true,"schema":{"type":"string","title":"Folder Uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FolderUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FolderRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["folders"],"summary":"Delete folder","description":"Delete a folder by its UUID. Sub-folders and item placements are removed with it.","operationId":"api_delete_folder_api_v1_folders__folder_uuid__delete","parameters":[{"name":"folder_uuid","in":"path","required":true,"schema":{"type":"string","title":"Folder Uuid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/folders/org/{org_id}/page/{page}/limit/{limit}":{"get":{"tags":["folders"],"summary":"List folders for org","description":"List folders for an organization. By default lists root folders; pass `parent_folder_uuid` to list a folder's direct sub-folders.","operationId":"api_get_folders_by_api_v1_folders_org__org_id__page__page__limit__limit__get","parameters":[{"name":"page","in":"path","required":true,"schema":{"type":"integer","title":"Page"}},{"name":"limit","in":"path","required":true,"schema":{"type":"integer","title":"Limit"}},{"name":"org_id","in":"path","required":true,"schema":{"type":"string","title":"Org Id"}},{"name":"parent_folder_uuid","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Folder Uuid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/FolderRead"},"title":"Response Api Get Folders By Api V1 Folders Org  Org Id  Page  Page  Limit  Limit  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/folders/org/{org_id}/search":{"get":{"tags":["folders"],"summary":"Search the library tree","description":"Search folders and content across the whole library tree; each result includes its folder-path context.","operationId":"api_search_library_api_v1_folders_org__org_id__search_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","title":"Org Id"}},{"name":"q","in":"query","required":true,"schema":{"type":"string","title":"Q"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/folders/org/{org_id}/order":{"put":{"tags":["folders"],"summary":"Reorder library folders","description":"Persist the manual (admin drag) ordering of sibling folders. Reorders root folders by default; pass `parent_folder_uuid` to reorder a folder's direct sub-folders. Admin only.","operationId":"api_reorder_folders_api_v1_folders_org__org_id__order_put","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"parent_folder_uuid","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Folder Uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FolderUpdateOrder"}}}},"responses":{"200":{"description":"Folder order updated","content":{"application/json":{"schema":{}}}},"400":{"description":"A folder id is not in the org/parent scope"},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not an organization administrator"},"404":{"description":"Organization or parent folder not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/folders/{folder_uuid}/content/order":{"put":{"tags":["folders"],"summary":"Reorder a folder's content items","description":"Persist the manual (admin drag) ordering of a folder's content (courses, media, …). Position is derived from the array index. Admin only.","operationId":"api_reorder_folder_content_api_v1_folders__folder_uuid__content_order_put","parameters":[{"name":"folder_uuid","in":"path","required":true,"schema":{"type":"string","title":"Folder Uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FolderContentUpdateOrder"}}}},"responses":{"200":{"description":"Folder content order updated","content":{"application/json":{"schema":{}}}},"400":{"description":"A resource is not in this folder"},"401":{"description":"Not authenticated"},"403":{"description":"Caller is not an organization administrator"},"404":{"description":"Folder or organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/folders/org/{org_id}/root":{"get":{"tags":["folders"],"summary":"List org library root items","description":"List the items placed directly at the organization library root (not inside any folder).","operationId":"api_get_org_root_items_api_v1_folders_org__org_id__root_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","title":"Org Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/FolderContentItem"},"title":"Response Api Get Org Root Items Api V1 Folders Org  Org Id  Root Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/folders/org/{org_id}/content":{"post":{"tags":["folders"],"summary":"Add content to library root","description":"Place a resource directly at the organization library root (Drive-like).","operationId":"api_add_org_root_content_api_v1_folders_org__org_id__content_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"resource_uuid","in":"query","required":true,"schema":{"type":"string","title":"Resource Uuid"}},{"name":"position","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Position"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["folders"],"summary":"Remove content from library root","description":"Remove a resource placement from the organization library root.","operationId":"api_remove_org_root_content_api_v1_folders_org__org_id__content_delete","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"resource_uuid","in":"query","required":true,"schema":{"type":"string","title":"Resource Uuid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/folders/{folder_uuid}/thumbnail":{"put":{"tags":["folders"],"summary":"Upload folder cover image","description":"Upload a cover image (thumbnail) for a folder.","operationId":"api_upload_folder_thumbnail_api_v1_folders__folder_uuid__thumbnail_put","parameters":[{"name":"folder_uuid","in":"path","required":true,"schema":{"type":"string","title":"Folder Uuid"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_api_upload_folder_thumbnail_api_v1_folders__folder_uuid__thumbnail_put"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FolderRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/folders/{folder_uuid}/content":{"post":{"tags":["folders"],"summary":"Add content to folder","description":"Place a resource (course/podcast/community/board/playground/media) into a folder.","operationId":"api_add_folder_content_api_v1_folders__folder_uuid__content_post","parameters":[{"name":"folder_uuid","in":"path","required":true,"schema":{"type":"string","title":"Folder Uuid"}},{"name":"resource_uuid","in":"query","required":true,"schema":{"type":"string","title":"Resource Uuid"}},{"name":"position","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Position"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FolderRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["folders"],"summary":"Remove content from folder","description":"Remove a resource placement from a folder (the resource itself is not deleted).","operationId":"api_remove_folder_content_api_v1_folders__folder_uuid__content_delete","parameters":[{"name":"folder_uuid","in":"path","required":true,"schema":{"type":"string","title":"Folder Uuid"}},{"name":"resource_uuid","in":"query","required":true,"schema":{"type":"string","title":"Resource Uuid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FolderRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/folders/{folder_uuid}/content/move":{"post":{"tags":["folders"],"summary":"Move content between folders","description":"Move a resource placement from this folder to a target folder.","operationId":"api_move_folder_content_api_v1_folders__folder_uuid__content_move_post","parameters":[{"name":"folder_uuid","in":"path","required":true,"schema":{"type":"string","title":"Folder Uuid"}},{"name":"target_folder_uuid","in":"query","required":true,"schema":{"type":"string","title":"Target Folder Uuid"}},{"name":"resource_uuid","in":"query","required":true,"schema":{"type":"string","title":"Resource Uuid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FolderRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/media/{media_uuid}/file":{"get":{"tags":["media"],"summary":"Serve a media file","description":"Streams the media file's bytes after enforcing access (folder-aware). The storage path is never exposed to the client. Supports Range requests.","operationId":"api_serve_media_file_api_v1_media__media_uuid__file_get","parameters":[{"name":"media_uuid","in":"path","required":true,"schema":{"type":"string","title":"Media Uuid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"head":{"tags":["media"],"summary":"Media file metadata","operationId":"api_head_media_file_api_v1_media__media_uuid__file_head","parameters":[{"name":"media_uuid","in":"path","required":true,"schema":{"type":"string","title":"Media Uuid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/media/{media_uuid}/share-link":{"post":{"tags":["media"],"summary":"Create a media share link","description":"Mints a fresh random, revocable token each call. The link is NOT an access bypass — recipients still need access.","operationId":"api_create_media_share_link_api_v1_media__media_uuid__share_link_post","parameters":[{"name":"media_uuid","in":"path","required":true,"schema":{"type":"string","title":"Media Uuid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/media/shared/{token}/file":{"get":{"tags":["media"],"summary":"Serve a shared media file by token","operationId":"api_serve_shared_media_api_v1_media_shared__token__file_get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"head":{"tags":["media"],"summary":"Shared media file metadata by token","operationId":"api_head_shared_media_api_v1_media_shared__token__file_head","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/media/":{"post":{"tags":["media"],"summary":"Create media","description":"Create a media asset. For UPLOAD, send a multipart file. For EMBED, send a url.","operationId":"api_create_media_api_v1_media__post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_api_create_media_api_v1_media__post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/media/{media_uuid}":{"get":{"tags":["media"],"summary":"Get media","description":"Get a single media asset by its UUID.","operationId":"api_get_media_api_v1_media__media_uuid__get","parameters":[{"name":"media_uuid","in":"path","required":true,"schema":{"type":"string","title":"Media Uuid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["media"],"summary":"Update media","description":"Update a media asset's metadata.","operationId":"api_update_media_api_v1_media__media_uuid__put","parameters":[{"name":"media_uuid","in":"path","required":true,"schema":{"type":"string","title":"Media Uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["media"],"summary":"Delete media","description":"Delete a media asset and remove it from any folders.","operationId":"api_delete_media_api_v1_media__media_uuid__delete","parameters":[{"name":"media_uuid","in":"path","required":true,"schema":{"type":"string","title":"Media Uuid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/media/org/{org_id}/page/{page}/limit/{limit}":{"get":{"tags":["media"],"summary":"List media for org","description":"List media assets for an organization, paginated.","operationId":"api_get_media_list_api_v1_media_org__org_id__page__page__limit__limit__get","parameters":[{"name":"page","in":"path","required":true,"schema":{"type":"integer","title":"Page"}},{"name":"limit","in":"path","required":true,"schema":{"type":"integer","title":"Limit"}},{"name":"org_id","in":"path","required":true,"schema":{"type":"string","title":"Org Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MediaRead"},"title":"Response Api Get Media List Api V1 Media Org  Org Id  Page  Page  Limit  Limit  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/communities/":{"post":{"tags":["communities"],"summary":"Create a community","description":"Create a new community inside an organization. Optionally link it to a course on creation. Requires admin/maintainer role.","operationId":"api_create_community_api_v1_communities__post","parameters":[{"name":"org_id","in":"query","required":true,"schema":{"type":"integer","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommunityCreateRequest"}}}},"responses":{"200":{"description":"Community created successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommunityRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks admin/maintainer role for the organization"},"404":{"description":"Organization or course not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/communities/{community_uuid}":{"get":{"tags":["communities"],"summary":"Get a community","description":"Retrieve a community by its UUID. The caller must be able to read the community.","operationId":"api_get_community_api_v1_communities__community_uuid__get","parameters":[{"name":"community_uuid","in":"path","required":true,"schema":{"type":"string","title":"Community Uuid"}}],"responses":{"200":{"description":"Community retrieved.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommunityRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"User does not have read access to this community"},"404":{"description":"Community not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["communities"],"summary":"Update a community","description":"Update an existing community's attributes. Requires admin/maintainer role.","operationId":"api_update_community_api_v1_communities__community_uuid__put","parameters":[{"name":"community_uuid","in":"path","required":true,"schema":{"type":"string","title":"Community Uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommunityUpdate"}}}},"responses":{"200":{"description":"Community updated successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommunityRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks admin/maintainer role for this community"},"404":{"description":"Community not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["communities"],"summary":"Delete a community","description":"Permanently delete a community. Requires admin/maintainer role.","operationId":"api_delete_community_api_v1_communities__community_uuid__delete","parameters":[{"name":"community_uuid","in":"path","required":true,"schema":{"type":"string","title":"Community Uuid"}}],"responses":{"200":{"description":"Community deleted successfully.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Api Delete Community Api V1 Communities  Community Uuid  Delete"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks admin/maintainer role for this community"},"404":{"description":"Community not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/communities/org/{org_id}/page/{page}/limit/{limit}":{"get":{"tags":["communities"],"summary":"List communities for an organization","description":"Retrieve a paginated list of communities belonging to an organization.","operationId":"api_get_communities_by_org_api_v1_communities_org__org_id__page__page__limit__limit__get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"page","in":"path","required":true,"schema":{"type":"integer","minimum":1,"title":"Page"}},{"name":"limit","in":"path","required":true,"schema":{"type":"integer","maximum":1000,"minimum":1,"title":"Limit"}}],"responses":{"200":{"description":"Paginated list of communities.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CommunityRead"},"title":"Response 200 Api Get Communities By Org Api V1 Communities Org  Org Id  Page  Page  Limit  Limit  Get"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks access to this organization's communities"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/communities/course/{course_uuid}":{"get":{"tags":["communities"],"summary":"Get community for a course","description":"Retrieve the community that is linked to a specific course, if one exists.","operationId":"api_get_community_by_course_api_v1_communities_course__course_uuid__get","parameters":[{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","title":"Course Uuid"}}],"responses":{"200":{"description":"Community linked to the course, or null if no community is linked.","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/CommunityRead"},{"type":"null"}],"title":"Response Api Get Community By Course Api V1 Communities Course  Course Uuid  Get"}}}},"401":{"description":"Authentication required"},"403":{"description":"User does not have access to this course"},"404":{"description":"Course not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/communities/{community_uuid}/link-course/{course_uuid}":{"put":{"tags":["communities"],"summary":"Link community to a course","description":"Associate a community with a course so that course members can participate. Requires admin/maintainer role.","operationId":"api_link_community_to_course_api_v1_communities__community_uuid__link_course__course_uuid__put","parameters":[{"name":"community_uuid","in":"path","required":true,"schema":{"type":"string","title":"Community Uuid"}},{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","title":"Course Uuid"}}],"responses":{"200":{"description":"Community linked to course.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommunityRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks admin/maintainer role for this community"},"404":{"description":"Community or course not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/communities/{community_uuid}/unlink-course":{"delete":{"tags":["communities"],"summary":"Unlink community from its course","description":"Remove the association between a community and its currently linked course. Requires admin/maintainer role.","operationId":"api_unlink_community_from_course_api_v1_communities__community_uuid__unlink_course_delete","parameters":[{"name":"community_uuid","in":"path","required":true,"schema":{"type":"string","title":"Community Uuid"}}],"responses":{"200":{"description":"Community unlinked from course.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommunityRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks admin/maintainer role for this community"},"404":{"description":"Community not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/communities/{community_uuid}/rights":{"get":{"tags":["communities"],"summary":"Get current user rights for a community","description":"Return a detailed breakdown of the rights the current user has on a community (read, write, moderate, admin).","operationId":"api_get_community_rights_api_v1_communities__community_uuid__rights_get","parameters":[{"name":"community_uuid","in":"path","required":true,"schema":{"type":"string","title":"Community Uuid"}}],"responses":{"200":{"description":"User rights for the community.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Api Get Community Rights Api V1 Communities  Community Uuid  Rights Get"}}}},"401":{"description":"Authentication required"},"404":{"description":"Community not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/communities/{community_uuid}/thumbnail":{"put":{"tags":["communities"],"summary":"Upload a community thumbnail","description":"Upload or replace the thumbnail image for a community. Requires admin/maintainer role.","operationId":"api_update_community_thumbnail_api_v1_communities__community_uuid__thumbnail_put","parameters":[{"name":"community_uuid","in":"path","required":true,"schema":{"type":"string","title":"Community Uuid"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_api_update_community_thumbnail_api_v1_communities__community_uuid__thumbnail_put"}}}},"responses":{"200":{"description":"Thumbnail uploaded and community updated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommunityRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks admin/maintainer role for this community"},"404":{"description":"Community or organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/discussions/labels":{"get":{"tags":["discussions"],"summary":"List discussion labels","description":"Return the catalog of labels (category tags) that can be assigned to discussions.","operationId":"api_get_discussion_labels_api_v1_discussions_labels_get","responses":{"200":{"description":"Available discussion labels.","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/DiscussionLabelInfo"},"type":"array","title":"Response 200 Api Get Discussion Labels Api V1 Discussions Labels Get"}}}}}}},"/api/v1/communities/{community_uuid}/discussions":{"post":{"tags":["discussions"],"summary":"Create a discussion","description":"Create a new discussion thread inside a community. Requires an authenticated user with read access to the community.","operationId":"api_create_discussion_api_v1_communities__community_uuid__discussions_post","parameters":[{"name":"community_uuid","in":"path","required":true,"schema":{"type":"string","title":"Community Uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DiscussionCreateRequest"}}}},"responses":{"200":{"description":"Discussion created successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DiscussionReadWithVoteStatus"}}}},"401":{"description":"Authentication required"},"403":{"description":"User does not have access to this community"},"404":{"description":"Community not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["discussions"],"summary":"List discussions in a community","description":"Retrieve a paginated list of discussions for a community with sorting and optional label filtering. Pinned discussions are always returned first.","operationId":"api_get_discussions_by_community_api_v1_communities__community_uuid__discussions_get","parameters":[{"name":"community_uuid","in":"path","required":true,"schema":{"type":"string","title":"Community Uuid"}},{"name":"sort_by","in":"query","required":false,"schema":{"$ref":"#/components/schemas/DiscussionSortBy","default":"recent"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":10,"title":"Limit"}},{"name":"label","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label"}}],"responses":{"200":{"description":"Discussions for the community.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DiscussionReadWithVoteStatus"},"title":"Response 200 Api Get Discussions By Community Api V1 Communities  Community Uuid  Discussions Get"}}}},"401":{"description":"Authentication required"},"403":{"description":"User does not have access to this community"},"404":{"description":"Community not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/discussions/{discussion_uuid}":{"get":{"tags":["discussions"],"summary":"Get a discussion","description":"Retrieve a single discussion by its UUID, including the current user's vote status.","operationId":"api_get_discussion_api_v1_discussions__discussion_uuid__get","parameters":[{"name":"discussion_uuid","in":"path","required":true,"schema":{"type":"string","title":"Discussion Uuid"}}],"responses":{"200":{"description":"Discussion retrieved.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DiscussionReadWithVoteStatus"}}}},"401":{"description":"Authentication required"},"403":{"description":"User does not have access to this discussion's community"},"404":{"description":"Discussion not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["discussions"],"summary":"Update a discussion","description":"Update a discussion's title, content, or label. Requires the discussion author or an admin role.","operationId":"api_update_discussion_api_v1_discussions__discussion_uuid__put","parameters":[{"name":"discussion_uuid","in":"path","required":true,"schema":{"type":"string","title":"Discussion Uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DiscussionUpdate"}}}},"responses":{"200":{"description":"Discussion updated successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DiscussionReadWithVoteStatus"}}}},"401":{"description":"Authentication required"},"403":{"description":"User is not the author or lacks admin role"},"404":{"description":"Discussion not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["discussions"],"summary":"Delete a discussion","description":"Permanently delete a discussion and its associated comments. Requires the discussion author or an admin role.","operationId":"api_delete_discussion_api_v1_discussions__discussion_uuid__delete","parameters":[{"name":"discussion_uuid","in":"path","required":true,"schema":{"type":"string","title":"Discussion Uuid"}}],"responses":{"200":{"description":"Discussion deleted successfully.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Api Delete Discussion Api V1 Discussions  Discussion Uuid  Delete"}}}},"401":{"description":"Authentication required"},"403":{"description":"User is not the author or lacks admin role"},"404":{"description":"Discussion not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/discussions/{discussion_uuid}/pin":{"put":{"tags":["discussions"],"summary":"Pin or unpin a discussion","description":"Toggle the pinned state of a discussion. Requires a community admin or maintainer role.","operationId":"api_pin_discussion_api_v1_discussions__discussion_uuid__pin_put","parameters":[{"name":"discussion_uuid","in":"path","required":true,"schema":{"type":"string","title":"Discussion Uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DiscussionPinUpdate"}}}},"responses":{"200":{"description":"Discussion pin state updated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DiscussionReadWithVoteStatus"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks the required moderator role"},"404":{"description":"Discussion not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/discussions/{discussion_uuid}/lock":{"put":{"tags":["discussions"],"summary":"Lock or unlock a discussion","description":"Toggle the locked state of a discussion. Locked discussions cannot receive new comments. Requires a community admin or maintainer role.","operationId":"api_lock_discussion_api_v1_discussions__discussion_uuid__lock_put","parameters":[{"name":"discussion_uuid","in":"path","required":true,"schema":{"type":"string","title":"Discussion Uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DiscussionLockUpdate"}}}},"responses":{"200":{"description":"Discussion lock state updated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DiscussionReadWithVoteStatus"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks the required moderator role"},"404":{"description":"Discussion not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/discussions/{discussion_uuid}/vote":{"post":{"tags":["discussions"],"summary":"Upvote a discussion","description":"Cast an upvote for a discussion on behalf of the current user. Requires read access to the community.","operationId":"api_upvote_discussion_api_v1_discussions__discussion_uuid__vote_post","parameters":[{"name":"discussion_uuid","in":"path","required":true,"schema":{"type":"string","title":"Discussion Uuid"}}],"responses":{"200":{"description":"Upvote registered.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DiscussionVoteRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"User does not have access to this discussion's community"},"404":{"description":"Discussion not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["discussions"],"summary":"Remove an upvote from a discussion","description":"Remove the current user's upvote from a discussion. The user must have previously voted.","operationId":"api_remove_upvote_api_v1_discussions__discussion_uuid__vote_delete","parameters":[{"name":"discussion_uuid","in":"path","required":true,"schema":{"type":"string","title":"Discussion Uuid"}}],"responses":{"200":{"description":"Upvote removed.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Api Remove Upvote Api V1 Discussions  Discussion Uuid  Vote Delete"}}}},"401":{"description":"Authentication required"},"403":{"description":"User does not have access to this discussion's community"},"404":{"description":"Discussion or existing vote not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/discussions/votes/batch":{"post":{"tags":["discussions"],"summary":"Batch check user vote status","description":"Check in bulk whether the current user has upvoted each of the supplied discussion UUIDs. Returns a mapping of discussion_uuid to voted status.","operationId":"api_get_user_votes_batch_api_v1_discussions_votes_batch_post","requestBody":{"content":{"application/json":{"schema":{"items":{"type":"string"},"type":"array","title":"Discussion Uuids"}}},"required":true},"responses":{"200":{"description":"Mapping of discussion_uuid to voted status.","content":{"application/json":{"schema":{"additionalProperties":{"type":"boolean"},"type":"object","title":"Response Api Get User Votes Batch Api V1 Discussions Votes Batch Post"}}}},"401":{"description":"Authentication required"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/discussions/{discussion_uuid}/comments":{"post":{"tags":["discussions"],"summary":"Create a comment","description":"Post a new comment on a discussion. Requires read access to the community and the discussion must not be locked.","operationId":"api_create_comment_api_v1_discussions__discussion_uuid__comments_post","parameters":[{"name":"discussion_uuid","in":"path","required":true,"schema":{"type":"string","title":"Discussion Uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommentCreateRequest"}}}},"responses":{"200":{"description":"Comment created successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DiscussionCommentReadWithVoteStatus"}}}},"401":{"description":"Authentication required"},"403":{"description":"User does not have access to this community or discussion is locked"},"404":{"description":"Discussion not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["discussions"],"summary":"List comments for a discussion","description":"Retrieve a paginated list of comments belonging to a discussion, including the current user's vote status.","operationId":"api_get_comments_by_discussion_api_v1_discussions__discussion_uuid__comments_get","parameters":[{"name":"discussion_uuid","in":"path","required":true,"schema":{"type":"string","title":"Discussion Uuid"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Comments for the discussion.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DiscussionCommentReadWithVoteStatus"},"title":"Response 200 Api Get Comments By Discussion Api V1 Discussions  Discussion Uuid  Comments Get"}}}},"401":{"description":"Authentication required"},"403":{"description":"User does not have access to this discussion's community"},"404":{"description":"Discussion not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/discussions/{discussion_uuid}/comments/count":{"get":{"tags":["discussions"],"summary":"Get comment count for a discussion","description":"Return the total number of comments on a discussion. The caller must be able to read the parent community (public communities are readable by anyone, including anonymous users).","operationId":"api_get_comment_count_api_v1_discussions__discussion_uuid__comments_count_get","parameters":[{"name":"discussion_uuid","in":"path","required":true,"schema":{"type":"string","title":"Discussion Uuid"}}],"responses":{"200":{"description":"Object with the comment count (e.g. {\"count\": 42}).","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Api Get Comment Count Api V1 Discussions  Discussion Uuid  Comments Count Get"}}}},"403":{"description":"Caller cannot read this discussion's community"},"404":{"description":"Discussion not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/comments/{comment_uuid}":{"put":{"tags":["discussions"],"summary":"Update a comment","description":"Edit the content of an existing comment. Requires the comment author.","operationId":"api_update_comment_api_v1_comments__comment_uuid__put","parameters":[{"name":"comment_uuid","in":"path","required":true,"schema":{"type":"string","title":"Comment Uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DiscussionCommentUpdate"}}}},"responses":{"200":{"description":"Comment updated successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DiscussionCommentReadWithVoteStatus"}}}},"401":{"description":"Authentication required"},"403":{"description":"User is not the comment author"},"404":{"description":"Comment not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["discussions"],"summary":"Delete a comment","description":"Permanently delete a comment. Requires the comment author or a community admin.","operationId":"api_delete_comment_api_v1_comments__comment_uuid__delete","parameters":[{"name":"comment_uuid","in":"path","required":true,"schema":{"type":"string","title":"Comment Uuid"}}],"responses":{"200":{"description":"Comment deleted successfully.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Api Delete Comment Api V1 Comments  Comment Uuid  Delete"}}}},"401":{"description":"Authentication required"},"403":{"description":"User is not the author and lacks community admin role"},"404":{"description":"Comment not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/comments/{comment_uuid}/vote":{"post":{"tags":["discussions"],"summary":"Upvote a comment","description":"Cast an upvote for a comment on behalf of the current user. Requires read access to the parent community.","operationId":"api_upvote_comment_api_v1_comments__comment_uuid__vote_post","parameters":[{"name":"comment_uuid","in":"path","required":true,"schema":{"type":"string","title":"Comment Uuid"}}],"responses":{"200":{"description":"Upvote registered.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DiscussionCommentVoteRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"User does not have access to this comment's community"},"404":{"description":"Comment not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["discussions"],"summary":"Remove an upvote from a comment","description":"Remove the current user's upvote from a comment. The user must have previously voted.","operationId":"api_remove_comment_upvote_api_v1_comments__comment_uuid__vote_delete","parameters":[{"name":"comment_uuid","in":"path","required":true,"schema":{"type":"string","title":"Comment Uuid"}}],"responses":{"200":{"description":"Upvote removed.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Api Remove Comment Upvote Api V1 Comments  Comment Uuid  Vote Delete"}}}},"401":{"description":"Authentication required"},"403":{"description":"User does not have access to this comment's community"},"404":{"description":"Comment or existing vote not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/discussions/{discussion_uuid}/reactions":{"get":{"tags":["discussions"],"summary":"List reactions on a discussion","description":"Return all emoji reactions on a discussion, grouped by emoji, with counts and a flag indicating whether the current user has reacted.","operationId":"api_get_reactions_api_v1_discussions__discussion_uuid__reactions_get","parameters":[{"name":"discussion_uuid","in":"path","required":true,"schema":{"type":"string","title":"Discussion Uuid"}}],"responses":{"200":{"description":"Reaction summaries for the discussion.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DiscussionReactionSummary"},"title":"Response 200 Api Get Reactions Api V1 Discussions  Discussion Uuid  Reactions Get"}}}},"401":{"description":"Authentication required"},"403":{"description":"User does not have access to this discussion's community"},"404":{"description":"Discussion not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["discussions"],"summary":"Toggle a reaction on a discussion","description":"Toggle an emoji reaction on a discussion for the current user. If the user has already reacted with this emoji it is removed; otherwise it is added. Requires read access to the community.","operationId":"api_toggle_reaction_api_v1_discussions__discussion_uuid__reactions_post","parameters":[{"name":"discussion_uuid","in":"path","required":true,"schema":{"type":"string","title":"Discussion Uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReactionRequest"}}}},"responses":{"200":{"description":"Reaction toggled; response indicates the new state.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Api Toggle Reaction Api V1 Discussions  Discussion Uuid  Reactions Post"}}}},"401":{"description":"Authentication required"},"403":{"description":"User does not have access to this discussion's community"},"404":{"description":"Discussion not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/podcasts/":{"post":{"tags":["podcasts"],"summary":"Create a podcast","description":"Create a new podcast within an organization. Accepts multipart form data with optional thumbnail upload.","operationId":"api_create_podcast_api_v1_podcasts__post","parameters":[{"name":"org_id","in":"query","required":true,"schema":{"type":"integer","title":"Org Id"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_api_create_podcast_api_v1_podcasts__post"}}}},"responses":{"200":{"description":"Podcast created successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PodcastRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to create podcasts in this organization"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/podcasts/{podcast_uuid}":{"get":{"tags":["podcasts"],"summary":"Get a podcast","description":"Fetch a podcast by its UUID. The caller must have read access to the podcast.","operationId":"api_get_podcast_api_v1_podcasts__podcast_uuid__get","parameters":[{"name":"podcast_uuid","in":"path","required":true,"schema":{"type":"string","title":"Podcast Uuid"}}],"responses":{"200":{"description":"Podcast details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PodcastRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to read this podcast"},"404":{"description":"Podcast not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["podcasts"],"summary":"Update a podcast","description":"Update a podcast's metadata. The caller must have write access to the podcast.","operationId":"api_update_podcast_api_v1_podcasts__podcast_uuid__put","parameters":[{"name":"podcast_uuid","in":"path","required":true,"schema":{"type":"string","title":"Podcast Uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PodcastUpdate"}}}},"responses":{"200":{"description":"Podcast updated successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PodcastRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to update this podcast"},"404":{"description":"Podcast not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["podcasts"],"summary":"Delete a podcast","description":"Delete a podcast and its associated episodes. This operation cannot be undone.","operationId":"api_delete_podcast_api_v1_podcasts__podcast_uuid__delete","parameters":[{"name":"podcast_uuid","in":"path","required":true,"schema":{"type":"string","title":"Podcast Uuid"}}],"responses":{"200":{"description":"Podcast deleted successfully.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to delete this podcast"},"404":{"description":"Podcast not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/podcasts/{podcast_uuid}/meta":{"get":{"tags":["podcasts"],"summary":"Get podcast metadata","description":"Fetch a podcast along with its episodes and related metadata.","operationId":"api_get_podcast_meta_api_v1_podcasts__podcast_uuid__meta_get","parameters":[{"name":"podcast_uuid","in":"path","required":true,"schema":{"type":"string","title":"Podcast Uuid"}}],"responses":{"200":{"description":"Podcast metadata with episodes.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to read this podcast"},"404":{"description":"Podcast not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/podcasts/org_slug/{org_slug}/page/{page}/limit/{limit}":{"get":{"tags":["podcasts"],"summary":"List podcasts for an organization","description":"Return a paginated list of podcasts belonging to an organization, with episode counts. Set `include_unpublished=true` to include unpublished podcasts (requires appropriate permissions).","operationId":"api_get_podcasts_orgslug_api_v1_podcasts_org_slug__org_slug__page__page__limit__limit__get","parameters":[{"name":"org_slug","in":"path","required":true,"schema":{"type":"string","title":"Org Slug"}},{"name":"page","in":"path","required":true,"schema":{"type":"integer","minimum":1,"title":"Page"}},{"name":"limit","in":"path","required":true,"schema":{"type":"integer","maximum":100,"minimum":1,"title":"Limit"}},{"name":"include_unpublished","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Unpublished"}}],"responses":{"200":{"description":"Paginated list of podcasts with episode counts.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PodcastReadWithEpisodeCount"},"title":"Response 200 Api Get Podcasts Orgslug Api V1 Podcasts Org Slug  Org Slug  Page  Page  Limit  Limit  Get"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to list podcasts in this organization"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/podcasts/org_slug/{org_slug}/count":{"get":{"tags":["podcasts"],"summary":"Count podcasts for an organization","description":"Return the total number of podcasts belonging to an organization.","operationId":"api_get_podcasts_count_orgslug_api_v1_podcasts_org_slug__org_slug__count_get","parameters":[{"name":"org_slug","in":"path","required":true,"schema":{"type":"string","title":"Org Slug"}}],"responses":{"200":{"description":"Object with the total podcast count.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to list podcasts in this organization"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/podcasts/{podcast_uuid}/thumbnail":{"put":{"tags":["podcasts"],"summary":"Update podcast thumbnail","description":"Upload or replace the thumbnail image for a podcast.","operationId":"api_update_podcast_thumbnail_api_v1_podcasts__podcast_uuid__thumbnail_put","parameters":[{"name":"podcast_uuid","in":"path","required":true,"schema":{"type":"string","title":"Podcast Uuid"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_api_update_podcast_thumbnail_api_v1_podcasts__podcast_uuid__thumbnail_put"}}}},"responses":{"200":{"description":"Thumbnail uploaded and podcast updated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PodcastRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to update this podcast"},"404":{"description":"Podcast not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/podcasts/{podcast_uuid}/rights":{"get":{"tags":["podcasts"],"summary":"Get podcast user rights","description":"Return the current user's rights (read, update, delete) on a given podcast.","operationId":"api_get_podcast_rights_api_v1_podcasts__podcast_uuid__rights_get","parameters":[{"name":"podcast_uuid","in":"path","required":true,"schema":{"type":"string","title":"Podcast Uuid"}}],"responses":{"200":{"description":"User rights for the podcast.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"404":{"description":"Podcast not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/podcasts/{podcast_uuid}/episodes":{"get":{"tags":["podcasts"],"summary":"List podcast episodes","description":"Return all episodes for a podcast. Set `include_unpublished=true` to include unpublished episodes (requires appropriate permissions).","operationId":"api_get_podcast_episodes_api_v1_podcasts__podcast_uuid__episodes_get","parameters":[{"name":"podcast_uuid","in":"path","required":true,"schema":{"type":"string","title":"Podcast Uuid"}},{"name":"include_unpublished","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Unpublished"}}],"responses":{"200":{"description":"List of episodes for the podcast.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PodcastEpisodeRead"},"title":"Response 200 Api Get Podcast Episodes Api V1 Podcasts  Podcast Uuid  Episodes Get"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to read this podcast"},"404":{"description":"Podcast not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["podcasts"],"summary":"Create a podcast episode","description":"Create a new episode for a podcast. Accepts multipart form data with optional audio file and thumbnail upload.","operationId":"api_create_episode_api_v1_podcasts__podcast_uuid__episodes_post","parameters":[{"name":"podcast_uuid","in":"path","required":true,"schema":{"type":"string","title":"Podcast Uuid"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_api_create_episode_api_v1_podcasts__podcast_uuid__episodes_post"}}}},"responses":{"200":{"description":"Episode created successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PodcastEpisodeRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to create episodes in this podcast"},"404":{"description":"Podcast not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/podcasts/{podcast_uuid}/episodes/reorder":{"put":{"tags":["podcasts"],"summary":"Reorder podcast episodes","description":"Reorder the episodes of a podcast by providing a list of episode ordering objects.","operationId":"api_reorder_episodes_api_v1_podcasts__podcast_uuid__episodes_reorder_put","parameters":[{"name":"podcast_uuid","in":"path","required":true,"schema":{"type":"string","title":"Podcast Uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true},"title":"Episode Orders"}}}},"responses":{"200":{"description":"Episodes reordered successfully.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to reorder episodes in this podcast"},"404":{"description":"Podcast not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/podcasts/episodes/{episode_uuid}":{"get":{"tags":["podcasts","episodes"],"summary":"Get a podcast episode","description":"Fetch a podcast episode by its UUID.","operationId":"api_get_episode_api_v1_podcasts_episodes__episode_uuid__get","parameters":[{"name":"episode_uuid","in":"path","required":true,"schema":{"type":"string","title":"Episode Uuid"}}],"responses":{"200":{"description":"Episode details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PodcastEpisodeRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to read this episode"},"404":{"description":"Episode not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["podcasts","episodes"],"summary":"Update a podcast episode","description":"Update an episode's metadata. The caller must have write access to the parent podcast.","operationId":"api_update_episode_api_v1_podcasts_episodes__episode_uuid__put","parameters":[{"name":"episode_uuid","in":"path","required":true,"schema":{"type":"string","title":"Episode Uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PodcastEpisodeUpdate"}}}},"responses":{"200":{"description":"Episode updated successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PodcastEpisodeRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to update this episode"},"404":{"description":"Episode not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["podcasts","episodes"],"summary":"Delete a podcast episode","description":"Delete a podcast episode and its associated files. This operation cannot be undone.","operationId":"api_delete_episode_api_v1_podcasts_episodes__episode_uuid__delete","parameters":[{"name":"episode_uuid","in":"path","required":true,"schema":{"type":"string","title":"Episode Uuid"}}],"responses":{"200":{"description":"Episode deleted successfully.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to delete this episode"},"404":{"description":"Episode not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/podcasts/episodes/{episode_uuid}/audio":{"put":{"tags":["podcasts","episodes"],"summary":"Upload episode audio","description":"Upload or replace the audio file for a podcast episode.","operationId":"api_upload_episode_audio_api_v1_podcasts_episodes__episode_uuid__audio_put","parameters":[{"name":"episode_uuid","in":"path","required":true,"schema":{"type":"string","title":"Episode Uuid"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_api_upload_episode_audio_api_v1_podcasts_episodes__episode_uuid__audio_put"}}}},"responses":{"200":{"description":"Audio uploaded and episode updated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PodcastEpisodeRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to update this episode"},"404":{"description":"Episode not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/podcasts/episodes/{episode_uuid}/thumbnail":{"put":{"tags":["podcasts","episodes"],"summary":"Upload episode thumbnail","description":"Upload or replace the thumbnail image for a podcast episode.","operationId":"api_upload_episode_thumbnail_api_v1_podcasts_episodes__episode_uuid__thumbnail_put","parameters":[{"name":"episode_uuid","in":"path","required":true,"schema":{"type":"string","title":"Episode Uuid"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_api_upload_episode_thumbnail_api_v1_podcasts_episodes__episode_uuid__thumbnail_put"}}}},"responses":{"200":{"description":"Thumbnail uploaded and episode updated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PodcastEpisodeRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission to update this episode"},"404":{"description":"Episode not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/certifications/":{"post":{"tags":["certifications"],"summary":"Create certification","description":"Create a new certification template for a course. Certifications are awarded when a learner completes the course.","operationId":"api_create_certification_api_v1_certifications__post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CertificationCreate"}}},"required":true},"responses":{"200":{"description":"Certification created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CertificationRead"}}}},"403":{"description":"Caller lacks permission to create certifications on this course"},"404":{"description":"Course not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/certifications/{certification_uuid}":{"get":{"tags":["certifications"],"summary":"Get certification","description":"Get a single certification template by its UUID.","operationId":"api_get_certification_api_v1_certifications__certification_uuid__get","parameters":[{"name":"certification_uuid","in":"path","required":true,"schema":{"type":"string","title":"Certification Uuid"}}],"responses":{"200":{"description":"Certification details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CertificationRead"}}}},"404":{"description":"Certification not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["certifications"],"summary":"Update certification","description":"Update a certification template by its UUID.","operationId":"api_update_certification_api_v1_certifications__certification_uuid__put","parameters":[{"name":"certification_uuid","in":"path","required":true,"schema":{"type":"string","title":"Certification Uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CertificationUpdate"}}}},"responses":{"200":{"description":"Certification updated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CertificationRead"}}}},"403":{"description":"Caller lacks permission to update this certification"},"404":{"description":"Certification not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["certifications"],"summary":"Delete certification","description":"Delete a certification template by its UUID. Existing awarded certificates are not removed.","operationId":"api_delete_certification_api_v1_certifications__certification_uuid__delete","parameters":[{"name":"certification_uuid","in":"path","required":true,"schema":{"type":"string","title":"Certification Uuid"}}],"responses":{"200":{"description":"Certification deleted.","content":{"application/json":{"schema":{}}}},"403":{"description":"Caller lacks permission to delete this certification"},"404":{"description":"Certification not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/certifications/course/{course_uuid}":{"get":{"tags":["certifications"],"summary":"List course certifications","description":"Get all certification templates attached to a course.","operationId":"api_get_certifications_by_course_api_v1_certifications_course__course_uuid__get","parameters":[{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","title":"Course Uuid"}}],"responses":{"200":{"description":"List of certifications for the course.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CertificationRead"},"title":"Response Api Get Certifications By Course Api V1 Certifications Course  Course Uuid  Get"}}}},"404":{"description":"Course not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/certifications/user/course/{course_uuid}":{"get":{"tags":["certifications"],"summary":"List my certificates for course","description":"Get all certificates awarded to the current user for a specific course, including certification details.","operationId":"api_get_user_certificates_for_course_api_v1_certifications_user_course__course_uuid__get","parameters":[{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","title":"Course Uuid"}}],"responses":{"200":{"description":"List of the user's certificates for the course.","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true},"title":"Response Api Get User Certificates For Course Api V1 Certifications User Course  Course Uuid  Get"}}}},"404":{"description":"Course not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/certifications/certificate/{user_certification_uuid}":{"get":{"tags":["certifications"],"summary":"Get awarded certificate","description":"Get an awarded certificate by its user_certification UUID, with linked certification and course details.","operationId":"api_get_certificate_by_user_certification_uuid_api_v1_certifications_certificate__user_certification_uuid__get","parameters":[{"name":"user_certification_uuid","in":"path","required":true,"schema":{"type":"string","title":"User Certification Uuid"}}],"responses":{"200":{"description":"Awarded certificate with linked certification and course.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Api Get Certificate By User Certification Uuid Api V1 Certifications Certificate  User Certification Uuid  Get"}}}},"404":{"description":"Certificate not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/certifications/user/all":{"get":{"tags":["certifications"],"summary":"List my certificates","description":"Get every certificate awarded to the current user across all courses, with complete linked information.","operationId":"api_get_all_user_certificates_api_v1_certifications_user_all_get","responses":{"200":{"description":"All certificates awarded to the current user.","content":{"application/json":{"schema":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Response Api Get All User Certificates Api V1 Certifications User All Get"}}}}}}},"/api/v1/boards/":{"post":{"tags":["boards"],"summary":"Create a board","description":"Create a new collaborative board within an organization. The authenticated user becomes the board owner.","operationId":"api_create_board_api_v1_boards__post","parameters":[{"name":"org_id","in":"query","required":true,"schema":{"type":"integer","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardCreate"}}}},"responses":{"200":{"description":"Board created successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"Insufficient permissions to create boards"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/boards/org/{org_id}":{"get":{"tags":["boards"],"summary":"List boards for an organization","description":"List all boards in the given organization that the current user is a member of or allowed to see.","operationId":"api_get_boards_by_org_api_v1_boards_org__org_id__get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"responses":{"200":{"description":"List of boards accessible to the current user.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/BoardRead"},"title":"Response 200 Api Get Boards By Org Api V1 Boards Org  Org Id  Get"}}}},"401":{"description":"Authentication required"},"403":{"description":"Access denied to this organization"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/boards/{board_uuid}":{"get":{"tags":["boards"],"summary":"Get a board by UUID","description":"Retrieve a single board by its UUID. The current user must be a member of the board.","operationId":"api_get_board_api_v1_boards__board_uuid__get","parameters":[{"name":"board_uuid","in":"path","required":true,"schema":{"type":"string","title":"Board Uuid"}}],"responses":{"200":{"description":"The requested board.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"Not a member of this board"},"404":{"description":"Board not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["boards"],"summary":"Update a board","description":"Update a board's fields. The current user must have update permission on the board.","operationId":"api_update_board_api_v1_boards__board_uuid__put","parameters":[{"name":"board_uuid","in":"path","required":true,"schema":{"type":"string","title":"Board Uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardUpdate"}}}},"responses":{"200":{"description":"Board updated successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"Insufficient permissions to update board"},"404":{"description":"Board not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["boards"],"summary":"Delete a board","description":"Delete a board by UUID. The current user must be the board owner or have delete permission.","operationId":"api_delete_board_api_v1_boards__board_uuid__delete","parameters":[{"name":"board_uuid","in":"path","required":true,"schema":{"type":"string","title":"Board Uuid"}}],"responses":{"200":{"description":"Board deleted successfully.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"Insufficient permissions to delete board"},"404":{"description":"Board not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/boards/{board_uuid}/duplicate":{"post":{"tags":["boards"],"summary":"Duplicate a board","description":"Create a copy of an existing board. The current user must have permission to create boards in the source org.","operationId":"api_duplicate_board_api_v1_boards__board_uuid__duplicate_post","parameters":[{"name":"board_uuid","in":"path","required":true,"schema":{"type":"string","title":"Board Uuid"}}],"responses":{"200":{"description":"Board duplicated successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"Insufficient permissions"},"404":{"description":"Board not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/boards/{board_uuid}/members":{"get":{"tags":["boards"],"summary":"List board members","description":"Return the list of members on a given board. The current user must be a member of the board.","operationId":"api_get_board_members_api_v1_boards__board_uuid__members_get","parameters":[{"name":"board_uuid","in":"path","required":true,"schema":{"type":"string","title":"Board Uuid"}}],"responses":{"200":{"description":"List of board members.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/BoardMemberRead"},"title":"Response 200 Api Get Board Members Api V1 Boards  Board Uuid  Members Get"}}}},"401":{"description":"Authentication required"},"403":{"description":"Not a member of this board"},"404":{"description":"Board not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["boards"],"summary":"Add a member to a board","description":"Add a single user as a member of the given board. The current user must have permission to manage board members.","operationId":"api_add_board_member_api_v1_boards__board_uuid__members_post","parameters":[{"name":"board_uuid","in":"path","required":true,"schema":{"type":"string","title":"Board Uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardMemberCreate"}}}},"responses":{"200":{"description":"Member added to board.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardMemberRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"Board member limit reached or insufficient permissions"},"404":{"description":"Board or user not found"},"409":{"description":"User is already a board member"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/boards/{board_uuid}/thumbnail":{"post":{"tags":["boards"],"summary":"Upload a board thumbnail","description":"Upload or replace the thumbnail image for a board. The current user must have update permission on the board.","operationId":"api_update_board_thumbnail_api_v1_boards__board_uuid__thumbnail_post","parameters":[{"name":"board_uuid","in":"path","required":true,"schema":{"type":"string","title":"Board Uuid"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_api_update_board_thumbnail_api_v1_boards__board_uuid__thumbnail_post"}}}},"responses":{"200":{"description":"Thumbnail uploaded and board updated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardRead"}}}},"400":{"description":"No thumbnail file provided"},"401":{"description":"Authentication required"},"403":{"description":"Insufficient permissions to update board"},"404":{"description":"Board not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/boards/{board_uuid}/members/batch":{"post":{"tags":["boards"],"summary":"Add multiple members to a board","description":"Add several users as members of a board in a single request. The current user must have permission to manage board members.","operationId":"api_add_board_members_batch_api_v1_boards__board_uuid__members_batch_post","parameters":[{"name":"board_uuid","in":"path","required":true,"schema":{"type":"string","title":"Board Uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardMemberBatchCreate"}}}},"responses":{"200":{"description":"Members added to board.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/BoardMemberRead"},"title":"Response 200 Api Add Board Members Batch Api V1 Boards  Board Uuid  Members Batch Post"}}}},"401":{"description":"Authentication required"},"403":{"description":"Board member limit reached or insufficient permissions"},"404":{"description":"Board not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/boards/{board_uuid}/members/{user_id}":{"delete":{"tags":["boards"],"summary":"Remove a member from a board","description":"Remove a user from a board's member list. The board owner cannot be removed via this endpoint.","operationId":"api_remove_board_member_api_v1_boards__board_uuid__members__user_id__delete","parameters":[{"name":"board_uuid","in":"path","required":true,"schema":{"type":"string","title":"Board Uuid"}},{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}}],"responses":{"200":{"description":"Member removed from board.","content":{"application/json":{"schema":{}}}},"400":{"description":"Cannot remove the board owner"},"401":{"description":"Authentication required"},"403":{"description":"Insufficient permissions"},"404":{"description":"Board member not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/boards/{board_uuid}/membership":{"get":{"tags":["boards"],"summary":"Check current user's board membership","description":"Return the current user's membership record on a board, if any. Used by clients to check role and access before loading the collab session.","operationId":"api_check_board_membership_api_v1_boards__board_uuid__membership_get","parameters":[{"name":"board_uuid","in":"path","required":true,"schema":{"type":"string","title":"Board Uuid"}}],"responses":{"200":{"description":"The current user's membership record on the board.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardMemberRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"Not a member of this board"},"404":{"description":"Board not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/boards/{board_uuid}/ydoc":{"get":{"tags":["boards-internal"],"summary":"Fetch the Yjs document state for a board","description":"Return the persisted Yjs document binary state for a board. Internal endpoint used by the Hocuspocus collab server; requires the shared internal key header.","operationId":"api_get_ydoc_state_api_v1_boards__board_uuid__ydoc_get","parameters":[{"name":"board_uuid","in":"path","required":true,"schema":{"type":"string","title":"Board Uuid"}},{"name":"x-internal-key","in":"header","required":true,"schema":{"type":"string","title":"X-Internal-Key"}}],"responses":{"200":{"description":"Binary Yjs document state (empty body if no state is stored).","content":{"application/json":{"schema":{}},"application/octet-stream":{}}},"403":{"description":"Invalid internal key"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["boards-internal"],"summary":"Persist the Yjs document state for a board","description":"Store the latest Yjs document binary state for a board. Internal endpoint used by the Hocuspocus collab server; requires the shared internal key header.","operationId":"api_store_ydoc_state_api_v1_boards__board_uuid__ydoc_put","parameters":[{"name":"board_uuid","in":"path","required":true,"schema":{"type":"string","title":"Board Uuid"}},{"name":"x-internal-key","in":"header","required":true,"schema":{"type":"string","title":"X-Internal-Key"}}],"responses":{"200":{"description":"Yjs document state persisted successfully.","content":{"application/json":{"schema":{}}}},"403":{"description":"Invalid internal key"},"404":{"description":"Board not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/trail/start":{"post":{"tags":["trail"],"summary":"Start a trail","description":"Create a new learning trail for the current user within an organization.","operationId":"api_start_trail_api_v1_trail_start_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrailCreate"}}},"required":true},"responses":{"200":{"description":"Trail created successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Trail"}}}},"401":{"description":"Authentication required"},"403":{"description":"User does not have permission to create a trail"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/trail/":{"get":{"tags":["trail"],"summary":"Get current user's trails","description":"Retrieve the learning trails associated with the currently authenticated user.","operationId":"api_get_user_trail_api_v1_trail__get","responses":{"200":{"description":"User trails retrieved.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrailRead"}}}},"401":{"description":"Authentication required"},"404":{"description":"Trail not found for user"}}}},"/api/v1/trail/org/{org_id}/trail":{"get":{"tags":["trail"],"summary":"Get user trail by organization","description":"Retrieve the current user's learning trail scoped to a specific organization.","operationId":"api_get_trail_by_org_id_api_v1_trail_org__org_id__trail_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"responses":{"200":{"description":"User trail for the organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrailRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"User does not have access to this organization's trail"},"404":{"description":"Trail or organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/trail/add_course/{course_uuid}":{"post":{"tags":["trail"],"summary":"Add course to trail","description":"Attach a course to the current user's learning trail.","operationId":"api_add_course_to_trail_api_v1_trail_add_course__course_uuid__post","parameters":[{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","title":"Course Uuid"}}],"responses":{"200":{"description":"Course added to trail.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrailRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"User does not have access to this course"},"404":{"description":"Course or trail not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/trail/remove_course/{course_uuid}":{"delete":{"tags":["trail"],"summary":"Remove course from trail","description":"Detach a course from the current user's learning trail.","operationId":"api_remove_course_to_trail_api_v1_trail_remove_course__course_uuid__delete","parameters":[{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","title":"Course Uuid"}}],"responses":{"200":{"description":"Course removed from trail.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrailRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"User does not have permission to modify this trail"},"404":{"description":"Course or trail not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/trail/add_activity/{activity_uuid}":{"post":{"tags":["trail"],"summary":"Add activity to trail","description":"Attach an activity to the current user's learning trail, marking it as started.","operationId":"api_add_activity_to_trail_api_v1_trail_add_activity__activity_uuid__post","parameters":[{"name":"activity_uuid","in":"path","required":true,"schema":{"type":"string","title":"Activity Uuid"}}],"responses":{"200":{"description":"Activity added to trail.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrailRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"User does not have access to this activity"},"404":{"description":"Activity or trail not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/trail/remove_activity/{activity_uuid}":{"delete":{"tags":["trail"],"summary":"Remove activity from trail","description":"Detach an activity from the current user's learning trail.","operationId":"api_remove_activity_from_trail_api_v1_trail_remove_activity__activity_uuid__delete","parameters":[{"name":"activity_uuid","in":"path","required":true,"schema":{"type":"string","title":"Activity Uuid"}}],"responses":{"200":{"description":"Activity removed from trail.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrailRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"User does not have permission to modify this trail"},"404":{"description":"Activity or trail not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ai/start/activity_chat_session":{"post":{"tags":["ai"],"summary":"Start activity AI chat session","description":"Start a new AI chat session anchored to a course activity. Returns the new session's state and initial message.","operationId":"api_ai_start_activity_chat_session_api_v1_ai_start_activity_chat_session_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StartActivityAIChatSession"}}},"required":true},"responses":{"200":{"description":"New AI chat session created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivityAIChatSessionResponse"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission or AI feature disabled for this organization"},"404":{"description":"Activity or organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ai/send/activity_chat_message":{"post":{"tags":["ai"],"summary":"Send activity AI chat message","description":"Send a message to an existing AI chat session anchored to a course activity and receive the updated session state.","operationId":"api_ai_send_activity_chat_message_api_v1_ai_send_activity_chat_message_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendActivityAIChatMessage"}}},"required":true},"responses":{"200":{"description":"Message sent and AI response recorded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivityAIChatSessionResponse"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission or AI feature disabled for this organization"},"404":{"description":"Session or activity not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ai/stream/start/activity_chat_session":{"post":{"tags":["ai"],"summary":"Start activity AI chat session (streaming)","description":"Start a new AI chat session for a course activity and stream the response as Server-Sent Events (SSE).","operationId":"api_ai_start_activity_chat_session_stream_api_v1_ai_stream_start_activity_chat_session_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StartActivityAIChatSession"}}},"required":true},"responses":{"200":{"description":"SSE stream of chat events (start, chunk, done, follow_ups, error).","content":{"application/json":{"schema":{}},"text/event-stream":{}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission or AI feature disabled for this organization"},"404":{"description":"Activity or organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ai/stream/send/activity_chat_message":{"post":{"tags":["ai"],"summary":"Send activity AI chat message (streaming)","description":"Send a message to an existing activity AI chat session and stream the response as Server-Sent Events (SSE).","operationId":"api_ai_send_activity_chat_message_stream_api_v1_ai_stream_send_activity_chat_message_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendActivityAIChatMessage"}}},"required":true},"responses":{"200":{"description":"SSE stream of chat events (start, chunk, done, follow_ups, error).","content":{"application/json":{"schema":{}},"text/event-stream":{}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission or AI feature disabled for this organization"},"404":{"description":"Session or activity not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ai/stream/editor/start":{"post":{"tags":["ai"],"summary":"Start editor AI chat session (streaming)","description":"Start a new AI editor chat session that is aware of the current editor content. Streams the response as Server-Sent Events (SSE) and can emit content modification blocks to be inserted into the editor.","operationId":"api_editor_ai_start_chat_session_stream_api_v1_ai_stream_editor_start_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StartEditorAIChatSession"}}},"required":true},"responses":{"200":{"description":"SSE stream of editor chat events (start, chat_chunk, content_start, content_chunk, content_end, done, follow_ups, error).","content":{"application/json":{"schema":{}},"text/event-stream":{}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission or AI feature disabled for this organization"},"404":{"description":"Activity or organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ai/stream/editor/message":{"post":{"tags":["ai"],"summary":"Send editor AI chat message (streaming)","description":"Send a message to an existing AI editor chat session and stream the response as Server-Sent Events (SSE). The endpoint is aware of the current editor content and can emit content modification blocks.","operationId":"api_editor_ai_send_message_stream_api_v1_ai_stream_editor_message_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendEditorAIChatMessage"}}},"required":true},"responses":{"200":{"description":"SSE stream of editor chat events (start, chat_chunk, content_start, content_chunk, content_end, done, follow_ups, error).","content":{"application/json":{"schema":{}},"text/event-stream":{}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks permission or AI feature disabled for this organization"},"404":{"description":"Session or activity not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ai/magicblocks/start":{"post":{"tags":["ai","magicblocks"],"summary":"Start MagicBlock session (streaming)","description":"Start a new MagicBlock AI generation session for an activity block. Streams generated HTML as Server-Sent Events (SSE). Consumes AI credits from the owning organization.","operationId":"start_magicblock_session_api_v1_ai_magicblocks_start_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StartMagicBlockSession"}}},"required":true},"responses":{"200":{"description":"SSE stream of generation events (chunk, done, error).","content":{"application/json":{"schema":{}},"text/event-stream":{}}},"401":{"description":"Authentication required"},"403":{"description":"AI feature disabled or insufficient credits"},"404":{"description":"Activity, course, or organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ai/magicblocks/iterate":{"post":{"tags":["ai","magicblocks"],"summary":"Iterate MagicBlock session (streaming)","description":"Continue an existing MagicBlock session with a new user message. Streams the updated HTML as Server-Sent Events (SSE). Consumes AI credits and is bounded by the session's max iterations.","operationId":"iterate_magicblock_session_api_v1_ai_magicblocks_iterate_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendMagicBlockMessage"}}},"required":true},"responses":{"200":{"description":"SSE stream of generation events (chunk, done, error).","content":{"application/json":{"schema":{}},"text/event-stream":{}}},"400":{"description":"Maximum iterations reached or activity/block UUID mismatch"},"401":{"description":"Authentication required"},"403":{"description":"AI feature disabled or insufficient credits"},"404":{"description":"Session, course, or organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ai/magicblocks/session/{session_uuid}":{"get":{"tags":["ai","magicblocks"],"summary":"Get MagicBlock session state","description":"Return the current state of a MagicBlock session, including iteration count, generated HTML, and full message history.","operationId":"get_session_state_api_v1_ai_magicblocks_session__session_uuid__get","parameters":[{"name":"session_uuid","in":"path","required":true,"schema":{"type":"string","title":"Session Uuid"}}],"responses":{"200":{"description":"MagicBlock session state.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MagicBlockSessionResponse"}}}},"401":{"description":"Authentication required"},"404":{"description":"Session not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ai/courseplanning/start":{"post":{"tags":["ai","courseplanning"],"summary":"Start course planning session (streaming)","description":"Start a new AI course planning session for an organization and stream the generated course plan as Server-Sent Events (SSE). Consumes AI credits based on the organization's plan tier.","operationId":"start_course_planning_session_api_v1_ai_courseplanning_start_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StartCoursePlanningSession"}}},"required":true},"responses":{"200":{"description":"SSE stream of course planning events (chunk, done, error).","content":{"application/json":{"schema":{}},"text/event-stream":{}}},"401":{"description":"Authentication required"},"403":{"description":"User is not a member of this organization or insufficient credits"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ai/courseplanning/iterate":{"post":{"tags":["ai","courseplanning"],"summary":"Iterate course planning session (streaming)","description":"Continue an existing course planning session with a new user message and stream the updated plan as Server-Sent Events (SSE). Bounded by the session's max planning iterations.","operationId":"iterate_course_planning_session_api_v1_ai_courseplanning_iterate_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendCoursePlanningMessage"}}},"required":true},"responses":{"200":{"description":"SSE stream of course planning events (chunk, done, error).","content":{"application/json":{"schema":{}},"text/event-stream":{}}},"400":{"description":"Maximum planning iterations reached"},"401":{"description":"Authentication required"},"403":{"description":"User is not a member of this organization or insufficient credits"},"404":{"description":"Session or organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ai/courseplanning/finalize":{"post":{"tags":["ai","courseplanning"],"summary":"Finalize course plan","description":"Finalize an AI-generated course plan and persist the course, chapters, and activities in the database. The calling user becomes the creator of the resulting course.","operationId":"finalize_course_plan_api_v1_ai_courseplanning_finalize_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FinalizeCoursePlanRequest"}}},"required":true},"responses":{"200":{"description":"Course, chapters, and activities created from the plan.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FinalizeCoursePlanResponse"}}}},"400":{"description":"Course already created from this session"},"401":{"description":"Authentication required"},"403":{"description":"User is not a member of this organization"},"404":{"description":"Session or organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ai/courseplanning/generate-activity":{"post":{"tags":["ai","courseplanning"],"summary":"Generate activity content (streaming)","description":"Generate AI content for a specific activity within a course planning session and stream it as Server-Sent Events (SSE). Bounded by the session's max activity iterations. Content must subsequently be persisted via the save-activity-content endpoint.","operationId":"generate_activity_content_api_v1_ai_courseplanning_generate_activity_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateActivityContentRequest"}}},"required":true},"responses":{"200":{"description":"SSE stream of activity content generation events (chunk, done, error).","content":{"application/json":{"schema":{}},"text/event-stream":{}}},"400":{"description":"Maximum activity iterations reached"},"401":{"description":"Authentication required"},"403":{"description":"Activity content generation disabled, user not a member of the organization, or insufficient credits"},"404":{"description":"Session, activity, or organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ai/courseplanning/save-activity-content":{"post":{"tags":["ai","courseplanning"],"summary":"Save AI-generated activity content","description":"Persist AI-generated ProseMirror content to an activity. The content is validated for correct document structure before being saved.","operationId":"save_activity_content_api_v1_ai_courseplanning_save_activity_content_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaveActivityContentRequest"}}},"required":true},"responses":{"200":{"description":"Activity content saved successfully.","content":{"application/json":{"schema":{}}}},"400":{"description":"Invalid content structure"},"401":{"description":"Authentication required"},"403":{"description":"User is not a member of this organization"},"404":{"description":"Activity or organization not found"},"500":{"description":"Failed to save content due to an internal error"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ai/courseplanning/session/{session_uuid}":{"get":{"tags":["ai","courseplanning"],"summary":"Get course planning session state","description":"Return the current state of a course planning session, including the current plan, iteration counts, message history, and any linked course.","operationId":"get_session_state_api_v1_ai_courseplanning_session__session_uuid__get","parameters":[{"name":"session_uuid","in":"path","required":true,"schema":{"type":"string","title":"Session Uuid"}}],"responses":{"200":{"description":"Course planning session state.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CoursePlanningSessionResponse"}}}},"401":{"description":"Authentication required"},"404":{"description":"Session not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ai/rag/chat":{"post":{"tags":["ai","rag"],"summary":"RAG chat (streaming)","description":"Streaming RAG chatbot grounded in course content. If `course_uuid` is provided, searches within that course only. Otherwise searches across all courses for the user's organization. Responses are delivered as Server-Sent Events (SSE).","operationId":"api_rag_chat_api_v1_ai_rag_chat_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RAGChatRequest"}}},"required":true},"responses":{"200":{"description":"SSE stream of chat events (start, chunk, sources, done, follow_ups, session_title, error).","content":{"application/json":{"schema":{}},"text/event-stream":{}}},"401":{"description":"Authentication required"},"403":{"description":"AI features disabled, copilot disabled, or user has no organization"},"404":{"description":"Course or organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ai/rag/index":{"post":{"tags":["ai","rag"],"summary":"Reindex course content for RAG","description":"Manually trigger re-indexing (embedding) of a course's content for the RAG chatbot. Requires admin/maintainer role on the course's organization.","operationId":"api_rag_index_api_v1_ai_rag_index_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RAGIndexRequest"}}},"required":true},"responses":{"200":{"description":"Course re-indexed successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RAGIndexResponse"}}}},"401":{"description":"Authentication required"},"403":{"description":"User lacks admin/maintainer role on the organization"},"404":{"description":"Course not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ai/rag/sessions":{"get":{"tags":["ai","rag"],"summary":"List RAG chat sessions","description":"List all RAG chat sessions owned by the current user, optionally filtered by organization via `org_slug`.","operationId":"api_rag_sessions_api_v1_ai_rag_sessions_get","parameters":[{"name":"org_slug","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Org Slug"}}],"responses":{"200":{"description":"Object containing the list of chat sessions for the current user.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ai/rag/sessions/{aichat_uuid}/messages":{"get":{"tags":["ai","rag"],"summary":"Get RAG chat session messages","description":"Load the full message history for a specific RAG chat session owned by the current user.","operationId":"api_rag_session_messages_api_v1_ai_rag_sessions__aichat_uuid__messages_get","parameters":[{"name":"aichat_uuid","in":"path","required":true,"schema":{"type":"string","title":"Aichat Uuid"}}],"responses":{"200":{"description":"Object containing the session's messages.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"404":{"description":"Session not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ai/rag/sessions/{aichat_uuid}":{"delete":{"tags":["ai","rag"],"summary":"Delete a RAG chat session","description":"Delete a RAG chat session and all its messages. The session must belong to the current user.","operationId":"api_rag_session_delete_api_v1_ai_rag_sessions__aichat_uuid__delete","parameters":[{"name":"aichat_uuid","in":"path","required":true,"schema":{"type":"string","title":"Aichat Uuid"}}],"responses":{"200":{"description":"Session deleted successfully.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"404":{"description":"Session not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["ai","rag"],"summary":"Update a RAG chat session","description":"Update a RAG chat session's title and/or favorite status. The session must belong to the current user.","operationId":"api_rag_session_update_api_v1_ai_rag_sessions__aichat_uuid__patch","parameters":[{"name":"aichat_uuid","in":"path","required":true,"schema":{"type":"string","title":"Aichat Uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RAGSessionUpdateRequest"}}}},"responses":{"200":{"description":"Session updated successfully.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"404":{"description":"Session not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ai/images/generate":{"post":{"tags":["ai","images"],"summary":"Generate an image with AI (nano banana)","description":"Generate or refine an image from a text prompt. Consumes AI credits.","operationId":"api_generate_image_api_v1_ai_images_generate_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateImageRequest"}}},"required":true},"responses":{"200":{"description":"Image generated and stored.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateImageResponse"}}}},"401":{"description":"Authentication required"},"403":{"description":"Not an org member, AI disabled, or insufficient credits"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ai/images/{org_id}/{file_id}/bytes":{"get":{"tags":["ai","images"],"summary":"Download a generated AI image (same-origin, authenticated)","description":"Serve a generated image's raw bytes from the SAME origin as the API.\n\nUpload surfaces fetch this (instead of the public, possibly cross-origin\nmedia URL) so building a File to re-upload never trips CORS.","operationId":"api_get_image_bytes_api_v1_ai_images__org_id___file_id__bytes_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"file_id","in":"path","required":true,"schema":{"type":"string","title":"File Id"}}],"responses":{"200":{"description":"Image bytes returned","content":{"application/json":{"schema":{}},"image/png":{}}},"400":{"description":"Invalid file id"},"401":{"description":"Authentication required"},"403":{"description":"Not an org member"},"404":{"description":"Image not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ai/images/history":{"get":{"tags":["ai","images"],"summary":"List AI image generation history","operationId":"api_list_image_history_api_v1_ai_images_history_get","parameters":[{"name":"org_id","in":"query","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":30,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AIImageHistoryItem"},"title":"Response Api List Image History Api V1 Ai Images History Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ai/images/history/{ai_generation_uuid}":{"delete":{"tags":["ai","images"],"summary":"Delete an AI image generation from history","operationId":"api_delete_image_history_api_v1_ai_images_history__ai_generation_uuid__delete","parameters":[{"name":"ai_generation_uuid","in":"path","required":true,"schema":{"type":"string","title":"Ai Generation Uuid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Api Delete Image History Api V1 Ai Images History  Ai Generation Uuid  Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ai/audio/generate":{"post":{"tags":["ai","audio"],"summary":"Generate an audio block with AI (Gemini TTS)","description":"Generate speech (single voice) or a podcast (up to two speakers) from text and attach it to an activity as an audio block. Consumes AI credits.","operationId":"api_generate_audio_api_v1_ai_audio_generate_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateAudioRequest"}}},"required":true},"responses":{"200":{"description":"Audio generated, stored and returned.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlockRead"}}}},"400":{"description":"Invalid request"},"401":{"description":"Authentication required"},"403":{"description":"Not an org member, AI disabled, or insufficient credits"},"404":{"description":"Activity not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ai/audio/script":{"post":{"tags":["ai","audio"],"summary":"Generate a spoken script with AI (podcast dialogue or monologue)","description":"Turn a topic, question, or source material into a spoken script — a two-speaker discussion ('podcast') or a detailed single-speaker explanation ('speak') — of an approximate length. Consumes AI credits.","operationId":"api_generate_script_api_v1_ai_audio_script_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateScriptRequest"}}},"required":true},"responses":{"200":{"description":"Script generated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateScriptResponse"}}}},"400":{"description":"Invalid request"},"401":{"description":"Authentication required"},"403":{"description":"Not an org member, AI disabled, or insufficient credits"},"404":{"description":"Activity not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ai/quiz/generate":{"post":{"tags":["ai","quiz"],"summary":"Generate a quiz for the editor","operationId":"api_generate_quiz_api_v1_ai_quiz_generate_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateQuizRequest"}}},"required":true},"responses":{"200":{"description":"Quiz generated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateQuizResponse"}}}},"403":{"description":"Not an org member, AI disabled, or insufficient credits"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ai/quiz/history":{"get":{"tags":["ai","quiz"],"summary":"List AI quiz generation history","operationId":"api_list_quiz_history_api_v1_ai_quiz_history_get","parameters":[{"name":"org_id","in":"query","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":30,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AIQuizHistoryItem"},"title":"Response Api List Quiz History Api V1 Ai Quiz History Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ai/quiz/history/{ai_generation_uuid}":{"delete":{"tags":["ai","quiz"],"summary":"Delete an AI quiz generation from history","operationId":"api_delete_quiz_history_api_v1_ai_quiz_history__ai_generation_uuid__delete","parameters":[{"name":"ai_generation_uuid","in":"path","required":true,"schema":{"type":"string","title":"Ai Generation Uuid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Api Delete Quiz History Api V1 Ai Quiz History  Ai Generation Uuid  Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ai/assignments/generate":{"post":{"tags":["ai","assignment-gen"],"summary":"Generate an assignment plan from course content","operationId":"api_generate_assignment_api_v1_ai_assignments_generate_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateAssignmentRequest"}}},"required":true},"responses":{"200":{"description":"Assignment plan generated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateAssignmentResponse"}}}},"403":{"description":"Not an org member, AI disabled, or insufficient credits"},"404":{"description":"Organization or course not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ai/assignments/history":{"get":{"tags":["ai","assignment-gen"],"summary":"List AI assignment generation history","operationId":"api_list_assignment_history_api_v1_ai_assignments_history_get","parameters":[{"name":"org_id","in":"query","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":30,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AIAssignmentHistoryItem"},"title":"Response Api List Assignment History Api V1 Ai Assignments History Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ai/assignments/history/{ai_generation_uuid}":{"delete":{"tags":["ai","assignment-gen"],"summary":"Delete an AI assignment generation from history","operationId":"api_delete_assignment_history_api_v1_ai_assignments_history__ai_generation_uuid__delete","parameters":[{"name":"ai_generation_uuid","in":"path","required":true,"schema":{"type":"string","title":"Ai Generation Uuid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Api Delete Assignment History Api V1 Ai Assignments History  Ai Generation Uuid  Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ai/scenario/generate":{"post":{"tags":["ai","scenario"],"summary":"Generate an interactive scenario for the editor","operationId":"api_generate_scenario_api_v1_ai_scenario_generate_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateScenarioRequest"}}},"required":true},"responses":{"200":{"description":"Scenario generated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateScenarioResponse"}}}},"403":{"description":"Not an org member, AI disabled, or insufficient credits"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ai/scenario/history":{"get":{"tags":["ai","scenario"],"summary":"List AI scenario generation history","operationId":"api_list_scenario_history_api_v1_ai_scenario_history_get","parameters":[{"name":"org_id","in":"query","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":30,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AIScenarioHistoryItem"},"title":"Response Api List Scenario History Api V1 Ai Scenario History Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ai/scenario/history/{ai_generation_uuid}":{"delete":{"tags":["ai","scenario"],"summary":"Delete an AI scenario generation from history","operationId":"api_delete_scenario_history_api_v1_ai_scenario_history__ai_generation_uuid__delete","parameters":[{"name":"ai_generation_uuid","in":"path","required":true,"schema":{"type":"string","title":"Ai Generation Uuid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Api Delete Scenario History Api V1 Ai Scenario History  Ai Generation Uuid  Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/boards/playground/start":{"post":{"tags":["boards","boards-playground"],"summary":"Start a boards playground AI session","description":"Start a new Boards Playground AI generation session with a server-sent events stream. Deducts AI credits and requires a valid board and organization.","operationId":"start_boards_playground_session_api_v1_boards_playground_start_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StartBoardsPlaygroundSession"}}},"required":true},"responses":{"200":{"description":"Server-sent events stream of generated playground content.","content":{"application/json":{"schema":{}},"text/event-stream":{}}},"401":{"description":"Authentication required"},"404":{"description":"Board or organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/boards/playground/iterate":{"post":{"tags":["boards","boards-playground"],"summary":"Iterate on a boards playground AI session","description":"Continue an existing Boards Playground session with a new message, streaming the updated output. Deducts AI credits and enforces the session's iteration limit.","operationId":"iterate_boards_playground_session_api_v1_boards_playground_iterate_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendBoardsPlaygroundMessage"}}},"required":true},"responses":{"200":{"description":"Server-sent events stream of generated playground content.","content":{"application/json":{"schema":{}},"text/event-stream":{}}},"400":{"description":"Maximum iterations reached, or board/block UUID mismatch"},"401":{"description":"Authentication required"},"404":{"description":"Session, board, or organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/boards/playground/session/{session_uuid}":{"get":{"tags":["boards","boards-playground"],"summary":"Get boards playground session state","description":"Retrieve the current state of a Boards Playground generation session, including iteration count, current HTML, and message history.","operationId":"get_session_state_api_v1_boards_playground_session__session_uuid__get","parameters":[{"name":"session_uuid","in":"path","required":true,"schema":{"type":"string","title":"Session Uuid"}}],"responses":{"200":{"description":"Current state of the boards playground session.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardsPlaygroundSessionResponse"}}}},"401":{"description":"Authentication required"},"404":{"description":"Session not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/playgrounds/":{"post":{"tags":["playgrounds"],"summary":"Create a playground","description":"Create a new playground within an organization. The authenticated user must have permission to create playgrounds in the target org.","operationId":"api_create_playground_api_v1_playgrounds__post","parameters":[{"name":"org_id","in":"query","required":true,"schema":{"type":"integer","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaygroundCreate"}}}},"responses":{"200":{"description":"Playground created successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaygroundRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"Insufficient permissions to create playgrounds"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/playgrounds/org/{org_id}":{"get":{"tags":["playgrounds"],"summary":"List playgrounds for an organization","description":"List all playgrounds in the given organization that the current user is allowed to see.","operationId":"api_list_org_playgrounds_api_v1_playgrounds_org__org_id__get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"responses":{"200":{"description":"List of playgrounds accessible to the current user.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PlaygroundRead"},"title":"Response 200 Api List Org Playgrounds Api V1 Playgrounds Org  Org Id  Get"}}}},"401":{"description":"Authentication required"},"403":{"description":"Access denied to this organization"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/playgrounds/{playground_uuid}":{"get":{"tags":["playgrounds"],"summary":"Get a playground by UUID","description":"Retrieve a single playground by its UUID. The current user must have access to the playground.","operationId":"api_get_playground_api_v1_playgrounds__playground_uuid__get","parameters":[{"name":"playground_uuid","in":"path","required":true,"schema":{"type":"string","title":"Playground Uuid"}}],"responses":{"200":{"description":"The requested playground.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaygroundRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"Access denied to this playground"},"404":{"description":"Playground not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["playgrounds"],"summary":"Update a playground","description":"Update a playground's fields. The current user must have update permission on the playground.","operationId":"api_update_playground_api_v1_playgrounds__playground_uuid__put","parameters":[{"name":"playground_uuid","in":"path","required":true,"schema":{"type":"string","title":"Playground Uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaygroundUpdate"}}}},"responses":{"200":{"description":"Playground updated successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaygroundRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"Insufficient permissions to update playground"},"404":{"description":"Playground not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["playgrounds"],"summary":"Delete a playground","description":"Delete a playground by UUID. The current user must have delete permission on the playground.","operationId":"api_delete_playground_api_v1_playgrounds__playground_uuid__delete","parameters":[{"name":"playground_uuid","in":"path","required":true,"schema":{"type":"string","title":"Playground Uuid"}}],"responses":{"200":{"description":"Playground deleted successfully.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Api Delete Playground Api V1 Playgrounds  Playground Uuid  Delete"}}}},"401":{"description":"Authentication required"},"403":{"description":"Insufficient permissions to delete playground"},"404":{"description":"Playground not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/playgrounds/{playground_uuid}/duplicate":{"post":{"tags":["playgrounds"],"summary":"Duplicate a playground","description":"Create a copy of an existing playground. The current user must have permission to create playgrounds in the source org.","operationId":"api_duplicate_playground_api_v1_playgrounds__playground_uuid__duplicate_post","parameters":[{"name":"playground_uuid","in":"path","required":true,"schema":{"type":"string","title":"Playground Uuid"}}],"responses":{"200":{"description":"Playground duplicated successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaygroundRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"Insufficient permissions to create playgrounds"},"404":{"description":"Playground not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/playgrounds/{playground_uuid}/thumbnail":{"post":{"tags":["playgrounds"],"summary":"Upload a playground thumbnail","description":"Upload or replace the thumbnail image for a playground. The current user must have update permission on the playground.","operationId":"api_update_playground_thumbnail_api_v1_playgrounds__playground_uuid__thumbnail_post","parameters":[{"name":"playground_uuid","in":"path","required":true,"schema":{"type":"string","title":"Playground Uuid"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_api_update_playground_thumbnail_api_v1_playgrounds__playground_uuid__thumbnail_post"}}}},"responses":{"200":{"description":"Thumbnail uploaded and playground updated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaygroundRead"}}}},"400":{"description":"No thumbnail file provided"},"401":{"description":"Authentication required"},"403":{"description":"Insufficient permissions to update playground"},"404":{"description":"Playground or organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/playgrounds/{playground_uuid}/usergroups/{usergroup_uuid}":{"post":{"tags":["playgrounds"],"summary":"Grant a usergroup access to a playground","description":"Associate a usergroup with a playground so its members can access it. The current user must have update permission on the playground.","operationId":"api_add_usergroup_to_playground_api_v1_playgrounds__playground_uuid__usergroups__usergroup_uuid__post","parameters":[{"name":"playground_uuid","in":"path","required":true,"schema":{"type":"string","title":"Playground Uuid"}},{"name":"usergroup_uuid","in":"path","required":true,"schema":{"type":"string","title":"Usergroup Uuid"}}],"responses":{"200":{"description":"Usergroup granted access to playground.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Api Add Usergroup To Playground Api V1 Playgrounds  Playground Uuid  Usergroups  Usergroup Uuid  Post"}}}},"401":{"description":"Authentication required"},"403":{"description":"Insufficient permissions"},"404":{"description":"Playground or user group not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["playgrounds"],"summary":"Revoke a usergroup from a playground","description":"Remove a usergroup's access to a playground. The current user must have update permission on the playground.","operationId":"api_remove_usergroup_from_playground_api_v1_playgrounds__playground_uuid__usergroups__usergroup_uuid__delete","parameters":[{"name":"playground_uuid","in":"path","required":true,"schema":{"type":"string","title":"Playground Uuid"}},{"name":"usergroup_uuid","in":"path","required":true,"schema":{"type":"string","title":"Usergroup Uuid"}}],"responses":{"200":{"description":"Usergroup removed from playground.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Api Remove Usergroup From Playground Api V1 Playgrounds  Playground Uuid  Usergroups  Usergroup Uuid  Delete"}}}},"401":{"description":"Authentication required"},"403":{"description":"Insufficient permissions"},"404":{"description":"Playground, user group, or association not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/playgrounds/{playground_uuid}/usergroups":{"get":{"tags":["playgrounds"],"summary":"List usergroups attached to a playground","description":"Return the list of usergroups that have access to a given playground.","operationId":"api_get_playground_usergroups_api_v1_playgrounds__playground_uuid__usergroups_get","parameters":[{"name":"playground_uuid","in":"path","required":true,"schema":{"type":"string","title":"Playground Uuid"}}],"responses":{"200":{"description":"List of usergroups associated with the playground.","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true},"title":"Response Api Get Playground Usergroups Api V1 Playgrounds  Playground Uuid  Usergroups Get"}}}},"401":{"description":"Authentication required"},"403":{"description":"Access denied to this playground"},"404":{"description":"Playground not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/playgrounds/{playground_uuid}/reactions":{"get":{"tags":["playgrounds"],"summary":"List reactions on a playground","description":"Return reaction counts and the current user's reactions for a playground. Supports anonymous viewers.","operationId":"api_get_playground_reactions_api_v1_playgrounds__playground_uuid__reactions_get","parameters":[{"name":"playground_uuid","in":"path","required":true,"schema":{"type":"string","title":"Playground Uuid"}}],"responses":{"200":{"description":"Aggregated reaction summary for the playground.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PlaygroundReactionSummary"},"title":"Response 200 Api Get Playground Reactions Api V1 Playgrounds  Playground Uuid  Reactions Get"}}}},"404":{"description":"Playground not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["playgrounds"],"summary":"Toggle a reaction on a playground","description":"Toggle the current user's reaction (emoji) on a playground. Adds the reaction if missing or removes it if already present.","operationId":"api_toggle_playground_reaction_api_v1_playgrounds__playground_uuid__reactions_post","parameters":[{"name":"playground_uuid","in":"path","required":true,"schema":{"type":"string","title":"Playground Uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Reaction"}}}},"responses":{"200":{"description":"Reaction toggled successfully.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Api Toggle Playground Reaction Api V1 Playgrounds  Playground Uuid  Reactions Post"}}}},"401":{"description":"Authentication required"},"404":{"description":"Playground not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/playgrounds/generate/start":{"post":{"tags":["playgrounds","playgrounds-generator"],"summary":"Start a playground generation session","description":"Start a new Playground AI generation session with a server-sent events stream. Deducts AI credits and requires update permission on the target playground.","operationId":"start_playground_session_api_v1_playgrounds_generate_start_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StartPlaygroundSession"}}},"required":true},"responses":{"200":{"description":"Server-sent events stream of generated playground content.","content":{"application/json":{"schema":{}},"text/event-stream":{}}},"401":{"description":"Authentication required"},"403":{"description":"Insufficient permissions to generate content"},"404":{"description":"Playground or organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/playgrounds/generate/iterate":{"post":{"tags":["playgrounds","playgrounds-generator"],"summary":"Iterate on a playground generation session","description":"Continue an existing Playground session with a new message, streaming the updated output. Deducts AI credits and enforces the session's iteration limit.","operationId":"iterate_playground_session_api_v1_playgrounds_generate_iterate_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendPlaygroundMessage"}}},"required":true},"responses":{"200":{"description":"Server-sent events stream of generated playground content.","content":{"application/json":{"schema":{}},"text/event-stream":{}}},"400":{"description":"Maximum iterations reached or playground UUID mismatch"},"401":{"description":"Authentication required"},"403":{"description":"Insufficient permissions"},"404":{"description":"Session, playground, or organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/playgrounds/generate/session/{session_uuid}":{"get":{"tags":["playgrounds","playgrounds-generator"],"summary":"Get playground generation session state","description":"Retrieve the current state of a Playground generation session, including iteration count, current HTML, and message history.","operationId":"get_session_state_api_v1_playgrounds_generate_session__session_uuid__get","parameters":[{"name":"session_uuid","in":"path","required":true,"schema":{"type":"string","title":"Session Uuid"}}],"responses":{"200":{"description":"Current state of the playground generation session.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaygroundSessionResponse"}}}},"401":{"description":"Authentication required"},"404":{"description":"Session not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/analytics/status":{"get":{"tags":["analytics"],"summary":"Check analytics configuration","description":"Returns whether the analytics backend (Tinybird) is configured on the server.","operationId":"analytics_status_api_v1_analytics_status_get","responses":{"200":{"description":"Analytics configuration status","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"}}}},"/api/v1/analytics/events":{"post":{"tags":["analytics"],"summary":"Ingest a frontend analytics event","description":"Proxies a whitelisted analytics event from the frontend to the analytics backend. The authenticated user must belong to the target organization, and the event name must be in the allowed list.","operationId":"ingest_frontend_event_api_v1_analytics_events_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FrontendEvent"}}},"required":true},"responses":{"200":{"description":"Event ingested successfully","content":{"application/json":{"schema":{}}}},"400":{"description":"Invalid event name"},"401":{"description":"Authentication required"},"403":{"description":"User is not a member of the target organization"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/analytics/dashboard/detail/{query_name}":{"get":{"tags":["analytics"],"summary":"Run a detail dashboard query","description":"Executes a predefined analytics detail query against Tinybird and enriches the result rows with course, activity, and user metadata from PostgreSQL. Requires org admin privileges.","operationId":"query_dashboard_detail_api_v1_analytics_dashboard_detail__query_name__get","parameters":[{"name":"query_name","in":"path","required":true,"schema":{"type":"string","title":"Query Name"}},{"name":"org_id","in":"query","required":true,"schema":{"type":"integer","title":"Org Id"}}],"responses":{"200":{"description":"Detail query results with enriched metadata","content":{"application/json":{"schema":{}}}},"400":{"description":"Invalid query parameter"},"401":{"description":"Authentication required"},"403":{"description":"User is not a member or admin of the organization"},"404":{"description":"Unknown detail query name"},"502":{"description":"Upstream analytics query failed"},"503":{"description":"Analytics backend is not configured"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/analytics/dashboard/{query_name}":{"get":{"tags":["analytics"],"summary":"Run a dashboard analytics query","description":"Executes a predefined analytics query via Tinybird and returns the aggregated results. Advanced queries require an Enterprise plan. Requires org admin privileges.","operationId":"query_dashboard_api_v1_analytics_dashboard__query_name__get","parameters":[{"name":"query_name","in":"path","required":true,"schema":{"type":"string","title":"Query Name"}},{"name":"org_id","in":"query","required":true,"schema":{"type":"integer","title":"Org Id"}}],"responses":{"200":{"description":"Query results with enriched metadata","content":{"application/json":{"schema":{}}}},"400":{"description":"Invalid query parameter"},"401":{"description":"Authentication required"},"403":{"description":"User is not a member/admin, or plan does not permit advanced queries"},"404":{"description":"Unknown query name"},"502":{"description":"Upstream analytics query failed"},"503":{"description":"Analytics backend is not configured"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/analytics/dashboard/db/{query_name}":{"get":{"tags":["analytics"],"summary":"Run a PostgreSQL-backed dashboard query","description":"Executes a predefined PostgreSQL analytics query (e.g. grade distribution histogram). Requires org admin privileges and a Pro plan or higher.","operationId":"query_dashboard_db_api_v1_analytics_dashboard_db__query_name__get","parameters":[{"name":"query_name","in":"path","required":true,"schema":{"type":"string","title":"Query Name"}},{"name":"org_id","in":"query","required":true,"schema":{"type":"integer","title":"Org Id"}}],"responses":{"200":{"description":"Query results from PostgreSQL","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"User is not admin or the organization lacks a Pro plan"},"404":{"description":"Unknown query name"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/analytics/dashboard/course/detail/{query_name}":{"get":{"tags":["analytics"],"summary":"Run a course-level detail analytics query","description":"Executes a predefined course-level detail query via Tinybird with fallback to PostgreSQL TrailRun data, and enriches results with course, activity, and user metadata. Requires org admin privileges and a Pro plan or higher.","operationId":"query_course_dashboard_detail_api_v1_analytics_dashboard_course_detail__query_name__get","parameters":[{"name":"query_name","in":"path","required":true,"schema":{"type":"string","title":"Query Name"}},{"name":"org_id","in":"query","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"course_uuid","in":"query","required":true,"schema":{"type":"string","title":"Course Uuid"}}],"responses":{"200":{"description":"Course detail query results with enriched metadata","content":{"application/json":{"schema":{}}}},"400":{"description":"Invalid query parameter or course_uuid"},"401":{"description":"Authentication required"},"403":{"description":"User is not admin or the organization lacks a Pro plan"},"404":{"description":"Unknown course detail query name"},"502":{"description":"Upstream analytics query failed"},"503":{"description":"Analytics backend is not configured"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/analytics/dashboard/course/{query_name}":{"get":{"tags":["analytics"],"summary":"Run a course-level analytics query","description":"Executes a predefined course-level analytics query via Tinybird and returns enriched aggregated results. Requires org admin privileges and a Pro plan or higher.","operationId":"query_course_dashboard_api_v1_analytics_dashboard_course__query_name__get","parameters":[{"name":"query_name","in":"path","required":true,"schema":{"type":"string","title":"Query Name"}},{"name":"org_id","in":"query","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"course_uuid","in":"query","required":true,"schema":{"type":"string","title":"Course Uuid"}}],"responses":{"200":{"description":"Course query results with enriched metadata","content":{"application/json":{"schema":{}}}},"400":{"description":"Invalid query parameter or course_uuid"},"401":{"description":"Authentication required"},"403":{"description":"User is not admin or the organization lacks a Pro plan"},"404":{"description":"Unknown course query name"},"502":{"description":"Upstream analytics query failed"},"503":{"description":"Analytics backend is not configured"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/analytics/export":{"get":{"tags":["analytics"],"summary":"Export analytics data","description":"Exports results for a comma-separated list of analytics queries in either JSON or CSV format. Requires org admin privileges.","operationId":"export_analytics_api_v1_analytics_export_get","parameters":[{"name":"org_id","in":"query","required":true,"schema":{"type":"integer","title":"Org Id"}}],"responses":{"200":{"description":"Analytics data exported as JSON or streaming CSV","content":{"application/json":{"schema":{}}}},"400":{"description":"Invalid format, queries, or parameters"},"401":{"description":"Authentication required"},"403":{"description":"User is not admin of the organization"},"502":{"description":"Upstream analytics query failed"},"503":{"description":"Analytics backend is not configured"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/analytics/plan-info":{"get":{"tags":["analytics"],"summary":"Get analytics plan tier for an organization","description":"Returns the analytics tier (core or advanced) available to the organization based on its current plan.","operationId":"get_plan_info_api_v1_analytics_plan_info_get","parameters":[{"name":"org_id","in":"query","required":true,"schema":{"type":"integer","title":"Org Id"}}],"responses":{"200":{"description":"Analytics plan tier information","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"User is not a member of the target organization"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/code/execute":{"post":{"tags":["code-execution"],"summary":"Execute a code snippet","description":"Submit a single code snippet to the Judge0 sandbox and return its result. Supports SQL execution via a bundled SQLite database; API tokens are not permitted for this endpoint.","operationId":"execute_code_api_v1_code_execute_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExecuteRequest"}}},"required":true},"responses":{"200":{"description":"Judge0 submission result for the executed code.","content":{"application/json":{"schema":{}}}},"400":{"description":"Invalid sqlite_db_path or file path"},"401":{"description":"Authentication required"},"403":{"description":"API tokens not permitted, or no access to the referenced course"},"404":{"description":"SQLite database file not found"},"503":{"description":"Code execution is not configured on this instance"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/code/execute-batch":{"post":{"tags":["code-execution"],"summary":"Execute code against a batch of test cases","description":"Run a code snippet against multiple test cases in parallel and return per-test pass/fail results. Supports SQL execution via a bundled SQLite database; API tokens are not permitted.","operationId":"execute_batch_api_v1_code_execute_batch_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExecuteBatchRequest"}}},"required":true},"responses":{"200":{"description":"Per-test execution results for the submitted code.","content":{"application/json":{"schema":{}}}},"400":{"description":"Invalid sqlite_db_path or file path"},"401":{"description":"Authentication required"},"403":{"description":"API tokens not permitted, or no access to the referenced course"},"404":{"description":"SQLite database file not found"},"503":{"description":"Code execution is not configured on this instance"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/code/upload-sqlite":{"post":{"tags":["code-execution"],"summary":"Upload a SQLite database for a code playground block","description":"Upload a SQLite database file for a code playground block. Requires an authenticated user with update permission on the target course; API tokens are not permitted.","operationId":"upload_sqlite_db_api_v1_code_upload_sqlite_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_sqlite_db_api_v1_code_upload_sqlite_post"}}},"required":true},"responses":{"200":{"description":"Uploaded file path and original filename.","content":{"application/json":{"schema":{}}}},"400":{"description":"Invalid course_uuid or file path"},"401":{"description":"Authentication required"},"403":{"description":"API tokens not permitted, or no update access to the course"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/code/submissions/history":{"get":{"tags":["code_submissions"],"summary":"List a user's code submission history","description":"Return the authenticated user's previous code submissions for a given activity block, paginated by page and limit.","operationId":"get_submission_history_api_v1_code_submissions_history_get","parameters":[{"name":"activity_uuid","in":"query","required":true,"schema":{"type":"string","title":"Activity Uuid"}},{"name":"block_id","in":"query","required":true,"schema":{"type":"string","title":"Block Id"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}}],"responses":{"200":{"description":"Paginated list of code submissions for the current user on the given block.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Submission History Api V1 Code Submissions History Get"}}}},"401":{"description":"Authentication required"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/code/submissions/save":{"post":{"tags":["code_submissions"],"summary":"Save a code submission","description":"Persist a code submission (source, results, pass/fail counts) for the authenticated user on an activity block.","operationId":"save_submission_api_v1_code_submissions_save_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaveSubmissionRequest"}}},"required":true},"responses":{"200":{"description":"Code submission saved successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CodeSubmissionRead"}}}},"401":{"description":"Authentication required"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/instance/info":{"get":{"tags":["instance"],"summary":"Get instance info","description":"Public endpoint returning instance configuration (deployment mode, default org slug, frontend domain, and multi-org flag). Result is cached for performance.","operationId":"get_instance_info_api_v1_instance_info_get","responses":{"200":{"description":"Instance configuration for the current deployment.","content":{"application/json":{"schema":{}}}}}}},"/api/v1/monitoring/feedback":{"post":{"tags":["monitoring"],"summary":"Submit user feedback","description":"Relay user feedback to Sentry from the server so requests aren't dropped by client-side ad/tracker blockers.","operationId":"submit_feedback_api_v1_monitoring_feedback_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_submit_feedback_api_v1_monitoring_feedback_post"}}}},"responses":{"204":{"description":"Feedback accepted and forwarded to Sentry."},"400":{"description":"Empty or invalid feedback payload."},"503":{"description":"Sentry is not configured on this instance."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/plans":{"get":{"tags":["plans"],"summary":"Get plan feature limits","description":"Public endpoint that returns the feature limits (courses, members, admin seats, AI credits) for every available plan. Used by the frontend to render pricing pages and plan comparison tables.","operationId":"api_get_plan_limits_api_v1_plans_get","responses":{"200":{"description":"Mapping of plan id to feature limits","content":{"application/json":{"schema":{}}}}}}},"/api/v1/cloud_internal/update_org_config":{"put":{"tags":["cloud_internal"],"summary":"Update an organization config (no-auth internal)","description":"Internal endpoint used by the control plane to overwrite an organization's configuration. This bypasses user auth and is protected by the internal cloud key header at the dependency level.","operationId":"update_org_Config_api_v1_cloud_internal_update_org_config_put","parameters":[{"name":"org_id","in":"query","required":true,"schema":{"type":"integer","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgConfigUpdateBody"}}}},"responses":{"200":{"description":"Updated organization config payload returned by the service.","content":{"application/json":{"schema":{}}}},"403":{"description":"Missing or invalid CloudInternalKey header"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/cloud_internal/plans":{"get":{"tags":["cloud_internal"],"summary":"List available plans and hierarchy","description":"Return all available plan configs and the plan hierarchy. The platform app uses this instead of maintaining its own copy. Requires the internal cloud key.","operationId":"get_available_plans_api_v1_cloud_internal_plans_get","responses":{"200":{"description":"Plan feature configs and plan hierarchy.","content":{"application/json":{"schema":{}}}},"403":{"description":"Missing or invalid CloudInternalKey header"}}}},"/api/v1/cloud_internal/email_automation_data":{"get":{"tags":["cloud_internal"],"summary":"Get email automation data","description":"Returns aggregated data for the platform cron jobs to decide which transactional emails to send. Includes recent signups, new orgs, new members, recently published courses, milestone orgs, inactive orgs, and digest orgs. Requires the internal cloud key.","operationId":"get_email_automation_data_api_v1_cloud_internal_email_automation_data_get","responses":{"200":{"description":"Aggregated email automation dataset.","content":{"application/json":{"schema":{}}}},"403":{"description":"Missing or invalid CloudInternalKey header"}}}},"/api/v1/payments/stripe/webhook":{"post":{"tags":["payments"],"summary":"Stripe webhook (standard)","description":"Receive and process Stripe webhook events for the standard (non-Connect) account. Called by Stripe.","operationId":"api_handle_stripe_webhook_api_v1_payments_stripe_webhook_post","responses":{"200":{"description":"Webhook event accepted.","content":{"application/json":{"schema":{}}}},"400":{"description":"Invalid signature or malformed payload"}}}},"/api/v1/payments/stripe/webhook/connect":{"post":{"tags":["payments"],"summary":"Stripe webhook (Connect)","description":"Receive and process Stripe webhook events for Stripe Connect / Express accounts. Called by Stripe.","operationId":"api_handle_stripe_webhook_connect_api_v1_payments_stripe_webhook_connect_post","responses":{"200":{"description":"Webhook event accepted.","content":{"application/json":{"schema":{}}}},"400":{"description":"Invalid signature or malformed payload"}}}},"/api/v1/payments/{org_id}/config":{"post":{"tags":["payments"],"summary":"Initialize payments config","description":"Initialize a payments configuration for an organization with the given provider. Requires an org admin to be authenticated.","operationId":"api_create_payments_config_api_v1_payments__org_id__config_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"provider","in":"query","required":true,"schema":{"const":"stripe","type":"string","title":"Provider"}}],"responses":{"200":{"description":"Newly created payments config for the org.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentsConfig"}}}},"401":{"description":"Authentication required"},"403":{"description":"Caller lacks permission to manage payments for this org"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["payments"],"summary":"Get payments config","description":"Return the payments configuration(s) for the organization.","operationId":"api_get_payments_config_api_v1_payments__org_id__config_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"responses":{"200":{"description":"List of payments configs for the organization.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PaymentsConfigRead"},"title":"Response Api Get Payments Config Api V1 Payments  Org Id  Config Get"}}}},"401":{"description":"Authentication required"},"403":{"description":"Caller lacks permission to view payments config for this org"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["payments"],"summary":"Delete payments config","description":"Delete the payments configuration for an organization.","operationId":"api_delete_payments_config_api_v1_payments__org_id__config_delete","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"responses":{"200":{"description":"Payments config deleted successfully.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"Caller lacks permission to manage payments for this org"},"404":{"description":"Payments config not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/payments/{org_id}/groups":{"post":{"tags":["payments"],"summary":"Create payment group","description":"Create a new payment group that can bundle resources for offers.","operationId":"api_create_payments_group_api_v1_payments__org_id__groups_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentsGroupCreate"}}}},"responses":{"200":{"description":"Newly created payment group.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentsGroupRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"Caller lacks permission to manage payments for this org"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["payments"],"summary":"List payment groups","description":"Return all payment groups configured for an organization.","operationId":"api_list_payments_groups_api_v1_payments__org_id__groups_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"responses":{"200":{"description":"List of payment groups for the org.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PaymentsGroupRead"},"title":"Response Api List Payments Groups Api V1 Payments  Org Id  Groups Get"}}}},"401":{"description":"Authentication required"},"403":{"description":"Caller lacks permission to view payment groups"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/payments/{org_id}/groups/{group_id}":{"get":{"tags":["payments"],"summary":"Get payment group","description":"Return a single payment group by id.","operationId":"api_get_payments_group_api_v1_payments__org_id__groups__group_id__get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"group_id","in":"path","required":true,"schema":{"type":"integer","title":"Group Id"}}],"responses":{"200":{"description":"The requested payment group.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentsGroupRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"Caller lacks permission to view this payment group"},"404":{"description":"Payment group not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["payments"],"summary":"Update payment group","description":"Update metadata on an existing payment group.","operationId":"api_update_payments_group_api_v1_payments__org_id__groups__group_id__put","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"group_id","in":"path","required":true,"schema":{"type":"integer","title":"Group Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentsGroupUpdate"}}}},"responses":{"200":{"description":"Updated payment group.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentsGroupRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"Caller lacks permission to manage this payment group"},"404":{"description":"Payment group not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["payments"],"summary":"Delete payment group","description":"Delete an existing payment group. Associated resources are detached.","operationId":"api_delete_payments_group_api_v1_payments__org_id__groups__group_id__delete","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"group_id","in":"path","required":true,"schema":{"type":"integer","title":"Group Id"}}],"responses":{"200":{"description":"Payment group deleted successfully.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"Caller lacks permission to manage this payment group"},"404":{"description":"Payment group not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/payments/{org_id}/groups/{group_id}/resources":{"post":{"tags":["payments"],"summary":"Add resource to payment group","description":"Attach a resource (by UUID) to an existing payment group.","operationId":"api_add_group_resource_api_v1_payments__org_id__groups__group_id__resources_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"group_id","in":"path","required":true,"schema":{"type":"integer","title":"Group Id"}},{"name":"resource_uuid","in":"query","required":true,"schema":{"type":"string","title":"Resource Uuid"}}],"responses":{"200":{"description":"Resource linked to the payment group.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"Caller lacks permission to manage this payment group"},"404":{"description":"Payment group or resource not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["payments"],"summary":"Remove resource from payment group","description":"Detach a resource from an existing payment group.","operationId":"api_remove_group_resource_api_v1_payments__org_id__groups__group_id__resources_delete","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"group_id","in":"path","required":true,"schema":{"type":"integer","title":"Group Id"}},{"name":"resource_uuid","in":"query","required":true,"schema":{"type":"string","title":"Resource Uuid"}}],"responses":{"200":{"description":"Resource removed from the payment group.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"Caller lacks permission to manage this payment group"},"404":{"description":"Payment group or resource not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["payments"],"summary":"List payment group resources","description":"Return the list of resource UUIDs attached to a payment group.","operationId":"api_list_group_resources_api_v1_payments__org_id__groups__group_id__resources_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"group_id","in":"path","required":true,"schema":{"type":"integer","title":"Group Id"}}],"responses":{"200":{"description":"Resource UUIDs attached to the group.","content":{"application/json":{"schema":{"type":"array","items":{"type":"string"},"title":"Response Api List Group Resources Api V1 Payments  Org Id  Groups  Group Id  Resources Get"}}}},"404":{"description":"Payment group not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/payments/{org_id}/groups/{group_id}/sync":{"post":{"tags":["payments"],"summary":"Add usergroup sync to payment group","description":"Link a usergroup to a payment group so purchasers are automatically added to that cohort after a successful payment.","operationId":"api_add_group_sync_api_v1_payments__org_id__groups__group_id__sync_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"group_id","in":"path","required":true,"schema":{"type":"integer","title":"Group Id"}},{"name":"usergroup_id","in":"query","required":true,"schema":{"type":"integer","title":"Usergroup Id"}}],"responses":{"200":{"description":"Usergroup sync added to the payment group.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"Caller lacks permission to manage this payment group"},"404":{"description":"Payment group or usergroup not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["payments"],"summary":"Remove usergroup sync","description":"Remove a usergroup sync from a payment group.","operationId":"api_remove_group_sync_api_v1_payments__org_id__groups__group_id__sync_delete","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"group_id","in":"path","required":true,"schema":{"type":"integer","title":"Group Id"}},{"name":"usergroup_id","in":"query","required":true,"schema":{"type":"integer","title":"Usergroup Id"}}],"responses":{"200":{"description":"Usergroup sync removed.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"Caller lacks permission to manage this payment group"},"404":{"description":"Payment group or sync not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["payments"],"summary":"List usergroup syncs","description":"Return all usergroup syncs configured for a payment group.","operationId":"api_list_group_syncs_api_v1_payments__org_id__groups__group_id__sync_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"group_id","in":"path","required":true,"schema":{"type":"integer","title":"Group Id"}}],"responses":{"200":{"description":"Usergroup syncs configured for the payment group.","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true},"title":"Response Api List Group Syncs Api V1 Payments  Org Id  Groups  Group Id  Sync Get"}}}},"404":{"description":"Payment group not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/payments/{org_id}/offers/{offer_id}/resources":{"post":{"tags":["payments"],"summary":"Add resource to offer","description":"Attach a direct resource (e.g. a course) to an offer. Grants buyers of this offer access to the linked resource.","operationId":"api_add_offer_resource_api_v1_payments__org_id__offers__offer_id__resources_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"offer_id","in":"path","required":true,"schema":{"type":"integer","title":"Offer Id"}},{"name":"resource_uuid","in":"query","required":true,"schema":{"type":"string","title":"Resource Uuid"}}],"responses":{"200":{"description":"Resource linked to the offer.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"Caller lacks permission to manage this offer"},"404":{"description":"Offer, org, or resource not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["payments"],"summary":"Remove resource from offer","description":"Detach a directly-linked resource from an offer. Does not affect resources granted through a payments group.","operationId":"api_remove_offer_resource_api_v1_payments__org_id__offers__offer_id__resources_delete","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"offer_id","in":"path","required":true,"schema":{"type":"integer","title":"Offer Id"}},{"name":"resource_uuid","in":"query","required":true,"schema":{"type":"string","title":"Resource Uuid"}}],"responses":{"200":{"description":"Resource removed from the offer.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"Caller lacks permission to manage this offer"},"404":{"description":"Offer or link not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["payments"],"summary":"List offer resources","description":"Public endpoint returning the resource UUIDs directly linked to an offer (excluding group-granted resources).","operationId":"api_list_offer_resources_api_v1_payments__org_id__offers__offer_id__resources_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"offer_id","in":"path","required":true,"schema":{"type":"integer","title":"Offer Id"}}],"responses":{"200":{"description":"List of resource UUIDs directly linked to the offer.","content":{"application/json":{"schema":{"type":"array","items":{"type":"string"},"title":"Response Api List Offer Resources Api V1 Payments  Org Id  Offers  Offer Id  Resources Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/payments/{org_id}/offers":{"post":{"tags":["payments"],"summary":"Create payments offer","description":"Create a new payments offer (one-time purchase or subscription) for an organization.","operationId":"api_create_payments_offer_api_v1_payments__org_id__offers_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentsOfferCreate"}}}},"responses":{"200":{"description":"Offer created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentsOfferRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"Caller lacks permission to create offers in this org"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["payments"],"summary":"List payments offers","description":"List all payments offers owned by an organization, including unlisted ones. Requires authorization.","operationId":"api_list_payments_offers_api_v1_payments__org_id__offers_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"responses":{"200":{"description":"List of payments offers for the organization.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PaymentsOfferRead"},"title":"Response Api List Payments Offers Api V1 Payments  Org Id  Offers Get"}}}},"401":{"description":"Authentication required"},"403":{"description":"Caller lacks permission to view offers for this org"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/payments/{org_id}/offers/public-listing":{"get":{"tags":["payments"],"summary":"List public offers","description":"Public endpoint listing all publicly-listed offers for an organization, enriched with included-resource metadata (course name, description, thumbnail).","operationId":"api_list_public_offers_api_v1_payments__org_id__offers_public_listing_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"responses":{"200":{"description":"List of public offers with enriched resource info.","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/payments/{org_id}/offers/by-resource":{"get":{"tags":["payments"],"summary":"List offers by resource","description":"Public endpoint returning offers that grant access to a given resource UUID, checking both direct offer resources and payments-group resources.","operationId":"api_get_offers_by_resource_api_v1_payments__org_id__offers_by_resource_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"resource_uuid","in":"query","required":true,"schema":{"type":"string","title":"Resource Uuid"}}],"responses":{"200":{"description":"List of publicly-listed offers that grant access to the resource.","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/payments/{org_id}/offers/{offer_uuid}/public":{"get":{"tags":["payments"],"summary":"Get public offer","description":"Public endpoint returning offer metadata and its included resources enriched with course details.","operationId":"api_get_public_offer_api_v1_payments__org_id__offers__offer_uuid__public_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"offer_uuid","in":"path","required":true,"schema":{"type":"string","title":"Offer Uuid"}}],"responses":{"200":{"description":"Public offer details with enriched included-resources.","content":{"application/json":{"schema":{}}}},"404":{"description":"Offer not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/payments/{org_id}/offers/{offer_id}":{"get":{"tags":["payments"],"summary":"Get payments offer","description":"Get a single payments offer by its numeric id.","operationId":"api_get_payments_offer_api_v1_payments__org_id__offers__offer_id__get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"offer_id","in":"path","required":true,"schema":{"type":"integer","title":"Offer Id"}}],"responses":{"200":{"description":"Offer details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentsOfferRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"Caller lacks permission to view this offer"},"404":{"description":"Offer not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["payments"],"summary":"Update payments offer","description":"Update an existing payments offer.","operationId":"api_update_payments_offer_api_v1_payments__org_id__offers__offer_id__put","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"offer_id","in":"path","required":true,"schema":{"type":"integer","title":"Offer Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentsOfferUpdate"}}}},"responses":{"200":{"description":"Offer updated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentsOfferRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"Caller lacks permission to update this offer"},"404":{"description":"Offer not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["payments"],"summary":"Delete payments offer","description":"Delete a payments offer. The offer becomes unavailable for checkout immediately.","operationId":"api_delete_payments_offer_api_v1_payments__org_id__offers__offer_id__delete","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"offer_id","in":"path","required":true,"schema":{"type":"integer","title":"Offer Id"}}],"responses":{"200":{"description":"Offer deleted.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"Caller lacks permission to delete this offer"},"404":{"description":"Offer not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/payments/{org_id}/offers/{offer_uuid}/checkout":{"post":{"tags":["payments"],"summary":"Create offer checkout session","description":"Create a provider checkout session for an offer. Returns a URL the user should be redirected to in order to complete purchase.","operationId":"api_create_offer_checkout_session_api_v1_payments__org_id__offers__offer_uuid__checkout_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"offer_uuid","in":"path","required":true,"schema":{"type":"string","title":"Offer Uuid"}},{"name":"redirect_uri","in":"query","required":true,"schema":{"type":"string","title":"Redirect Uri"}}],"responses":{"200":{"description":"Checkout session created; returns the provider checkout URL.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"404":{"description":"Offer not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/payments/{org_id}/enrollments/mine":{"get":{"tags":["payments"],"summary":"Get my paid enrollments","description":"Return the current user's paid enrollments (offers purchased) within an organization.","operationId":"api_get_user_enrollments_api_v1_payments__org_id__enrollments_mine_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"responses":{"200":{"description":"The caller's paid enrollments for the organization.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/payments/{org_id}/billing/portal":{"post":{"tags":["payments"],"summary":"Create billing portal session","description":"Create a provider billing-portal session so the user can manage subscriptions, cancel, and view invoices/receipts.","operationId":"api_create_billing_portal_session_api_v1_payments__org_id__billing_portal_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"return_url","in":"query","required":true,"schema":{"type":"string","title":"Return Url"}}],"responses":{"200":{"description":"Billing portal session created; returns the portal URL.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"404":{"description":"No payments config found for this org"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/payments/{org_id}/customers":{"get":{"tags":["payments"],"summary":"List payment customers","description":"List every known payment customer (buyer) for the organization.","operationId":"api_get_customers_api_v1_payments__org_id__customers_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"responses":{"200":{"description":"List of payment customers for the organization.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"Caller lacks permission to view customers for this org"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/payments/{org_id}/stripe/overview":{"get":{"tags":["payments"],"summary":"Get Stripe overview","description":"Live dashboard overview fetched directly from the Stripe API (balance, recent activity summary).","operationId":"api_stripe_overview_api_v1_payments__org_id__stripe_overview_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"responses":{"200":{"description":"Stripe overview snapshot.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/payments/{org_id}/stripe/charges":{"get":{"tags":["payments"],"summary":"List Stripe charges","description":"List Stripe charges for the org's connected account, paginated via `starting_after`. Data is fetched directly from Stripe.","operationId":"api_stripe_charges_api_v1_payments__org_id__stripe_charges_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":25,"title":"Limit"}},{"name":"starting_after","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Starting After"}}],"responses":{"200":{"description":"Paginated list of Stripe charges.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/payments/{org_id}/stripe/subscriptions":{"get":{"tags":["payments"],"summary":"List Stripe subscriptions","description":"List Stripe subscriptions for the org's connected account (defaults to active). Data is fetched directly from Stripe.","operationId":"api_stripe_subscriptions_api_v1_payments__org_id__stripe_subscriptions_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"status","in":"query","required":false,"schema":{"type":"string","default":"active","title":"Status"}}],"responses":{"200":{"description":"List of Stripe subscriptions with the given status.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/payments/{org_id}/stripe/connect/link":{"post":{"tags":["payments"],"summary":"Generate Stripe Connect link","description":"Generate a Stripe Connect OAuth URL so an admin can connect their own Stripe account to the organization.","operationId":"api_generate_stripe_connect_link_api_v1_payments__org_id__stripe_connect_link_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"redirect_uri","in":"query","required":true,"schema":{"type":"string","title":"Redirect Uri"}}],"responses":{"200":{"description":"Stripe Connect OAuth URL for the admin to visit.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"Caller lacks permission to configure payments for this org"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/payments/stripe/oauth/callback":{"get":{"tags":["payments"],"summary":"Stripe OAuth callback","description":"Callback endpoint Stripe redirects to after the admin completes the Connect OAuth flow. Persists the resulting account id to the org's payments config.","operationId":"stripe_oauth_callback_api_v1_payments_stripe_oauth_callback_get","parameters":[{"name":"code","in":"query","required":true,"schema":{"type":"string","title":"Code"}},{"name":"org_id","in":"query","required":true,"schema":{"type":"integer","title":"Org Id"}}],"responses":{"200":{"description":"OAuth exchange completed — connected account stored.","content":{"application/json":{"schema":{}}}},"400":{"description":"Invalid or expired authorization code"},"401":{"description":"Authentication required"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/payments/{org_id}/stripe/express/connect/link":{"post":{"tags":["payments"],"summary":"Create Stripe Express link","description":"Create a Stripe Express account (if not already created) and return an onboarding link for the admin to complete account setup.","operationId":"api_stripe_express_connect_link_api_v1_payments__org_id__stripe_express_connect_link_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"redirect_uri","in":"query","required":true,"schema":{"type":"string","title":"Redirect Uri"}}],"responses":{"200":{"description":"Stripe Express onboarding URL.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"Caller lacks permission to configure payments for this org"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/payments/{org_id}/stripe/express/connect/refresh":{"post":{"tags":["payments"],"summary":"Refresh Stripe Express link","description":"Generate a fresh Stripe Express onboarding link when the previous one has expired. This endpoint is unauthenticated because Stripe redirects unauthenticated sessions here.","operationId":"api_stripe_express_connect_refresh_api_v1_payments__org_id__stripe_express_connect_refresh_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"redirect_uri","in":"query","required":true,"schema":{"type":"string","title":"Redirect Uri"}}],"responses":{"200":{"description":"Refreshed onboarding URL.","content":{"application/json":{"schema":{}}}},"404":{"description":"No payments config or Express account for this org"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/payments/{org_id}/stripe/express/dashboard":{"get":{"tags":["payments"],"summary":"Get Stripe Express dashboard URL","description":"Return a Stripe Express hosted dashboard URL for the connected Express account so the admin can manage payouts, balances, etc.","operationId":"api_stripe_express_dashboard_api_v1_payments__org_id__stripe_express_dashboard_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"responses":{"200":{"description":"Hosted Stripe Express dashboard URL.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"Caller lacks permission to view payments for this org"},"404":{"description":"No Express account linked to this org"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ee/status":{"get":{"tags":["ee"],"summary":"Get Enterprise Edition status","description":"Return the status of the Enterprise Edition build including version and license type.","operationId":"get_ee_status_api_v1_ee_status_get","responses":{"200":{"description":"Enterprise Edition status payload with enabled flag, version, and license.","content":{"application/json":{"schema":{}}}}}}},"/api/v1/ee/audit_logs/export":{"get":{"tags":["ee","audit_logs"],"summary":"Export audit logs as CSV","description":"Export audit logs for an organization as a CSV file. Supports the same filter set as the paginated listing endpoint and streams the result as an attachment. Requires Enterprise plan and admin RBAC.","operationId":"export_audit_logs_api_v1_ee_audit_logs_export_get","parameters":[{"name":"org_id","in":"query","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"user_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Id"}},{"name":"action","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Action"}},{"name":"resource","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Resource"}},{"name":"status_code","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Status Code"}},{"name":"ip_address","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ip Address"}},{"name":"username","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Username"}},{"name":"name","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"}},{"name":"start_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Start Date"}},{"name":"end_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"End Date"}}],"responses":{"200":{"description":"CSV file containing the filtered audit log rows.","content":{"application/json":{"schema":{}},"text/csv":{}}},"401":{"description":"Authentication required"},"403":{"description":"Organization not on Enterprise plan or caller lacks admin rights"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ee/audit_logs/":{"get":{"tags":["ee","audit_logs"],"summary":"List audit logs","description":"Retrieve audit logs for an organization with filtering and pagination. Supports filtering by user, action, resource, status code, IP, and date range. Requires Enterprise plan and admin RBAC.","operationId":"get_audit_logs_api_v1_ee_audit_logs__get","parameters":[{"name":"org_id","in":"query","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","lte":100,"default":100,"title":"Limit"}},{"name":"user_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Id"}},{"name":"action","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Action"}},{"name":"resource","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Resource"}},{"name":"status_code","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Status Code"}},{"name":"ip_address","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ip Address"}},{"name":"username","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Username"}},{"name":"name","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"}},{"name":"start_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Start Date"}},{"name":"end_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"End Date"}}],"responses":{"200":{"description":"Paginated audit log entries with total count.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditLogPaginated"}}}},"401":{"description":"Authentication required"},"403":{"description":"Organization not on Enterprise plan or caller lacks admin rights"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/scorm/analyze/{course_uuid}":{"post":{"tags":["scorm"],"summary":"Analyze a SCORM package","description":"Upload and analyze a SCORM package without importing it. Returns the list of detected SCOs with their details. The package is stored temporarily for a subsequent import call. Requires Enterprise plan.","operationId":"api_analyze_scorm_package_api_v1_scorm_analyze__course_uuid__post","parameters":[{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","title":"Course Uuid"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_api_analyze_scorm_package_api_v1_scorm_analyze__course_uuid__post"}}}},"responses":{"200":{"description":"Detected SCO listing and temporary package id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScormAnalysisResponse"}}}},"400":{"description":"Invalid course_uuid format"},"401":{"description":"Authentication required"},"403":{"description":"SCORM not available outside Enterprise plan"},"404":{"description":"Course or organization config not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/scorm/import/{course_uuid}":{"post":{"tags":["scorm"],"summary":"Import an analyzed SCORM package","description":"Import a previously analyzed SCORM package with chapter assignments, creating one activity per SCO assignment. Requires Enterprise plan.","operationId":"api_import_scorm_package_api_v1_scorm_import__course_uuid__post","parameters":[{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","title":"Course Uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScormImportRequest"}}}},"responses":{"200":{"description":"List of activities created from the SCORM package.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ActivityRead"},"title":"Response Api Import Scorm Package Api V1 Scorm Import  Course Uuid  Post"}}}},"400":{"description":"Invalid course_uuid format"},"401":{"description":"Authentication required"},"403":{"description":"SCORM not available outside Enterprise plan"},"404":{"description":"Course or organization config not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/scorm/analyze-for-import/{org_id}":{"post":{"tags":["scorm"],"summary":"Analyze a SCORM package for new-course import","description":"Upload and analyze a SCORM package to prepare it for importing as a new course. Returns the detected SCOs; the package is stored temporarily for a subsequent course-import call. Requires Enterprise plan.","operationId":"api_analyze_scorm_for_course_import_api_v1_scorm_analyze_for_import__org_id__post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_api_analyze_scorm_for_course_import_api_v1_scorm_analyze_for_import__org_id__post"}}}},"responses":{"200":{"description":"Detected SCO listing and temporary package id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScormAnalysisResponse"}}}},"401":{"description":"Authentication required"},"403":{"description":"SCORM not available outside Enterprise plan"},"404":{"description":"Organization config not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/scorm/import-as-course":{"post":{"tags":["scorm"],"summary":"Import a SCORM package as a new course","description":"Create a new course, its chapters, and its activities from a previously analyzed SCORM package. Requires Enterprise plan.","operationId":"api_import_scorm_as_course_api_v1_scorm_import_as_course_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScormCourseImportRequest"}}},"required":true},"responses":{"200":{"description":"Newly created course and activity metadata.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScormCourseImportResponse"}}}},"401":{"description":"Authentication required"},"403":{"description":"SCORM not available outside Enterprise plan"},"404":{"description":"Organization config not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/scorm/{activity_uuid}/content/{file_path}":{"get":{"tags":["scorm"],"summary":"Serve a SCORM content file","description":"Serve SCORM content files. The file_path parameter captures the full path within the SCORM package. Requires authentication for non-public courses; public + published courses allow anonymous access so SCORM sub-resources (JS, CSS, images) can load without per-request tokens.","operationId":"api_get_scorm_content_api_v1_scorm__activity_uuid__content__file_path__get","parameters":[{"name":"activity_uuid","in":"path","required":true,"schema":{"type":"string","title":"Activity Uuid"}},{"name":"file_path","in":"path","required":true,"schema":{"type":"string","title":"File Path"}}],"responses":{"200":{"description":"Binary or text content of the requested SCORM asset.","content":{"application/json":{"schema":{}},"application/octet-stream":{}}},"400":{"description":"Invalid activity_uuid format"},"401":{"description":"Authentication required for non-public course"},"403":{"description":"Resolved path escapes the activity content directory"},"404":{"description":"Activity, organization, course, or file not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/scorm/{activity_uuid}/runtime/initialize":{"post":{"tags":["scorm"],"summary":"Initialize a SCORM session","description":"Initialize a SCORM runtime session. Returns initial CMI data based on the SCORM version and any stored data for the current user.","operationId":"api_initialize_scorm_session_api_v1_scorm__activity_uuid__runtime_initialize_post","parameters":[{"name":"activity_uuid","in":"path","required":true,"schema":{"type":"string","title":"Activity Uuid"}}],"responses":{"200":{"description":"Initial CMI data for the session.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Api Initialize Scorm Session Api V1 Scorm  Activity Uuid  Runtime Initialize Post"}}}},"400":{"description":"Invalid activity_uuid format"},"401":{"description":"Authentication required"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/scorm/{activity_uuid}/runtime/commit":{"post":{"tags":["scorm"],"summary":"Commit SCORM runtime data","description":"Commit (save) SCORM runtime data for the current session. Called when the SCORM content invokes LMSCommit() or Commit().","operationId":"api_commit_scorm_data_api_v1_scorm__activity_uuid__runtime_commit_post","parameters":[{"name":"activity_uuid","in":"path","required":true,"schema":{"type":"string","title":"Activity Uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Cmi Data"}}}},"responses":{"200":{"description":"Acknowledgement that the CMI data was stored.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Api Commit Scorm Data Api V1 Scorm  Activity Uuid  Runtime Commit Post"}}}},"400":{"description":"Invalid activity_uuid format"},"401":{"description":"Authentication required"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/scorm/{activity_uuid}/runtime/terminate":{"post":{"tags":["scorm"],"summary":"Terminate a SCORM session","description":"Terminate a SCORM runtime session. Called when the SCORM content invokes LMSFinish() or Terminate(). Optionally accepts final CMI data to commit.","operationId":"api_terminate_scorm_session_api_v1_scorm__activity_uuid__runtime_terminate_post","parameters":[{"name":"activity_uuid","in":"path","required":true,"schema":{"type":"string","title":"Activity Uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Cmi Data"}}}},"responses":{"200":{"description":"Session terminated and any final CMI data committed.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Api Terminate Scorm Session Api V1 Scorm  Activity Uuid  Runtime Terminate Post"}}}},"400":{"description":"Invalid activity_uuid format"},"401":{"description":"Authentication required"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/scorm/{activity_uuid}/runtime/data":{"get":{"tags":["scorm"],"summary":"Get SCORM runtime data","description":"Return SCORM runtime data for the current user and activity.","operationId":"api_get_runtime_data_api_v1_scorm__activity_uuid__runtime_data_get","parameters":[{"name":"activity_uuid","in":"path","required":true,"schema":{"type":"string","title":"Activity Uuid"}}],"responses":{"200":{"description":"Stored SCORM runtime data for the user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScormRuntimeDataRead"}}}},"400":{"description":"Invalid activity_uuid format"},"401":{"description":"Authentication required"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["scorm"],"summary":"Update SCORM runtime data","description":"Update SCORM runtime data directly for the current user and activity.","operationId":"api_update_runtime_data_api_v1_scorm__activity_uuid__runtime_data_put","parameters":[{"name":"activity_uuid","in":"path","required":true,"schema":{"type":"string","title":"Activity Uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScormRuntimeDataUpdate"}}}},"responses":{"200":{"description":"Updated SCORM runtime data.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScormRuntimeDataRead"}}}},"400":{"description":"Invalid activity_uuid format"},"401":{"description":"Authentication required"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/scorm/{activity_uuid}/results":{"get":{"tags":["scorm"],"summary":"List learner SCORM results for an activity","description":"Return every learner's SCORM completion/score/time for the activity. Requires course management permission (instructor/admin).","operationId":"api_get_activity_results_api_v1_scorm__activity_uuid__results_get","parameters":[{"name":"activity_uuid","in":"path","required":true,"schema":{"type":"string","title":"Activity Uuid"}}],"responses":{"200":{"description":"Per-learner SCORM results.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ScormActivityResultRead"},"title":"Response Api Get Activity Results Api V1 Scorm  Activity Uuid  Results Get"}}}},"400":{"description":"Invalid activity_uuid format"},"401":{"description":"Authentication required"},"403":{"description":"Course management permission required"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/sso/providers":{"get":{"tags":["sso","auth"],"summary":"List available SSO providers","description":"List all supported SSO providers with their configuration details. Requires the caller to be an org admin on an Enterprise-plan organization.","operationId":"list_sso_providers_api_v1_auth_sso_providers_get","parameters":[{"name":"org_id","in":"query","required":true,"schema":{"type":"integer","title":"Org Id"}}],"responses":{"200":{"description":"List of supported SSO providers with their metadata.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SSOProviderInfo"},"title":"Response List Sso Providers Api V1 Auth Sso Providers Get"}}}},"401":{"description":"Authentication required"},"403":{"description":"Organization not on Enterprise plan or caller lacks admin rights"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/sso/{org_id}/config":{"get":{"tags":["sso","auth"],"summary":"Get SSO configuration","description":"Return the current SSO configuration for an organization or null if it has not been configured yet. Requires org admin on an Enterprise-plan org.","operationId":"get_sso_config_api_v1_auth_sso__org_id__config_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"responses":{"200":{"description":"SSO connection if configured, otherwise null.","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/SSOConnectionRead"},{"type":"null"}],"title":"Response Get Sso Config Api V1 Auth Sso  Org Id  Config Get"}}}},"401":{"description":"Authentication required"},"403":{"description":"Organization not on Enterprise plan or caller lacks admin rights"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["sso","auth"],"summary":"Create SSO configuration","description":"Create SSO configuration for an organization, wiring up the chosen provider and its settings. Requires org admin on an Enterprise-plan org.","operationId":"create_sso_config_api_v1_auth_sso__org_id__config_post","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOConnectionCreate"}}}},"responses":{"200":{"description":"Newly created SSO connection.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOConnectionRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"Organization not on Enterprise plan or caller lacks admin rights"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["sso","auth"],"summary":"Update SSO configuration","description":"Modify existing SSO settings for an organization. Requires org admin on an Enterprise-plan org.","operationId":"update_sso_config_api_v1_auth_sso__org_id__config_put","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOConnectionUpdate"}}}},"responses":{"200":{"description":"Updated SSO connection.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOConnectionRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"Organization not on Enterprise plan or caller lacks admin rights"},"404":{"description":"Organization or SSO connection not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["sso","auth"],"summary":"Delete SSO configuration","description":"Disable SSO for an organization by removing its SSO connection. Requires org admin on an Enterprise-plan org.","operationId":"delete_sso_config_api_v1_auth_sso__org_id__config_delete","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"responses":{"200":{"description":"SSO configuration deleted successfully.","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"Organization not on Enterprise plan or caller lacks admin rights"},"404":{"description":"Organization or SSO configuration not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/sso/{org_id}/setup-url":{"get":{"tags":["sso","auth"],"summary":"Get provider setup URL","description":"Return the admin portal URL for configuring the identity provider. Only available for providers that expose a setup portal (for example WorkOS). Requires org admin on an Enterprise-plan org.","operationId":"get_setup_url_api_v1_auth_sso__org_id__setup_url_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"return_url","in":"query","required":true,"schema":{"type":"string","description":"URL to return to after setup","title":"Return Url"},"description":"URL to return to after setup"}],"responses":{"200":{"description":"Setup URL payload for the admin portal.","content":{"application/json":{"schema":{}}}},"400":{"description":"Setup URL is not available or provider does not support setup portal"},"401":{"description":"Authentication required"},"403":{"description":"Organization not on Enterprise plan or caller lacks admin rights"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/sso/check":{"get":{"tags":["sso","auth"],"summary":"Check if SSO is enabled","description":"Public endpoint used by the login page to determine whether the SSO button should be shown for a given organization slug.","operationId":"check_sso_api_v1_auth_sso_check_get","parameters":[{"name":"org_slug","in":"query","required":true,"schema":{"type":"string","description":"Organization slug","title":"Org Slug"},"description":"Organization slug"}],"responses":{"200":{"description":"Whether SSO is enabled for the organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOLoginCheckResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/sso/authorize":{"get":{"tags":["sso","auth"],"summary":"Initiate SSO login flow","description":"Start an SSO login flow by returning the authorization URL the user should be redirected to at the identity provider.","operationId":"authorize_sso_api_v1_auth_sso_authorize_get","parameters":[{"name":"org_slug","in":"query","required":true,"schema":{"type":"string","description":"Organization slug","title":"Org Slug"},"description":"Organization slug"}],"responses":{"200":{"description":"Authorization URL and state for the IdP redirect.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOAuthorizationResponse"}}}},"400":{"description":"SSO is not enabled or configured for this organization"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/sso/callback":{"get":{"tags":["sso","auth"],"summary":"Handle SSO callback","description":"Handle the SSO callback from the identity provider. Exchanges the authorization code for a user profile, creates or finds the user, sets authentication cookies, and returns the resolved user along with tokens and a frontend redirect URL. Also surfaces IdP error responses.","operationId":"sso_callback_api_v1_auth_sso_callback_get","parameters":[{"name":"code","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Authorization code from IdP","title":"Code"},"description":"Authorization code from IdP"},{"name":"state","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"State parameter for CSRF verification","title":"State"},"description":"State parameter for CSRF verification"},{"name":"error","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Error code from IdP","title":"Error"},"description":"Error code from IdP"},{"name":"error_description","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Error description from IdP","title":"Error Description"},"description":"Error description from IdP"}],"responses":{"200":{"description":"Authenticated user, tokens, and frontend redirect URL.","content":{"application/json":{"schema":{}}}},"400":{"description":"IdP returned an error or required parameters are missing"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ee/superadmin/status":{"get":{"tags":["ee","superadmin"],"summary":"Check superadmin status","description":"Return whether the current user has superadmin privileges. Used by the dashboard to gate superadmin UI.","operationId":"get_superadmin_status_api_v1_ee_superadmin_status_get","responses":{"200":{"description":"Caller is a superadmin.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuperadminStatusResponse"}}}},"401":{"description":"Authentication required"},"403":{"description":"Caller is not a superadmin"}}}},"/api/v1/ee/superadmin/users":{"get":{"tags":["ee","superadmin"],"summary":"List all platform users","description":"List every user across every organization on the platform, with paging, sort, search, and superadmin/min/max-org filters.","operationId":"list_all_users_api_v1_ee_superadmin_users_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"Page"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":20,"title":"Limit"}},{"name":"sort","in":"query","required":false,"schema":{"type":"string","default":"id","title":"Sort"}},{"name":"search","in":"query","required":false,"schema":{"type":"string","default":"","title":"Search"}},{"name":"superadmin","in":"query","required":false,"schema":{"type":"string","default":"","title":"Superadmin"}},{"name":"min_orgs","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Min Orgs"}},{"name":"max_orgs","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Max Orgs"}}],"responses":{"200":{"description":"Paginated list of users with org counts and memberships.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List All Users Api V1 Ee Superadmin Users Get"}}}},"401":{"description":"Authentication required"},"403":{"description":"Caller is not a superadmin"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ee/superadmin/organizations":{"post":{"tags":["ee","superadmin"],"summary":"Create an organization (superadmin)","description":"Create a new organization as a superadmin. Links the calling superadmin as an admin member of the org and seeds a v2 config. In SaaS mode the `plan` field is honored (defaults to `free`); in EE mode the field is ignored and the org is seeded with `plan=enterprise` so all features are available by default.","operationId":"create_organization_api_v1_ee_superadmin_organizations_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgCreateRequest"}}}},"responses":{"200":{"description":"Organization created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgDetailResponse"}}}},"400":{"description":"Invalid plan value or slug already in use"},"401":{"description":"Authentication required"},"403":{"description":"Caller is not a superadmin"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["ee","superadmin"],"summary":"List all organizations","description":"List every organization on the platform with user/course counts, plan, custom domains, and admin users. Supports paging, search, plan filter, and several sort modes (including Tinybird-backed `most_visits`).","operationId":"list_all_organizations_api_v1_ee_superadmin_organizations_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"Page"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":20,"title":"Limit"}},{"name":"sort","in":"query","required":false,"schema":{"type":"string","default":"id","title":"Sort"}},{"name":"search","in":"query","required":false,"schema":{"type":"string","default":"","title":"Search"}},{"name":"plan","in":"query","required":false,"schema":{"type":"string","default":"","title":"Plan"}}],"responses":{"200":{"description":"Paginated list of organizations with enrichment (plan, domains, admins, counts).","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List All Organizations Api V1 Ee Superadmin Organizations Get"}}}},"401":{"description":"Authentication required"},"403":{"description":"Caller is not a superadmin"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ee/superadmin/organizations/visits":{"get":{"tags":["ee","superadmin"],"summary":"Get weekly visits per org","description":"Return daily `page_view` counts per organization for the last 7 days, used for sparklines in the superadmin dashboard. Falls back to an empty response if Tinybird is unavailable.","operationId":"get_org_weekly_visits_api_v1_ee_superadmin_organizations_visits_get","responses":{"200":{"description":"Daily page-view counts per org for the last 7 days.","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Get Org Weekly Visits Api V1 Ee Superadmin Organizations Visits Get"}}}},"401":{"description":"Authentication required"},"403":{"description":"Caller is not a superadmin"}}}},"/api/v1/ee/superadmin/organizations/{org_id}":{"get":{"tags":["ee","superadmin"],"summary":"Get organization detail","description":"Get a single organization's full detail including config, plan, custom domains, admin users, and user/course counts.","operationId":"get_organization_detail_api_v1_ee_superadmin_organizations__org_id__get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"responses":{"200":{"description":"Organization detail with enrichment.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgDetailResponse"}}}},"401":{"description":"Authentication required"},"403":{"description":"Caller is not a superadmin"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ee/superadmin/organizations/{org_id}/courses":{"get":{"tags":["ee","superadmin"],"summary":"List courses for organization","description":"Paginated list of courses for a specific organization.","operationId":"list_org_courses_api_v1_ee_superadmin_organizations__org_id__courses_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"Page"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}}],"responses":{"200":{"description":"Paginated list of courses in the organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse"}}}},"401":{"description":"Authentication required"},"403":{"description":"Caller is not a superadmin"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ee/superadmin/organizations/{org_id}/users":{"get":{"tags":["ee","superadmin"],"summary":"List users for organization","description":"Paginated list of users that belong to a specific organization, with optional search.","operationId":"list_org_users_api_v1_ee_superadmin_organizations__org_id__users_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"Page"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}},{"name":"search","in":"query","required":false,"schema":{"type":"string","default":"","title":"Search"}}],"responses":{"200":{"description":"Paginated list of users in the organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse"}}}},"401":{"description":"Authentication required"},"403":{"description":"Caller is not a superadmin"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ee/superadmin/organizations/{org_id}/plan":{"put":{"tags":["ee","superadmin"],"summary":"Update organization plan","description":"Update an organization's plan (free, standard, pro, enterprise). Writes to both v1 and v2 config layouts.","operationId":"update_org_plan_api_v1_ee_superadmin_organizations__org_id__plan_put","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanUpdateRequest"}}}},"responses":{"200":{"description":"Plan updated.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Update Org Plan Api V1 Ee Superadmin Organizations  Org Id  Plan Put"}}}},"400":{"description":"Invalid plan value"},"401":{"description":"Authentication required"},"403":{"description":"Caller is not a superadmin"},"404":{"description":"Organization or organization config not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ee/superadmin/organizations/{org_id}/settings":{"put":{"tags":["ee","superadmin"],"summary":"Update organization settings","description":"Update an organization's top-level settings (name, slug, email, description). Enforces slug uniqueness.","operationId":"update_org_settings_api_v1_ee_superadmin_organizations__org_id__settings_put","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgSettingsUpdateRequest"}}}},"responses":{"200":{"description":"Organization settings updated.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Update Org Settings Api V1 Ee Superadmin Organizations  Org Id  Settings Put"}}}},"400":{"description":"Slug already in use"},"401":{"description":"Authentication required"},"403":{"description":"Caller is not a superadmin"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ee/superadmin/organizations/{org_id}/config":{"put":{"tags":["ee","superadmin"],"summary":"Update organization config","description":"Replace an organization's full config blob (features, limits, plan metadata, etc.). Superadmin only.","operationId":"update_org_config_api_v1_ee_superadmin_organizations__org_id__config_put","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgConfigUpdateRequest"}}}},"responses":{"200":{"description":"Organization config updated.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Update Org Config Api V1 Ee Superadmin Organizations  Org Id  Config Put"}}}},"401":{"description":"Authentication required"},"403":{"description":"Caller is not a superadmin"},"404":{"description":"Organization or organization config not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ee/superadmin/organizations/{org_id}/admin_toggles":{"put":{"tags":["ee","superadmin"],"summary":"Update organization admin toggles","description":"Replace the `admin_toggles` slice of an organization's v2 config — the per-feature on/off switches (and the few special sub-fields like `ai.copilot_enabled` and `members.signup_mode`). Validated against the AdminToggles pydantic model. v1 configs are rejected with 400.","operationId":"update_org_admin_toggles_api_v1_ee_superadmin_organizations__org_id__admin_toggles_put","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminTogglesUpdateRequest"}}}},"responses":{"200":{"description":"Admin toggles updated.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Update Org Admin Toggles Api V1 Ee Superadmin Organizations  Org Id  Admin Toggles Put"}}}},"400":{"description":"v1 config (admin toggles unavailable) or invalid toggle shape"},"401":{"description":"Authentication required"},"403":{"description":"Caller is not a superadmin"},"404":{"description":"Organization or organization config not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ee/superadmin/organizations/{org_id}/usage":{"get":{"tags":["ee","superadmin"],"summary":"Get organization usage","description":"Get usage and plan limits for an organization (courses, members, admin seats), including whether each limit is reached. Returns `unlimited` for zero-limit features.","operationId":"get_org_usage_api_v1_ee_superadmin_organizations__org_id__usage_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}}],"responses":{"200":{"description":"Usage and limits for the organization.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Org Usage Api V1 Ee Superadmin Organizations  Org Id  Usage Get"}}}},"401":{"description":"Authentication required"},"403":{"description":"Caller is not a superadmin"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ee/superadmin/organizations/{org_id}/analytics":{"get":{"tags":["ee","superadmin"],"summary":"Get organization analytics","description":"Run the core Tinybird analytics queries for a single organization over the last N days (default 30). Individual query failures are swallowed and returned as empty results.","operationId":"get_org_analytics_api_v1_ee_superadmin_organizations__org_id__analytics_get","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"integer","title":"Org Id"}},{"name":"days","in":"query","required":false,"schema":{"type":"integer","default":30,"title":"Days"}}],"responses":{"200":{"description":"Per-query analytics results for the organization.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Org Analytics Api V1 Ee Superadmin Organizations  Org Id  Analytics Get"}}}},"401":{"description":"Authentication required"},"403":{"description":"Caller is not a superadmin"},"404":{"description":"Organization not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ee/superadmin/analytics/global":{"get":{"tags":["ee","superadmin"],"summary":"Get global analytics","description":"Run the core Tinybird analytics queries globally (org_id=0) over the last N days (default 30). Individual query failures are swallowed and returned as empty results.","operationId":"get_global_analytics_api_v1_ee_superadmin_analytics_global_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","default":30,"title":"Days"}}],"responses":{"200":{"description":"Per-query cross-org analytics results.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Global Analytics Api V1 Ee Superadmin Analytics Global Get"}}}},"401":{"description":"Authentication required"},"403":{"description":"Caller is not a superadmin"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ee/superadmin/tokens/":{"get":{"tags":["ee","superadmin","api_tokens"],"summary":"List superadmin API tokens","description":"List all superadmin API tokens on the platform. Every superadmin sees every token — all superadmins are peers with equivalent power. The plaintext secret is NEVER returned here; only metadata.","operationId":"api_list_superadmin_tokens_api_v1_ee_superadmin_tokens__get","responses":{"200":{"description":"List of superadmin API tokens (metadata only).","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/SuperadminAPITokenRead"},"type":"array","title":"Response Api List Superadmin Tokens Api V1 Ee Superadmin Tokens  Get"}}}},"401":{"description":"Authentication required"},"403":{"description":"Superadmin access required, or caller is an API token"}}},"post":{"tags":["ee","superadmin","api_tokens"],"summary":"Create a superadmin API token","description":"Mint a new cross-org superadmin API token. The full secret is returned ONLY in this response — store it now, as it cannot be retrieved later. The token authenticates to every `/ee/superadmin/*` endpoint via `Authorization: Bearer lh_sa_<token>`.","operationId":"api_create_superadmin_token_api_v1_ee_superadmin_tokens__post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuperadminAPITokenCreate"}}},"required":true},"responses":{"200":{"description":"Token created; the full secret is included in the response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuperadminAPITokenCreatedResponse"}}}},"400":{"description":"Invalid token name"},"401":{"description":"Authentication required"},"403":{"description":"Superadmin access required, or caller is an API token"},"409":{"description":"An active token with this name already exists for this user"},"429":{"description":"Rate limit exceeded for token creation"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ee/superadmin/tokens/{token_uuid}":{"get":{"tags":["ee","superadmin","api_tokens"],"summary":"Get a superadmin API token","operationId":"api_get_superadmin_token_api_v1_ee_superadmin_tokens__token_uuid__get","parameters":[{"name":"token_uuid","in":"path","required":true,"schema":{"type":"string","title":"Token Uuid"}}],"responses":{"200":{"description":"Token metadata.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuperadminAPITokenRead"}}}},"401":{"description":"Authentication required"},"403":{"description":"Superadmin access required, or caller is an API token"},"404":{"description":"Token not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["ee","superadmin","api_tokens"],"summary":"Update a superadmin API token","description":"Update name, description, or expiration. The secret itself cannot be updated.","operationId":"api_update_superadmin_token_api_v1_ee_superadmin_tokens__token_uuid__patch","parameters":[{"name":"token_uuid","in":"path","required":true,"schema":{"type":"string","title":"Token Uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuperadminAPITokenUpdate"}}}},"responses":{"200":{"description":"Token updated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuperadminAPITokenRead"}}}},"400":{"description":"Invalid update payload"},"401":{"description":"Authentication required"},"403":{"description":"Superadmin access required, or caller is an API token"},"404":{"description":"Token not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["ee","superadmin","api_tokens"],"summary":"Revoke a superadmin API token","description":"Soft-revoke a token (sets is_active=False). Revoked tokens cannot be reactivated.","operationId":"api_revoke_superadmin_token_api_v1_ee_superadmin_tokens__token_uuid__delete","parameters":[{"name":"token_uuid","in":"path","required":true,"schema":{"type":"string","title":"Token Uuid"}}],"responses":{"200":{"description":"Token revoked.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Api Revoke Superadmin Token Api V1 Ee Superadmin Tokens  Token Uuid  Delete"}}}},"401":{"description":"Authentication required"},"403":{"description":"Superadmin access required, or caller is an API token"},"404":{"description":"Token not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/health":{"get":{"tags":["health"],"summary":"Health check","description":"Returns the overall health of the service and its dependencies (e.g. database connectivity).","operationId":"health_api_v1_health_get","responses":{"200":{"description":"Service is healthy; includes per-dependency status.","content":{"application/json":{"schema":{}}}}}}},"/api/v1/dev/config":{"get":{"tags":["dev"],"summary":"Get LearnHouse runtime config","description":"Returns the current LearnHouse configuration with sensitive values redacted. Restricted to superadmin users.","operationId":"config_api_v1_dev_config_get","responses":{"200":{"description":"Configuration dictionary with secrets redacted","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"Superadmin access required"}}}},"/api/v1/dev/migrate_orgconfig_v0_to_v1":{"post":{"tags":["dev"],"summary":"Migrate organization config v0 to v1","description":"Runs the v0 to v1 schema migration across every organization's configuration. Restricted to superadmin users.","operationId":"migrate_api_v1_dev_migrate_orgconfig_v0_to_v1_post","responses":{"200":{"description":"Migration completed successfully","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"Superadmin access required"}}}},"/api/v1/dev/migrate_orgconfig_v1_to_v1.1":{"post":{"tags":["dev"],"summary":"Migrate organization config v1 to v1.1","description":"Runs the v1 to v1.1 schema migration across every organization's configuration. Restricted to superadmin users.","operationId":"migratev1_1_api_v1_dev_migrate_orgconfig_v1_to_v1_1_post","responses":{"200":{"description":"Migration completed successfully","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"Superadmin access required"}}}},"/api/v1/dev/migrate_orgconfig_v1_to_v1.2":{"post":{"tags":["dev"],"summary":"Migrate organization config v1 to v1.2","description":"Runs the v1 to v1.2 schema migration across every organization's configuration. Restricted to superadmin users.","operationId":"migratev1_2_api_v1_dev_migrate_orgconfig_v1_to_v1_2_post","responses":{"200":{"description":"Migration completed successfully","content":{"application/json":{"schema":{}}}},"401":{"description":"Authentication required"},"403":{"description":"Superadmin access required"}}}},"/api/v1/utils/link-preview":{"get":{"tags":["utils"],"summary":"Fetch link preview metadata","description":"Fetches OpenGraph-style preview metadata (title, description, image) for a given URL. Requires an authenticated user.","operationId":"link_preview_api_v1_utils_link_preview_get","parameters":[{"name":"url","in":"query","required":true,"schema":{"type":"string","description":"URL to preview","title":"Url"},"description":"URL to preview"}],"responses":{"200":{"description":"Link preview metadata fetched successfully","content":{"application/json":{"schema":{}}}},"400":{"description":"Failed to fetch or parse link preview"},"401":{"description":"Authentication required"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/stream/video/{org_uuid}/{course_uuid}/{activity_uuid}/{filename}":{"get":{"tags":["stream"],"summary":"Stream an activity video","description":"Streams a video file for a course activity with HTTP Range request support. Validates user read access via RBAC before serving the file.","operationId":"stream_activity_video_api_v1_stream_video__org_uuid___course_uuid___activity_uuid___filename__get","parameters":[{"name":"org_uuid","in":"path","required":true,"schema":{"type":"string","description":"Organization UUID","title":"Org Uuid"},"description":"Organization UUID"},{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","description":"Course UUID","title":"Course Uuid"},"description":"Course UUID"},{"name":"activity_uuid","in":"path","required":true,"schema":{"type":"string","description":"Activity UUID","title":"Activity Uuid"},"description":"Activity UUID"},{"name":"filename","in":"path","required":true,"schema":{"type":"string","description":"Video filename","title":"Filename"},"description":"Video filename"}],"responses":{"200":{"description":"Full video streamed successfully","content":{"application/json":{"schema":{}}}},"206":{"description":"Partial video content returned for a Range request"},"403":{"description":"User is not permitted to read this course"},"404":{"description":"Activity, course, or video file not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"head":{"tags":["stream"],"summary":"Get activity video metadata","description":"Returns metadata for an activity video without the body. Used by video players to probe file size and Range support before playback.","operationId":"head_activity_video_api_v1_stream_video__org_uuid___course_uuid___activity_uuid___filename__head","parameters":[{"name":"org_uuid","in":"path","required":true,"schema":{"type":"string","description":"Organization UUID","title":"Org Uuid"},"description":"Organization UUID"},{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","description":"Course UUID","title":"Course Uuid"},"description":"Course UUID"},{"name":"activity_uuid","in":"path","required":true,"schema":{"type":"string","description":"Activity UUID","title":"Activity Uuid"},"description":"Activity UUID"},{"name":"filename","in":"path","required":true,"schema":{"type":"string","description":"Video filename","title":"Filename"},"description":"Video filename"}],"responses":{"200":{"description":"Video metadata returned via response headers","content":{"application/json":{"schema":{}}}},"403":{"description":"User is not permitted to read this course"},"404":{"description":"Activity, course, or video file not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/stream/hls/{org_uuid}/{course_uuid}/{activity_uuid}/{hls_path}":{"get":{"tags":["stream"],"summary":"Serve an HLS playlist or segment for an activity video","description":"Serves the adaptive-bitrate HLS assets for a hosted video activity. Playlists (.m3u8) are returned after an RBAC check with every segment URL rewritten to a presigned R2 URL, so the player fetches segments directly from object storage. Segments are only served here in local filesystem mode.","operationId":"stream_activity_hls_api_v1_stream_hls__org_uuid___course_uuid___activity_uuid___hls_path__get","parameters":[{"name":"org_uuid","in":"path","required":true,"schema":{"type":"string","description":"Organization UUID","title":"Org Uuid"},"description":"Organization UUID"},{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","description":"Course UUID","title":"Course Uuid"},"description":"Course UUID"},{"name":"activity_uuid","in":"path","required":true,"schema":{"type":"string","description":"Activity UUID","title":"Activity Uuid"},"description":"Activity UUID"},{"name":"hls_path","in":"path","required":true,"schema":{"type":"string","description":"HLS asset path (e.g. master.m3u8)","title":"Hls Path"},"description":"HLS asset path (e.g. master.m3u8)"}],"responses":{"200":{"description":"Playlist or segment returned","content":{"application/json":{"schema":{}}}},"302":{"description":"Redirect to a presigned segment URL (S3/R2 mode)"},"403":{"description":"User is not permitted to read this course"},"404":{"description":"Activity, course, or HLS asset not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/stream/block-hls/{org_uuid}/{course_uuid}/{activity_uuid}/{block_uuid}/{hls_path}":{"get":{"tags":["stream"],"summary":"Serve an HLS playlist or segment for a video block","description":"Serves the adaptive-bitrate HLS assets for a video block inside a dynamic activity — identical behavior to the activity HLS endpoint (RBAC-gated playlists with segment URLs presigned to R2), keyed off the block's dir.","operationId":"stream_block_hls_api_v1_stream_block_hls__org_uuid___course_uuid___activity_uuid___block_uuid___hls_path__get","parameters":[{"name":"org_uuid","in":"path","required":true,"schema":{"type":"string","description":"Organization UUID","title":"Org Uuid"},"description":"Organization UUID"},{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","description":"Course UUID","title":"Course Uuid"},"description":"Course UUID"},{"name":"activity_uuid","in":"path","required":true,"schema":{"type":"string","description":"Activity UUID","title":"Activity Uuid"},"description":"Activity UUID"},{"name":"block_uuid","in":"path","required":true,"schema":{"type":"string","description":"Block UUID","title":"Block Uuid"},"description":"Block UUID"},{"name":"hls_path","in":"path","required":true,"schema":{"type":"string","description":"HLS asset path (e.g. master.m3u8)","title":"Hls Path"},"description":"HLS asset path (e.g. master.m3u8)"}],"responses":{"200":{"description":"Playlist or segment returned","content":{"application/json":{"schema":{}}}},"302":{"description":"Redirect to a presigned segment URL (S3/R2 mode)"},"403":{"description":"User is not permitted to read this course"},"404":{"description":"Activity, course, block, or HLS asset not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/stream/captions/{org_uuid}/{course_uuid}/{activity_uuid}/{lang}.vtt":{"get":{"tags":["stream"],"summary":"Serve a WebVTT caption track for an activity video","description":"Returns the WebVTT subtitle track for the given language after an RBAC check (same access as the video). Served inline so the player can attach it as a text track.","operationId":"stream_activity_captions_api_v1_stream_captions__org_uuid___course_uuid___activity_uuid___lang__vtt_get","parameters":[{"name":"org_uuid","in":"path","required":true,"schema":{"type":"string","description":"Organization UUID","title":"Org Uuid"},"description":"Organization UUID"},{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","description":"Course UUID","title":"Course Uuid"},"description":"Course UUID"},{"name":"activity_uuid","in":"path","required":true,"schema":{"type":"string","description":"Activity UUID","title":"Activity Uuid"},"description":"Activity UUID"},{"name":"lang","in":"path","required":true,"schema":{"type":"string","description":"Caption language code (e.g. en, fr, es-419)","title":"Lang"},"description":"Caption language code (e.g. en, fr, es-419)"}],"responses":{"200":{"description":"WebVTT track returned","content":{"application/json":{"schema":{}}}},"403":{"description":"User is not permitted to read this course"},"404":{"description":"Caption track not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/stream/block/audio/{org_uuid}/{course_uuid}/{activity_uuid}/{block_uuid}/{filename}":{"get":{"tags":["stream"],"summary":"Stream an audio block file","description":"Streams an audio file attached to an audio block within an activity, with HTTP Range request support. Validates user read access to the parent course via RBAC.","operationId":"stream_block_audio_api_v1_stream_block_audio__org_uuid___course_uuid___activity_uuid___block_uuid___filename__get","parameters":[{"name":"org_uuid","in":"path","required":true,"schema":{"type":"string","description":"Organization UUID","title":"Org Uuid"},"description":"Organization UUID"},{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","description":"Course UUID","title":"Course Uuid"},"description":"Course UUID"},{"name":"activity_uuid","in":"path","required":true,"schema":{"type":"string","description":"Activity UUID","title":"Activity Uuid"},"description":"Activity UUID"},{"name":"block_uuid","in":"path","required":true,"schema":{"type":"string","description":"Block UUID","title":"Block Uuid"},"description":"Block UUID"},{"name":"filename","in":"path","required":true,"schema":{"type":"string","description":"Audio filename","title":"Filename"},"description":"Audio filename"}],"responses":{"200":{"description":"Full audio streamed successfully","content":{"application/json":{"schema":{}}}},"206":{"description":"Partial audio content returned for a Range request"},"403":{"description":"User is not permitted to read this course"},"404":{"description":"Activity, course, or audio file not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"head":{"tags":["stream"],"summary":"Get audio block file metadata","description":"Returns metadata for an audio block file without the body. Used by audio players to probe file size and MIME type before playback.","operationId":"head_block_audio_api_v1_stream_block_audio__org_uuid___course_uuid___activity_uuid___block_uuid___filename__head","parameters":[{"name":"org_uuid","in":"path","required":true,"schema":{"type":"string","description":"Organization UUID","title":"Org Uuid"},"description":"Organization UUID"},{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","description":"Course UUID","title":"Course Uuid"},"description":"Course UUID"},{"name":"activity_uuid","in":"path","required":true,"schema":{"type":"string","description":"Activity UUID","title":"Activity Uuid"},"description":"Activity UUID"},{"name":"block_uuid","in":"path","required":true,"schema":{"type":"string","description":"Block UUID","title":"Block Uuid"},"description":"Block UUID"},{"name":"filename","in":"path","required":true,"schema":{"type":"string","description":"Audio filename","title":"Filename"},"description":"Audio filename"}],"responses":{"200":{"description":"Audio metadata returned via response headers","content":{"application/json":{"schema":{}}}},"403":{"description":"User is not permitted to read this course"},"404":{"description":"Activity, course, or audio file not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/stream/block/{org_uuid}/{course_uuid}/{activity_uuid}/{block_uuid}/{filename}":{"get":{"tags":["stream"],"summary":"Stream a video block file","description":"Streams a video file attached to a video block within an activity, with HTTP Range request support. Validates user read access to the parent course via RBAC.","operationId":"stream_block_video_api_v1_stream_block__org_uuid___course_uuid___activity_uuid___block_uuid___filename__get","parameters":[{"name":"org_uuid","in":"path","required":true,"schema":{"type":"string","description":"Organization UUID","title":"Org Uuid"},"description":"Organization UUID"},{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","description":"Course UUID","title":"Course Uuid"},"description":"Course UUID"},{"name":"activity_uuid","in":"path","required":true,"schema":{"type":"string","description":"Activity UUID","title":"Activity Uuid"},"description":"Activity UUID"},{"name":"block_uuid","in":"path","required":true,"schema":{"type":"string","description":"Block UUID","title":"Block Uuid"},"description":"Block UUID"},{"name":"filename","in":"path","required":true,"schema":{"type":"string","description":"Video filename","title":"Filename"},"description":"Video filename"}],"responses":{"200":{"description":"Full video streamed successfully","content":{"application/json":{"schema":{}}}},"206":{"description":"Partial video content returned for a Range request"},"403":{"description":"User is not permitted to read this course"},"404":{"description":"Activity, course, or video file not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"head":{"tags":["stream"],"summary":"Get video block file metadata","description":"Returns metadata for a video block file without the body. Used by video players to probe file size and Range support before playback.","operationId":"head_block_video_api_v1_stream_block__org_uuid___course_uuid___activity_uuid___block_uuid___filename__head","parameters":[{"name":"org_uuid","in":"path","required":true,"schema":{"type":"string","description":"Organization UUID","title":"Org Uuid"},"description":"Organization UUID"},{"name":"course_uuid","in":"path","required":true,"schema":{"type":"string","description":"Course UUID","title":"Course Uuid"},"description":"Course UUID"},{"name":"activity_uuid","in":"path","required":true,"schema":{"type":"string","description":"Activity UUID","title":"Activity Uuid"},"description":"Activity UUID"},{"name":"block_uuid","in":"path","required":true,"schema":{"type":"string","description":"Block UUID","title":"Block Uuid"},"description":"Block UUID"},{"name":"filename","in":"path","required":true,"schema":{"type":"string","description":"Video filename","title":"Filename"},"description":"Video filename"}],"responses":{"200":{"description":"Video metadata returned via response headers","content":{"application/json":{"schema":{}}}},"403":{"description":"User is not permitted to read this course"},"404":{"description":"Activity, course, or video file not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/stream/audio/{org_uuid}/{podcast_uuid}/{episode_uuid}/{filename}":{"get":{"tags":["stream"],"summary":"Stream a podcast episode audio","description":"Streams a podcast episode audio file with HTTP Range request support. Validates user read access to the podcast via RBAC before serving the file.","operationId":"stream_podcast_audio_api_v1_stream_audio__org_uuid___podcast_uuid___episode_uuid___filename__get","parameters":[{"name":"org_uuid","in":"path","required":true,"schema":{"type":"string","description":"Organization UUID","title":"Org Uuid"},"description":"Organization UUID"},{"name":"podcast_uuid","in":"path","required":true,"schema":{"type":"string","description":"Podcast UUID","title":"Podcast Uuid"},"description":"Podcast UUID"},{"name":"episode_uuid","in":"path","required":true,"schema":{"type":"string","description":"Episode UUID","title":"Episode Uuid"},"description":"Episode UUID"},{"name":"filename","in":"path","required":true,"schema":{"type":"string","description":"Audio filename","title":"Filename"},"description":"Audio filename"}],"responses":{"200":{"description":"Full audio streamed successfully","content":{"application/json":{"schema":{}}}},"206":{"description":"Partial audio content returned for a Range request"},"403":{"description":"User is not permitted to read this podcast"},"404":{"description":"Podcast, episode, or audio file not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"head":{"tags":["stream"],"summary":"Get podcast audio metadata","description":"Returns metadata for a podcast episode audio file without the body. Used by audio players to probe file size and Range support before playback.","operationId":"head_podcast_audio_api_v1_stream_audio__org_uuid___podcast_uuid___episode_uuid___filename__head","parameters":[{"name":"org_uuid","in":"path","required":true,"schema":{"type":"string","description":"Organization UUID","title":"Org Uuid"},"description":"Organization UUID"},{"name":"podcast_uuid","in":"path","required":true,"schema":{"type":"string","description":"Podcast UUID","title":"Podcast Uuid"},"description":"Podcast UUID"},{"name":"episode_uuid","in":"path","required":true,"schema":{"type":"string","description":"Episode UUID","title":"Episode Uuid"},"description":"Episode UUID"},{"name":"filename","in":"path","required":true,"schema":{"type":"string","description":"Audio filename","title":"Filename"},"description":"Audio filename"}],"responses":{"200":{"description":"Audio metadata returned via response headers","content":{"application/json":{"schema":{}}}},"403":{"description":"User is not permitted to read this podcast"},"404":{"description":"Podcast, episode, or audio file not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/":{"get":{"summary":"Root","operationId":"root__get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}}},"components":{"schemas":{"AIAssignmentHistoryItem":{"properties":{"ai_generation_uuid":{"type":"string","title":"Ai Generation Uuid"},"session_uuid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Uuid"},"prompt":{"type":"string","title":"Prompt"},"plan":{"additionalProperties":true,"type":"object","title":"Plan"},"creation_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Creation Date"}},"type":"object","required":["ai_generation_uuid","prompt","plan"],"title":"AIAssignmentHistoryItem"},"AICreditsSummary":{"properties":{"plan":{"type":"string","title":"Plan"},"base_credits":{"anyOf":[{"type":"integer"},{"type":"string"}],"title":"Base Credits"},"purchased_credits":{"type":"integer","title":"Purchased Credits"},"total_credits":{"anyOf":[{"type":"integer"},{"type":"string"}],"title":"Total Credits"},"used_credits":{"type":"integer","title":"Used Credits"},"remaining_credits":{"anyOf":[{"type":"integer"},{"type":"string"}],"title":"Remaining Credits"},"mode":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mode"}},"type":"object","required":["plan","base_credits","purchased_credits","total_credits","used_credits","remaining_credits"],"title":"AICreditsSummary","description":"AI credits summary response."},"AIImageHistoryItem":{"properties":{"ai_generation_uuid":{"type":"string","title":"Ai Generation Uuid"},"session_uuid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Uuid"},"prompt":{"type":"string","title":"Prompt"},"file_id":{"type":"string","title":"File Id"},"media_url":{"type":"string","title":"Media Url"},"creation_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Creation Date"}},"type":"object","required":["ai_generation_uuid","prompt","file_id","media_url"],"title":"AIImageHistoryItem"},"AIOrgConfig":{"properties":{"enabled":{"type":"boolean","title":"Enabled","default":true},"limit":{"type":"integer","title":"Limit","default":10},"model":{"type":"string","title":"Model","default":""}},"type":"object","title":"AIOrgConfig"},"AIQuizHistoryItem":{"properties":{"ai_generation_uuid":{"type":"string","title":"Ai Generation Uuid"},"session_uuid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Uuid"},"prompt":{"type":"string","title":"Prompt"},"quiz":{"additionalProperties":true,"type":"object","title":"Quiz"},"creation_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Creation Date"}},"type":"object","required":["ai_generation_uuid","prompt","quiz"],"title":"AIQuizHistoryItem"},"AIScenarioHistoryItem":{"properties":{"ai_generation_uuid":{"type":"string","title":"Ai Generation Uuid"},"session_uuid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Uuid"},"prompt":{"type":"string","title":"Prompt"},"scenario":{"additionalProperties":true,"type":"object","title":"Scenario"},"creation_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Creation Date"}},"type":"object","required":["ai_generation_uuid","prompt","scenario"],"title":"AIScenarioHistoryItem"},"APIOrgConfig":{"properties":{"enabled":{"type":"boolean","title":"Enabled","default":true},"limit":{"type":"integer","title":"Limit","default":10}},"type":"object","title":"APIOrgConfig"},"APITokenCreate":{"properties":{"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"rights":{"anyOf":[{"$ref":"#/components/schemas/Rights"},{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Rights"},"expires_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expires At"}},"type":"object","required":["name"],"title":"APITokenCreate","description":"Model for creating a new API token"},"APITokenCreatedResponse":{"properties":{"token":{"type":"string","title":"Token"},"token_uuid":{"type":"string","title":"Token Uuid"},"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"token_prefix":{"type":"string","title":"Token Prefix"},"org_id":{"type":"integer","title":"Org Id"},"rights":{"anyOf":[{"$ref":"#/components/schemas/Rights"},{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Rights"},"created_by_user_id":{"type":"integer","title":"Created By User Id"},"creation_date":{"type":"string","title":"Creation Date"},"expires_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expires At"}},"type":"object","required":["token","token_uuid","name","token_prefix","org_id","created_by_user_id","creation_date"],"title":"APITokenCreatedResponse","description":"Response model when a new API token is created.\nThis is the ONLY time the full token is shown."},"APITokenRead":{"properties":{"id":{"type":"integer","title":"Id"},"token_uuid":{"type":"string","title":"Token Uuid"},"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"token_prefix":{"type":"string","title":"Token Prefix"},"org_id":{"type":"integer","title":"Org Id"},"rights":{"anyOf":[{"$ref":"#/components/schemas/Rights"},{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Rights"},"created_by_user_id":{"type":"integer","title":"Created By User Id"},"creation_date":{"type":"string","title":"Creation Date"},"update_date":{"type":"string","title":"Update Date"},"last_used_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Used At"},"expires_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expires At"},"is_active":{"type":"boolean","title":"Is Active"}},"type":"object","required":["id","token_uuid","name","token_prefix","org_id","created_by_user_id","creation_date","update_date","is_active"],"title":"APITokenRead","description":"Model for reading an API token (without sensitive data)"},"APITokenUpdate":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"rights":{"anyOf":[{"$ref":"#/components/schemas/Rights"},{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Rights"},"expires_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expires At"}},"type":"object","title":"APITokenUpdate","description":"Model for updating an API token"},"ActivatePackRequest":{"properties":{"pack_id":{"type":"string","title":"Pack Id"},"platform_subscription_id":{"type":"string","title":"Platform Subscription Id"}},"type":"object","required":["pack_id","platform_subscription_id"],"title":"ActivatePackRequest"},"ActivityAIChatSessionResponse":{"properties":{"aichat_uuid":{"type":"string","title":"Aichat Uuid"},"activity_uuid":{"type":"string","title":"Activity Uuid"},"message":{"type":"string","title":"Message"}},"type":"object","required":["aichat_uuid","activity_uuid","message"],"title":"ActivityAIChatSessionResponse"},"ActivityCompletionResponse":{"properties":{"activity_uuid":{"type":"string","title":"Activity Uuid"},"user_id":{"type":"integer","title":"User Id"},"completed":{"type":"boolean","title":"Completed"},"is_new_completion":{"type":"boolean","title":"Is New Completion","description":"True if this was a new completion (not already completed)"},"course_completed":{"type":"boolean","title":"Course Completed","description":"True if this completion finished the entire course"}},"type":"object","required":["activity_uuid","user_id","completed","is_new_completion","course_completed"],"title":"ActivityCompletionResponse","description":"Result of marking an activity as completed."},"ActivityCreate":{"properties":{"name":{"type":"string","title":"Name"},"activity_type":{"$ref":"#/components/schemas/ActivityTypeEnum","default":"TYPE_CUSTOM"},"activity_sub_type":{"$ref":"#/components/schemas/ActivitySubTypeEnum","default":"SUBTYPE_CUSTOM"},"content":{"additionalProperties":true,"type":"object","title":"Content"},"details":{"additionalProperties":true,"type":"object","title":"Details"},"published":{"type":"boolean","title":"Published","default":false},"lock_type":{"$ref":"#/components/schemas/ActivityLockType","default":"public"},"chapter_id":{"type":"integer","title":"Chapter Id"},"extra_metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Extra Metadata"}},"type":"object","required":["name","chapter_id"],"title":"ActivityCreate"},"ActivityLockType":{"type":"string","enum":["public","authenticated","restricted"],"title":"ActivityLockType"},"ActivityOrder":{"properties":{"activity_id":{"type":"integer","title":"Activity Id"}},"type":"object","required":["activity_id"],"title":"ActivityOrder"},"ActivityPlan":{"properties":{"name":{"type":"string","title":"Name"},"type":{"type":"string","title":"Type","default":"TYPE_DYNAMIC"},"description":{"type":"string","title":"Description"},"suggested_blocks":{"items":{"type":"string"},"type":"array","title":"Suggested Blocks","default":[]}},"type":"object","required":["name","description"],"title":"ActivityPlan","description":"Plan for a single activity within a chapter"},"ActivityRead":{"properties":{"name":{"type":"string","title":"Name"},"activity_type":{"$ref":"#/components/schemas/ActivityTypeEnum"},"activity_sub_type":{"$ref":"#/components/schemas/ActivitySubTypeEnum"},"content":{"additionalProperties":true,"type":"object","title":"Content"},"details":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Details"},"published":{"type":"boolean","title":"Published","default":false},"lock_type":{"$ref":"#/components/schemas/ActivityLockType","default":"public"},"id":{"type":"integer","title":"Id"},"org_id":{"type":"integer","title":"Org Id"},"course_id":{"type":"integer","title":"Course Id"},"activity_uuid":{"type":"string","title":"Activity Uuid"},"creation_date":{"type":"string","title":"Creation Date"},"update_date":{"type":"string","title":"Update Date"},"extra_metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Extra Metadata"},"current_version":{"type":"integer","title":"Current Version","default":1},"last_modified_by_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Last Modified By Id"},"last_modified_by_username":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Modified By Username"},"is_locked":{"type":"boolean","title":"Is Locked","default":false}},"type":"object","required":["name","activity_type","activity_sub_type","id","org_id","course_id","activity_uuid","creation_date","update_date"],"title":"ActivityRead"},"ActivityStateRead":{"properties":{"activity_uuid":{"type":"string","title":"Activity Uuid"},"update_date":{"type":"string","title":"Update Date"},"current_version":{"type":"integer","title":"Current Version"},"last_modified_by_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Last Modified By Id"},"last_modified_by_username":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Modified By Username"}},"type":"object","required":["activity_uuid","update_date","current_version"],"title":"ActivityStateRead","description":"Lightweight model for checking activity state for conflict detection.\nUsed to check if remote state has changed since user started editing."},"ActivitySubTypeEnum":{"type":"string","enum":["SUBTYPE_DYNAMIC_PAGE","SUBTYPE_DYNAMIC_MARKDOWN","SUBTYPE_DYNAMIC_EMBED","SUBTYPE_DYNAMIC_RESOURCE","SUBTYPE_VIDEO_YOUTUBE","SUBTYPE_VIDEO_HOSTED","SUBTYPE_DOCUMENT_PDF","SUBTYPE_DOCUMENT_DOC","SUBTYPE_ASSIGNMENT_ANY","SUBTYPE_CUSTOM","SUBTYPE_SCORM_12","SUBTYPE_SCORM_2004"],"title":"ActivitySubTypeEnum"},"ActivityTypeEnum":{"type":"string","enum":["TYPE_VIDEO","TYPE_DOCUMENT","TYPE_DYNAMIC","TYPE_ASSIGNMENT","TYPE_CUSTOM","TYPE_SCORM"],"title":"ActivityTypeEnum"},"ActivityUncompletionResponse":{"properties":{"activity_uuid":{"type":"string","title":"Activity Uuid"},"user_id":{"type":"integer","title":"User Id"},"completed":{"type":"boolean","title":"Completed","default":false}},"type":"object","required":["activity_uuid","user_id"],"title":"ActivityUncompletionResponse","description":"Result of removing an activity completion."},"ActivityUpdate":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"content":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Content"},"activity_type":{"anyOf":[{"$ref":"#/components/schemas/ActivityTypeEnum"},{"type":"null"}]},"activity_sub_type":{"anyOf":[{"$ref":"#/components/schemas/ActivitySubTypeEnum"},{"type":"null"}]},"details":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Details"},"published":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Published"},"lock_type":{"anyOf":[{"$ref":"#/components/schemas/ActivityLockType"},{"type":"null"}]},"extra_metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Extra Metadata"}},"type":"object","title":"ActivityUpdate"},"ActivityVersionRead":{"properties":{"content":{"additionalProperties":true,"type":"object","title":"Content"},"version_number":{"type":"integer","title":"Version Number"},"created_by_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Created By Id"},"id":{"type":"integer","title":"Id"},"activity_id":{"type":"integer","title":"Activity Id"},"org_id":{"type":"integer","title":"Org Id"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"created_by_username":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created By Username"},"created_by_avatar":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created By Avatar"}},"type":"object","required":["version_number","id","activity_id","org_id","created_at"],"title":"ActivityVersionRead","description":"Read model for activity versions"},"AddCreditsRequest":{"properties":{"amount":{"type":"integer","title":"Amount"}},"type":"object","required":["amount"],"title":"AddCreditsRequest","description":"Request body for adding AI credits."},"AddCreditsResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"new_purchased_total":{"type":"integer","title":"New Purchased Total"},"message":{"type":"string","title":"Message"}},"type":"object","required":["success","new_purchased_total","message"],"title":"AddCreditsResponse","description":"Response for adding AI credits."},"AdditionalFile":{"properties":{"name":{"type":"string","title":"Name"},"content":{"type":"string","title":"Content"}},"type":"object","required":["name","content"],"title":"AdditionalFile"},"AdminTogglesUpdateRequest":{"properties":{"toggles":{"additionalProperties":true,"type":"object","title":"Toggles"}},"type":"object","required":["toggles"],"title":"AdminTogglesUpdateRequest"},"AdminUserInfo":{"properties":{"username":{"type":"string","title":"Username"},"email":{"type":"string","title":"Email"},"avatar_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Avatar Image"},"user_uuid":{"type":"string","title":"User Uuid","default":""}},"type":"object","required":["username","email"],"title":"AdminUserInfo"},"AnalyticsOrgConfig":{"properties":{"enabled":{"type":"boolean","title":"Enabled","default":true},"limit":{"type":"integer","title":"Limit","default":10}},"type":"object","title":"AnalyticsOrgConfig"},"AnonymizeUserResponse":{"properties":{"detail":{"type":"string","title":"Detail"},"user_id":{"type":"integer","title":"User Id"},"anonymized_email":{"type":"string","title":"Anonymized Email"},"api_tokens_revoked":{"type":"integer","title":"Api Tokens Revoked"}},"type":"object","required":["detail","user_id","anonymized_email","api_tokens_revoked"],"title":"AnonymizeUserResponse"},"AssignmentCreate":{"properties":{"title":{"type":"string","title":"Title"},"description":{"type":"string","title":"Description"},"due_date":{"type":"string","title":"Due Date"},"published":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Published","default":false},"grading_type":{"$ref":"#/components/schemas/GradingTypeEnum"},"auto_grading":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Auto Grading","default":false},"anti_copy_paste":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Anti Copy Paste","default":false},"show_correct_answers":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Show Correct Answers","default":false},"allow_retries":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Allow Retries","default":false},"max_retries":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Retries","default":0},"org_id":{"type":"integer","title":"Org Id"},"course_id":{"type":"integer","title":"Course Id"},"chapter_id":{"type":"integer","title":"Chapter Id"},"activity_id":{"type":"integer","title":"Activity Id"}},"type":"object","required":["title","description","due_date","grading_type","org_id","course_id","chapter_id","activity_id"],"title":"AssignmentCreate","description":"Model for creating a new assignment."},"AssignmentOrgConfig":{"properties":{"enabled":{"type":"boolean","title":"Enabled","default":false},"limit":{"type":"integer","title":"Limit","default":10}},"type":"object","title":"AssignmentOrgConfig"},"AssignmentRead":{"properties":{"title":{"type":"string","title":"Title"},"description":{"type":"string","title":"Description"},"due_date":{"type":"string","title":"Due Date"},"published":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Published","default":false},"grading_type":{"$ref":"#/components/schemas/GradingTypeEnum"},"auto_grading":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Auto Grading","default":false},"anti_copy_paste":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Anti Copy Paste","default":false},"show_correct_answers":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Show Correct Answers","default":false},"allow_retries":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Allow Retries","default":false},"max_retries":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Retries","default":0},"org_id":{"type":"integer","title":"Org Id"},"course_id":{"type":"integer","title":"Course Id"},"chapter_id":{"type":"integer","title":"Chapter Id"},"activity_id":{"type":"integer","title":"Activity Id"},"id":{"type":"integer","title":"Id"},"assignment_uuid":{"type":"string","title":"Assignment Uuid"},"creation_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Creation Date"},"update_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Update Date"},"course_uuid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Course Uuid"},"activity_uuid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Activity Uuid"}},"type":"object","required":["title","description","due_date","grading_type","org_id","course_id","chapter_id","activity_id","id","assignment_uuid"],"title":"AssignmentRead","description":"Model for reading an assignment."},"AssignmentTaskCreate":{"properties":{"title":{"type":"string","title":"Title"},"description":{"type":"string","title":"Description"},"hint":{"type":"string","title":"Hint"},"reference_file":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reference File"},"assignment_type":{"$ref":"#/components/schemas/AssignmentTaskTypeEnum"},"contents":{"additionalProperties":true,"type":"object","title":"Contents"},"max_grade_value":{"type":"integer","title":"Max Grade Value","default":100}},"type":"object","required":["title","description","hint","assignment_type"],"title":"AssignmentTaskCreate","description":"Model for creating a new assignment task."},"AssignmentTaskSubmissionUpdate":{"properties":{"assignment_task_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Assignment Task Id"},"assignment_task_submission_uuid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Assignment Task Submission Uuid"},"task_submission":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Task Submission"},"grade":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Grade"},"task_submission_grade_feedback":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Task Submission Grade Feedback"},"manually_graded":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Manually Graded"},"assignment_type":{"anyOf":[{"$ref":"#/components/schemas/AssignmentTaskTypeEnum"},{"type":"null"}]}},"type":"object","title":"AssignmentTaskSubmissionUpdate","description":"Model for updating an assignment task submission."},"AssignmentTaskTypeEnum":{"type":"string","enum":["FILE_SUBMISSION","QUIZ","FORM","CODE","SHORT_ANSWER","NUMBER_ANSWER","CUSTOM","OTHER"],"title":"AssignmentTaskTypeEnum"},"AssignmentTaskUpdate":{"properties":{"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"hint":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Hint"},"assignment_type":{"anyOf":[{"$ref":"#/components/schemas/AssignmentTaskTypeEnum"},{"type":"null"}]},"contents":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Contents"},"max_grade_value":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Grade Value"}},"type":"object","title":"AssignmentTaskUpdate","description":"Model for updating an assignment task."},"AssignmentUpdate":{"properties":{"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"due_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Due Date"},"published":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Published"},"grading_type":{"anyOf":[{"$ref":"#/components/schemas/GradingTypeEnum"},{"type":"null"}]},"auto_grading":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Auto Grading"},"anti_copy_paste":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Anti Copy Paste"},"show_correct_answers":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Show Correct Answers"},"allow_retries":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Allow Retries"},"max_retries":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Retries"},"org_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Org Id"},"course_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Course Id"},"chapter_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Chapter Id"},"activity_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Activity Id"},"update_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Update Date"}},"type":"object","title":"AssignmentUpdate","description":"Model for updating an assignment."},"AssignmentUserSubmissionCreate":{"properties":{"assignment_id":{"type":"integer","title":"Assignment Id"},"submission_status":{"anyOf":[{"$ref":"#/components/schemas/AssignmentUserSubmissionStatus"},{"type":"null"}]},"grade":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Grade"},"user_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"User Id"}},"type":"object","required":["assignment_id"],"title":"AssignmentUserSubmissionCreate","description":"Model for creating/updating an assignment user submission.\n\nCarries the editable submission fields so the instructor update endpoint\ncan actually persist them. These are Optional because the update path only\napplies non-None values and strips the privileged ones for students."},"AssignmentUserSubmissionStatus":{"type":"string","enum":["PENDING","SUBMITTED","GRADED","LATE","NOT_SUBMITTED"],"title":"AssignmentUserSubmissionStatus"},"AttachmentData":{"properties":{"type":{"type":"string","enum":["image","video","file","youtube"],"title":"Type"},"name":{"type":"string","title":"Name"},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url"},"content_base64":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content Base64"},"mime_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mime Type"}},"type":"object","required":["type","name"],"title":"AttachmentData","description":"Attachment data sent with a message"},"AuditLogPaginated":{"properties":{"items":{"items":{"$ref":"#/components/schemas/AuditLogRead"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"limit":{"type":"integer","title":"Limit"},"offset":{"type":"integer","title":"Offset"}},"type":"object","required":["items","total","limit","offset"],"title":"AuditLogPaginated"},"AuditLogRead":{"properties":{"user_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"User Id"},"org_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Org Id"},"action":{"type":"string","title":"Action"},"resource":{"type":"string","title":"Resource"},"resource_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Resource Id"},"method":{"type":"string","title":"Method"},"path":{"type":"string","title":"Path"},"status_code":{"type":"integer","title":"Status Code"},"payload":{"anyOf":[{},{"type":"null"}],"title":"Payload"},"ip_address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ip Address"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"id":{"type":"integer","title":"Id"},"username":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Username"},"avatar_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Avatar Url"}},"type":"object","required":["action","resource","method","path","status_code","id"],"title":"AuditLogRead"},"AuthBrandingConfig":{"properties":{"welcome_message":{"type":"string","title":"Welcome Message","default":""},"background_type":{"type":"string","enum":["gradient","custom","unsplash"],"title":"Background Type","default":"gradient"},"background_image":{"type":"string","title":"Background Image","default":""},"text_color":{"type":"string","enum":["light","dark"],"title":"Text Color","default":"light"},"unsplash_photographer_name":{"type":"string","title":"Unsplash Photographer Name","default":""},"unsplash_photographer_url":{"type":"string","title":"Unsplash Photographer Url","default":""},"unsplash_photo_url":{"type":"string","title":"Unsplash Photo Url","default":""}},"type":"object","title":"AuthBrandingConfig"},"AuthorWithRole":{"properties":{"user":{"$ref":"#/components/schemas/UserRead"},"authorship":{"$ref":"#/components/schemas/ResourceAuthorshipEnum"},"authorship_status":{"$ref":"#/components/schemas/ResourceAuthorshipStatusEnum"},"creation_date":{"type":"string","title":"Creation Date"},"update_date":{"type":"string","title":"Update Date"}},"type":"object","required":["user","authorship","authorship_status","creation_date","update_date"],"title":"AuthorWithRole"},"AwardCertificateResponse":{"properties":{"user_certification_uuid":{"type":"string","title":"User Certification Uuid"},"user_id":{"type":"integer","title":"User Id"},"course_uuid":{"type":"string","title":"Course Uuid"}},"type":"object","required":["user_certification_uuid","user_id","course_uuid"],"title":"AwardCertificateResponse"},"BatchExportRequest":{"properties":{"course_uuids":{"items":{"type":"string"},"type":"array","title":"Course Uuids"}},"type":"object","required":["course_uuids"],"title":"BatchExportRequest","description":"Request model for batch course export.\n\nSECURITY: Limited to 20 courses per request to prevent resource exhaustion."},"BlockRead":{"properties":{"id":{"type":"integer","title":"Id"},"block_type":{"$ref":"#/components/schemas/BlockTypeEnum","default":"BLOCK_CUSTOM"},"content":{"additionalProperties":true,"type":"object","title":"Content"},"org_id":{"type":"integer","title":"Org Id"},"course_id":{"type":"integer","title":"Course Id"},"chapter_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Chapter Id"},"activity_id":{"type":"integer","title":"Activity Id"},"block_uuid":{"type":"string","title":"Block Uuid"},"creation_date":{"type":"string","title":"Creation Date"},"update_date":{"type":"string","title":"Update Date"}},"type":"object","required":["block_uuid","creation_date","update_date"],"title":"BlockRead"},"BlockTypeEnum":{"type":"string","enum":["BLOCK_QUIZ","BLOCK_VIDEO","BLOCK_DOCUMENT_PDF","BLOCK_IMAGE","BLOCK_AUDIO","BLOCK_CUSTOM"],"title":"BlockTypeEnum"},"BoardCreate":{"properties":{"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"thumbnail_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnail Image","default":""},"public":{"type":"boolean","title":"Public","default":false}},"type":"object","required":["name"],"title":"BoardCreate"},"BoardMemberBatchCreate":{"properties":{"members":{"items":{"$ref":"#/components/schemas/BoardMemberCreate"},"type":"array","title":"Members"}},"type":"object","required":["members"],"title":"BoardMemberBatchCreate"},"BoardMemberCreate":{"properties":{"user_id":{"type":"integer","title":"User Id"},"role":{"type":"string","title":"Role","default":"editor"}},"type":"object","required":["user_id"],"title":"BoardMemberCreate"},"BoardMemberRead":{"properties":{"id":{"type":"integer","title":"Id"},"board_id":{"type":"integer","title":"Board Id"},"user_id":{"type":"integer","title":"User Id"},"role":{"type":"string","title":"Role"},"creation_date":{"type":"string","title":"Creation Date"},"username":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Username"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"avatar_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Avatar Image"},"user_uuid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Uuid"}},"type":"object","required":["id","board_id","user_id","role","creation_date"],"title":"BoardMemberRead"},"BoardRead":{"properties":{"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"thumbnail_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnail Image","default":""},"public":{"type":"boolean","title":"Public","default":false},"id":{"type":"integer","title":"Id"},"org_id":{"type":"integer","title":"Org Id"},"board_uuid":{"type":"string","title":"Board Uuid"},"created_by":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Created By"},"creation_date":{"type":"string","title":"Creation Date"},"update_date":{"type":"string","title":"Update Date"},"member_count":{"type":"integer","title":"Member Count","default":0}},"type":"object","required":["name","id","org_id","board_uuid","creation_date","update_date"],"title":"BoardRead"},"BoardUpdate":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"thumbnail_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnail Image"},"public":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Public"}},"type":"object","title":"BoardUpdate"},"BoardsOrgConfig":{"properties":{"enabled":{"type":"boolean","title":"Enabled","default":false},"limit":{"type":"integer","title":"Limit","default":10}},"type":"object","title":"BoardsOrgConfig"},"BoardsPlaygroundContext":{"properties":{"board_name":{"type":"string","title":"Board Name"},"board_description":{"type":"string","title":"Board Description"}},"type":"object","required":["board_name","board_description"],"title":"BoardsPlaygroundContext"},"BoardsPlaygroundMessage":{"properties":{"role":{"type":"string","title":"Role"},"content":{"type":"string","title":"Content"}},"type":"object","required":["role","content"],"title":"BoardsPlaygroundMessage"},"BoardsPlaygroundSessionResponse":{"properties":{"session_uuid":{"type":"string","title":"Session Uuid"},"iteration_count":{"type":"integer","title":"Iteration Count"},"max_iterations":{"type":"integer","title":"Max Iterations"},"html_content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Html Content"},"message_history":{"items":{"$ref":"#/components/schemas/BoardsPlaygroundMessage"},"type":"array","title":"Message History"}},"type":"object","required":["session_uuid","iteration_count","max_iterations","html_content","message_history"],"title":"BoardsPlaygroundSessionResponse"},"Body_api_analyze_import_package_api_v1_courses_import_analyze_post":{"properties":{"zip_file":{"type":"string","contentMediaType":"application/octet-stream","title":"Zip File"}},"type":"object","required":["zip_file"],"title":"Body_api_analyze_import_package_api_v1_courses_import_analyze_post"},"Body_api_analyze_scorm_for_course_import_api_v1_scorm_analyze_for_import__org_id__post":{"properties":{"scorm_file":{"type":"string","contentMediaType":"application/octet-stream","title":"Scorm File"}},"type":"object","required":["scorm_file"],"title":"Body_api_analyze_scorm_for_course_import_api_v1_scorm_analyze_for_import__org_id__post"},"Body_api_analyze_scorm_package_api_v1_scorm_analyze__course_uuid__post":{"properties":{"scorm_file":{"type":"string","contentMediaType":"application/octet-stream","title":"Scorm File"}},"type":"object","required":["scorm_file"],"title":"Body_api_analyze_scorm_package_api_v1_scorm_analyze__course_uuid__post"},"Body_api_create_audio_file_block_api_v1_blocks_audio_post":{"properties":{"file_object":{"type":"string","contentMediaType":"application/octet-stream","title":"File Object"},"activity_uuid":{"type":"string","title":"Activity Uuid"}},"type":"object","required":["file_object","activity_uuid"],"title":"Body_api_create_audio_file_block_api_v1_blocks_audio_post"},"Body_api_create_course_api_v1_courses__post":{"properties":{"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"},"public":{"type":"boolean","title":"Public"},"learnings":{"type":"string","title":"Learnings"},"tags":{"type":"string","title":"Tags"},"about":{"type":"string","title":"About"},"thumbnail_type":{"$ref":"#/components/schemas/ThumbnailType","default":"image"},"extra_metadata":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Extra Metadata"},"thumbnail":{"anyOf":[{"type":"string","contentMediaType":"application/octet-stream"},{"type":"null"}],"title":"Thumbnail"}},"type":"object","required":["name","description","public","about"],"title":"Body_api_create_course_api_v1_courses__post"},"Body_api_create_course_thumbnail_api_v1_courses__course_uuid__thumbnail_put":{"properties":{"thumbnail_type":{"$ref":"#/components/schemas/ThumbnailType","default":"image"},"thumbnail":{"anyOf":[{"type":"string","contentMediaType":"application/octet-stream"},{"type":"null"}],"title":"Thumbnail"}},"type":"object","title":"Body_api_create_course_thumbnail_api_v1_courses__course_uuid__thumbnail_put"},"Body_api_create_documentpdf_activity_api_v1_activities_documentpdf_post":{"properties":{"name":{"type":"string","title":"Name"},"chapter_id":{"type":"integer","title":"Chapter Id"},"extra_metadata":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Extra Metadata"},"pdf_file":{"anyOf":[{"type":"string","contentMediaType":"application/octet-stream"},{"type":"null"}],"title":"Pdf File"}},"type":"object","required":["name","chapter_id"],"title":"Body_api_create_documentpdf_activity_api_v1_activities_documentpdf_post"},"Body_api_create_episode_api_v1_podcasts__podcast_uuid__episodes_post":{"properties":{"title":{"type":"string","title":"Title"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"duration_seconds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Duration Seconds","default":0},"published":{"type":"boolean","title":"Published","default":false},"audio":{"anyOf":[{"type":"string","contentMediaType":"application/octet-stream"},{"type":"null"}],"title":"Audio"},"thumbnail":{"anyOf":[{"type":"string","contentMediaType":"application/octet-stream"},{"type":"null"}],"title":"Thumbnail"}},"type":"object","required":["title"],"title":"Body_api_create_episode_api_v1_podcasts__podcast_uuid__episodes_post"},"Body_api_create_image_file_block_api_v1_blocks_image_post":{"properties":{"file_object":{"type":"string","contentMediaType":"application/octet-stream","title":"File Object"},"activity_uuid":{"type":"string","title":"Activity Uuid"}},"type":"object","required":["file_object","activity_uuid"],"title":"Body_api_create_image_file_block_api_v1_blocks_image_post"},"Body_api_create_media_api_v1_media__post":{"properties":{"org_id":{"type":"integer","title":"Org Id"},"name":{"type":"string","title":"Name"},"media_type":{"$ref":"#/components/schemas/MediaTypeEnum","default":"UPLOAD"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","default":""},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url","default":""},"public":{"type":"boolean","title":"Public","default":true},"folder_uuid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Folder Uuid"},"file":{"anyOf":[{"type":"string","contentMediaType":"application/octet-stream"},{"type":"null"}],"title":"File"}},"type":"object","required":["org_id","name"],"title":"Body_api_create_media_api_v1_media__post"},"Body_api_create_org_withconfig_api_v1_orgs_withconfig__post":{"properties":{"org_object":{"$ref":"#/components/schemas/OrganizationCreate"},"config_object":{"$ref":"#/components/schemas/OrganizationConfigBase"}},"type":"object","required":["org_object","config_object"],"title":"Body_api_create_org_withconfig_api_v1_orgs_withconfig__post"},"Body_api_create_pdf_file_block_api_v1_blocks_pdf_post":{"properties":{"file_object":{"type":"string","contentMediaType":"application/octet-stream","title":"File Object"},"activity_uuid":{"type":"string","title":"Activity Uuid"}},"type":"object","required":["file_object","activity_uuid"],"title":"Body_api_create_pdf_file_block_api_v1_blocks_pdf_post"},"Body_api_create_podcast_api_v1_podcasts__post":{"properties":{"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"about":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"About"},"tags":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tags"},"public":{"type":"boolean","title":"Public","default":false},"thumbnail":{"anyOf":[{"type":"string","contentMediaType":"application/octet-stream"},{"type":"null"}],"title":"Thumbnail"}},"type":"object","required":["name"],"title":"Body_api_create_podcast_api_v1_podcasts__post"},"Body_api_create_video_activity_api_v1_activities_video_post":{"properties":{"name":{"type":"string","title":"Name"},"chapter_id":{"type":"integer","title":"Chapter Id"},"details":{"type":"string","title":"Details","default":"{}"},"extra_metadata":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Extra Metadata"},"video_file":{"anyOf":[{"type":"string","contentMediaType":"application/octet-stream"},{"type":"null"}],"title":"Video File"}},"type":"object","required":["name","chapter_id"],"title":"Body_api_create_video_activity_api_v1_activities_video_post"},"Body_api_create_video_file_block_api_v1_blocks_video_post":{"properties":{"file_object":{"type":"string","contentMediaType":"application/octet-stream","title":"File Object"},"activity_uuid":{"type":"string","title":"Activity Uuid"}},"type":"object","required":["file_object","activity_uuid"],"title":"Body_api_create_video_file_block_api_v1_blocks_video_post"},"Body_api_put_assignment_task_ref_file_api_v1_assignments__assignment_uuid__tasks__assignment_task_uuid__ref_file_post":{"properties":{"reference_file":{"anyOf":[{"type":"string","contentMediaType":"application/octet-stream"},{"type":"null"}],"title":"Reference File"}},"type":"object","title":"Body_api_put_assignment_task_ref_file_api_v1_assignments__assignment_uuid__tasks__assignment_task_uuid__ref_file_post"},"Body_api_put_assignment_task_sub_file_api_v1_assignments__assignment_uuid__tasks__assignment_task_uuid__sub_file_post":{"properties":{"sub_file":{"anyOf":[{"type":"string","contentMediaType":"application/octet-stream"},{"type":"null"}],"title":"Sub File"}},"type":"object","title":"Body_api_put_assignment_task_sub_file_api_v1_assignments__assignment_uuid__tasks__assignment_task_uuid__sub_file_post"},"Body_api_update_avatar_user_api_v1_users_update_avatar__user_id__put":{"properties":{"avatar_file":{"anyOf":[{"type":"string","contentMediaType":"application/octet-stream"},{"type":"null"}],"title":"Avatar File"}},"type":"object","title":"Body_api_update_avatar_user_api_v1_users_update_avatar__user_id__put"},"Body_api_update_board_thumbnail_api_v1_boards__board_uuid__thumbnail_post":{"properties":{"thumbnail":{"type":"string","contentMediaType":"application/octet-stream","title":"Thumbnail"}},"type":"object","required":["thumbnail"],"title":"Body_api_update_board_thumbnail_api_v1_boards__board_uuid__thumbnail_post"},"Body_api_update_community_thumbnail_api_v1_communities__community_uuid__thumbnail_put":{"properties":{"thumbnail":{"anyOf":[{"type":"string","contentMediaType":"application/octet-stream"},{"type":"null"}],"title":"Thumbnail"}},"type":"object","title":"Body_api_update_community_thumbnail_api_v1_communities__community_uuid__thumbnail_put"},"Body_api_update_documentpdf_activity_api_v1_activities_documentpdf__activity_uuid__put":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"pdf_file":{"anyOf":[{"type":"string","contentMediaType":"application/octet-stream"},{"type":"null"}],"title":"Pdf File"}},"type":"object","title":"Body_api_update_documentpdf_activity_api_v1_activities_documentpdf__activity_uuid__put"},"Body_api_update_org_favicon_api_v1_orgs__org_id__favicon_put":{"properties":{"favicon_file":{"type":"string","contentMediaType":"application/octet-stream","title":"Favicon File"}},"type":"object","required":["favicon_file"],"title":"Body_api_update_org_favicon_api_v1_orgs__org_id__favicon_put"},"Body_api_update_org_logo_api_v1_orgs__org_id__logo_put":{"properties":{"logo_file":{"type":"string","contentMediaType":"application/octet-stream","title":"Logo File"}},"type":"object","required":["logo_file"],"title":"Body_api_update_org_logo_api_v1_orgs__org_id__logo_put"},"Body_api_update_org_preview_api_v1_orgs__org_id__preview_put":{"properties":{"preview_file":{"type":"string","contentMediaType":"application/octet-stream","title":"Preview File"}},"type":"object","required":["preview_file"],"title":"Body_api_update_org_preview_api_v1_orgs__org_id__preview_put"},"Body_api_update_org_thumbnail_api_v1_orgs__org_id__thumbnail_put":{"properties":{"thumbnail_file":{"type":"string","contentMediaType":"application/octet-stream","title":"Thumbnail File"}},"type":"object","required":["thumbnail_file"],"title":"Body_api_update_org_thumbnail_api_v1_orgs__org_id__thumbnail_put"},"Body_api_update_playground_thumbnail_api_v1_playgrounds__playground_uuid__thumbnail_post":{"properties":{"thumbnail":{"type":"string","contentMediaType":"application/octet-stream","title":"Thumbnail"}},"type":"object","required":["thumbnail"],"title":"Body_api_update_playground_thumbnail_api_v1_playgrounds__playground_uuid__thumbnail_post"},"Body_api_update_podcast_thumbnail_api_v1_podcasts__podcast_uuid__thumbnail_put":{"properties":{"thumbnail":{"type":"string","contentMediaType":"application/octet-stream","title":"Thumbnail"}},"type":"object","required":["thumbnail"],"title":"Body_api_update_podcast_thumbnail_api_v1_podcasts__podcast_uuid__thumbnail_put"},"Body_api_update_video_activity_api_v1_activities_video__activity_uuid__put":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"start_time":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Start Time"},"end_time":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"End Time"},"autoplay":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Autoplay"},"muted":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Muted"},"video_file":{"anyOf":[{"type":"string","contentMediaType":"application/octet-stream"},{"type":"null"}],"title":"Video File"}},"type":"object","title":"Body_api_update_video_activity_api_v1_activities_video__activity_uuid__put"},"Body_api_upload_episode_audio_api_v1_podcasts_episodes__episode_uuid__audio_put":{"properties":{"audio":{"type":"string","contentMediaType":"application/octet-stream","title":"Audio"}},"type":"object","required":["audio"],"title":"Body_api_upload_episode_audio_api_v1_podcasts_episodes__episode_uuid__audio_put"},"Body_api_upload_episode_thumbnail_api_v1_podcasts_episodes__episode_uuid__thumbnail_put":{"properties":{"thumbnail":{"type":"string","contentMediaType":"application/octet-stream","title":"Thumbnail"}},"type":"object","required":["thumbnail"],"title":"Body_api_upload_episode_thumbnail_api_v1_podcasts_episodes__episode_uuid__thumbnail_put"},"Body_api_upload_folder_thumbnail_api_v1_folders__folder_uuid__thumbnail_put":{"properties":{"thumbnail":{"type":"string","contentMediaType":"application/octet-stream","title":"Thumbnail"}},"type":"object","required":["thumbnail"],"title":"Body_api_upload_folder_thumbnail_api_v1_folders__folder_uuid__thumbnail_put"},"Body_api_upload_migration_files_api_v1_courses_migrate_upload_post":{"properties":{"files":{"items":{"type":"string","contentMediaType":"application/octet-stream"},"type":"array","title":"Files"}},"type":"object","required":["files"],"title":"Body_api_upload_migration_files_api_v1_courses_migrate_upload_post"},"Body_api_upload_org_auth_background_api_v1_orgs__org_id__auth_background_put":{"properties":{"background_file":{"type":"string","contentMediaType":"application/octet-stream","title":"Background File"}},"type":"object","required":["background_file"],"title":"Body_api_upload_org_auth_background_api_v1_orgs__org_id__auth_background_put"},"Body_api_upload_org_landing_content_api_v1_orgs__org_id__landing_content_post":{"properties":{"content_file":{"type":"string","contentMediaType":"application/octet-stream","title":"Content File"}},"type":"object","required":["content_file"],"title":"Body_api_upload_org_landing_content_api_v1_orgs__org_id__landing_content_post"},"Body_api_upload_org_og_image_api_v1_orgs__org_id__og_image_put":{"properties":{"og_image_file":{"type":"string","contentMediaType":"application/octet-stream","title":"Og Image File"}},"type":"object","required":["og_image_file"],"title":"Body_api_upload_org_og_image_api_v1_orgs__org_id__og_image_put"},"Body_login_api_v1_auth_login_post":{"properties":{"username":{"type":"string","title":"Username"},"password":{"type":"string","title":"Password"}},"type":"object","required":["username","password"],"title":"Body_login_api_v1_auth_login_post"},"Body_submit_feedback_api_v1_monitoring_feedback_post":{"properties":{"message":{"type":"string","title":"Message","default":""},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"associated_event_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Associated Event Id"},"attachments":{"items":{"type":"string","contentMediaType":"application/octet-stream"},"type":"array","title":"Attachments","default":[]}},"type":"object","title":"Body_submit_feedback_api_v1_monitoring_feedback_post"},"Body_upload_sqlite_db_api_v1_code_upload_sqlite_post":{"properties":{"file_object":{"type":"string","contentMediaType":"application/octet-stream","title":"File Object"},"activity_uuid":{"type":"string","title":"Activity Uuid"},"block_id":{"type":"string","title":"Block Id"},"org_uuid":{"type":"string","title":"Org Uuid"},"course_uuid":{"type":"string","title":"Course Uuid"}},"type":"object","required":["file_object","activity_uuid","block_id","org_uuid","course_uuid"],"title":"Body_upload_sqlite_db_api_v1_code_upload_sqlite_post"},"BulkEnrollRequest":{"properties":{"course_uuid":{"type":"string","title":"Course Uuid"},"user_ids":{"items":{"type":"integer"},"type":"array","maxItems":500,"title":"User Ids","description":"List of user ids to enroll (max 500)"}},"type":"object","required":["course_uuid","user_ids"],"title":"BulkEnrollRequest","description":"Request body for bulk enrolling users into a course."},"BulkEnrollResponse":{"properties":{"enrolled":{"items":{"type":"integer"},"type":"array","title":"Enrolled","description":"User ids that were newly enrolled"},"already_enrolled":{"items":{"type":"integer"},"type":"array","title":"Already Enrolled","description":"User ids that already had an enrollment"},"skipped":{"items":{"type":"integer"},"type":"array","title":"Skipped","description":"User ids that were not members of the org"}},"type":"object","required":["enrolled","already_enrolled","skipped"],"title":"BulkEnrollResponse"},"BulkUnenrollRequest":{"properties":{"course_uuid":{"type":"string","title":"Course Uuid"},"user_ids":{"items":{"type":"integer"},"type":"array","maxItems":500,"title":"User Ids"}},"type":"object","required":["course_uuid","user_ids"],"title":"BulkUnenrollRequest"},"BulkUnenrollResponse":{"properties":{"unenrolled":{"items":{"type":"integer"},"type":"array","title":"Unenrolled"},"not_enrolled":{"items":{"type":"integer"},"type":"array","title":"Not Enrolled"}},"type":"object","required":["unenrolled","not_enrolled"],"title":"BulkUnenrollResponse"},"CaptionLanguageIn":{"properties":{"code":{"type":"string","title":"Code"},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label"}},"type":"object","required":["code"],"title":"CaptionLanguageIn"},"CaptionsConfigIn":{"properties":{"enabled":{"type":"boolean","title":"Enabled","default":true},"source_language":{"type":"string","title":"Source Language","default":"auto"},"languages":{"items":{"$ref":"#/components/schemas/CaptionLanguageIn"},"type":"array","title":"Languages","default":[]}},"type":"object","title":"CaptionsConfigIn"},"CertificateCourseInfo":{"properties":{"id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Id"},"course_uuid":{"type":"string","title":"Course Uuid"},"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"thumbnail_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnail Image"}},"type":"object","required":["course_uuid","name"],"title":"CertificateCourseInfo"},"CertificateItem":{"properties":{"certificate_user":{"additionalProperties":true,"type":"object","title":"Certificate User"},"certification":{"additionalProperties":true,"type":"object","title":"Certification"},"course":{"$ref":"#/components/schemas/CertificateCourseInfo"}},"type":"object","required":["certificate_user","certification","course"],"title":"CertificateItem","description":"A user's certificate with certification and course info."},"CertificationCreate":{"properties":{"course_id":{"type":"integer","title":"Course Id"},"config":{"additionalProperties":true,"type":"object","title":"Config"}},"type":"object","required":["course_id"],"title":"CertificationCreate"},"CertificationRead":{"properties":{"id":{"type":"integer","title":"Id"},"certification_uuid":{"type":"string","title":"Certification Uuid"},"course_id":{"type":"integer","title":"Course Id"},"config":{"additionalProperties":true,"type":"object","title":"Config"},"creation_date":{"type":"string","title":"Creation Date"},"update_date":{"type":"string","title":"Update Date"}},"type":"object","required":["id","certification_uuid","course_id","config","creation_date","update_date"],"title":"CertificationRead"},"CertificationUpdate":{"properties":{"config":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Config"}},"type":"object","title":"CertificationUpdate"},"ChangeRoleRequest":{"properties":{"role_id":{"type":"integer","title":"Role Id","description":"Target role id"}},"type":"object","required":["role_id"],"title":"ChangeRoleRequest"},"ChangeRoleResponse":{"properties":{"user_id":{"type":"integer","title":"User Id"},"role_id":{"type":"integer","title":"Role Id"}},"type":"object","required":["user_id","role_id"],"title":"ChangeRoleResponse"},"ChapterCreate":{"properties":{"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","default":""},"thumbnail_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnail Image","default":""},"lock_type":{"$ref":"#/components/schemas/LockType","default":"public"},"org_id":{"type":"integer","title":"Org Id"},"course_id":{"type":"integer","title":"Course Id"},"extra_metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Extra Metadata"}},"type":"object","required":["name","org_id","course_id"],"title":"ChapterCreate"},"ChapterOrder":{"properties":{"chapter_id":{"type":"integer","title":"Chapter Id"},"activities_order_by_ids":{"items":{"$ref":"#/components/schemas/ActivityOrder"},"type":"array","title":"Activities Order By Ids"}},"type":"object","required":["chapter_id","activities_order_by_ids"],"title":"ChapterOrder"},"ChapterPlan":{"properties":{"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"},"activities":{"items":{"$ref":"#/components/schemas/ActivityPlan"},"type":"array","title":"Activities","default":[]}},"type":"object","required":["name","description"],"title":"ChapterPlan","description":"Plan for a single chapter within a course"},"ChapterRead":{"properties":{"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","default":""},"thumbnail_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnail Image","default":""},"lock_type":{"$ref":"#/components/schemas/LockType","default":"public"},"org_id":{"type":"integer","title":"Org Id"},"course_id":{"type":"integer","title":"Course Id"},"id":{"type":"integer","title":"Id"},"activities":{"items":{"$ref":"#/components/schemas/ActivityRead"},"type":"array","title":"Activities"},"chapter_uuid":{"type":"string","title":"Chapter Uuid"},"creation_date":{"type":"string","title":"Creation Date"},"update_date":{"type":"string","title":"Update Date"},"extra_metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Extra Metadata"},"is_locked":{"type":"boolean","title":"Is Locked","default":false}},"type":"object","required":["name","org_id","course_id","id","activities","chapter_uuid","creation_date","update_date"],"title":"ChapterRead"},"ChapterUpdate":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"thumbnail_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnail Image"},"lock_type":{"anyOf":[{"$ref":"#/components/schemas/LockType"},{"type":"null"}]},"extra_metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Extra Metadata"}},"type":"object","title":"ChapterUpdate"},"ChapterUpdateOrder":{"properties":{"chapter_order_by_ids":{"items":{"$ref":"#/components/schemas/ChapterOrder"},"type":"array","title":"Chapter Order By Ids"}},"type":"object","required":["chapter_order_by_ids"],"title":"ChapterUpdateOrder"},"CodeSubmissionRead":{"properties":{"id":{"type":"integer","title":"Id"},"submission_uuid":{"type":"string","title":"Submission Uuid"},"language_id":{"type":"integer","title":"Language Id"},"source_code":{"type":"string","title":"Source Code"},"results":{"additionalProperties":true,"type":"object","title":"Results"},"passed":{"type":"boolean","title":"Passed"},"total_tests":{"type":"integer","title":"Total Tests"},"passed_tests":{"type":"integer","title":"Passed Tests"},"execution_time_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Execution Time Ms"},"created_at":{"type":"string","title":"Created At"}},"type":"object","required":["id","submission_uuid","language_id","source_code","results","passed","total_tests","passed_tests","execution_time_ms","created_at"],"title":"CodeSubmissionRead"},"CollaborationOrgConfig":{"properties":{"enabled":{"type":"boolean","title":"Enabled","default":true},"limit":{"type":"integer","title":"Limit","default":10}},"type":"object","title":"CollaborationOrgConfig"},"CommentCreateRequest":{"properties":{"content":{"type":"string","title":"Content"}},"type":"object","required":["content"],"title":"CommentCreateRequest"},"CommunitiesOrgConfig":{"properties":{"enabled":{"type":"boolean","title":"Enabled","default":true}},"type":"object","title":"CommunitiesOrgConfig"},"CommunityCreateRequest":{"properties":{"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"public":{"type":"boolean","title":"Public","default":true},"course_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Course Id"}},"type":"object","required":["name"],"title":"CommunityCreateRequest"},"CommunityRead":{"properties":{"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"public":{"type":"boolean","title":"Public","default":true},"thumbnail_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnail Image","default":""},"id":{"type":"integer","title":"Id"},"org_id":{"type":"integer","title":"Org Id"},"course_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Course Id"},"community_uuid":{"type":"string","title":"Community Uuid"},"moderation_words":{"items":{"type":"string"},"type":"array","title":"Moderation Words","default":[]},"moderation_settings":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Moderation Settings"},"creation_date":{"type":"string","title":"Creation Date"},"update_date":{"type":"string","title":"Update Date"}},"type":"object","required":["name","id","community_uuid","creation_date","update_date"],"title":"CommunityRead"},"CommunityUpdate":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"public":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Public"},"moderation_words":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Moderation Words"},"moderation_settings":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Moderation Settings"}},"type":"object","title":"CommunityUpdate"},"CompletionStatusEnum":{"type":"string","enum":["not_attempted","incomplete","completed","passed","failed"],"title":"CompletionStatusEnum"},"CourseAccessResponse":{"properties":{"has_access":{"type":"boolean","title":"Has Access","description":"True if the user can access the course (public or enrolled)"},"is_enrolled":{"type":"boolean","title":"Is Enrolled","description":"True if the user is enrolled in the course"},"is_public":{"type":"boolean","title":"Is Public","description":"True if the course is public"},"is_published":{"type":"boolean","title":"Is Published","description":"True if the course is published"}},"type":"object","required":["has_access","is_enrolled","is_public","is_published"],"title":"CourseAccessResponse","description":"Whether a user can access a course."},"CourseAnalyticsResponse":{"properties":{"course_uuid":{"type":"string","title":"Course Uuid"},"enrollment_count":{"type":"integer","title":"Enrollment Count"},"completed_count":{"type":"integer","title":"Completed Count"},"in_progress_count":{"type":"integer","title":"In Progress Count"},"total_activities":{"type":"integer","title":"Total Activities"},"average_completion_percentage":{"type":"number","title":"Average Completion Percentage"},"certificate_count":{"type":"integer","title":"Certificate Count"}},"type":"object","required":["course_uuid","enrollment_count","completed_count","in_progress_count","total_activities","average_completion_percentage","certificate_count"],"title":"CourseAnalyticsResponse"},"CourseCompletionResponse":{"properties":{"course_uuid":{"type":"string","title":"Course Uuid"},"user_id":{"type":"integer","title":"User Id"},"completed_count":{"type":"integer","title":"Completed Count","description":"Number of newly completed activities"},"already_completed_count":{"type":"integer","title":"Already Completed Count","description":"Number of activities that were already completed"},"total_activities":{"type":"integer","title":"Total Activities"},"course_completed":{"type":"boolean","title":"Course Completed"},"certificate_awarded":{"type":"boolean","title":"Certificate Awarded","description":"True if a certificate was awarded as a result"}},"type":"object","required":["course_uuid","user_id","completed_count","already_completed_count","total_activities","course_completed","certificate_awarded"],"title":"CourseCompletionResponse","description":"Result of marking an entire course as completed."},"CourseEnrollmentItem":{"properties":{"user":{"additionalProperties":true,"type":"object","title":"User"},"enrolled_at":{"type":"string","title":"Enrolled At"},"status":{"type":"string","title":"Status"}},"type":"object","required":["user","enrolled_at","status"],"title":"CourseEnrollmentItem","description":"A single row in a course enrollment listing."},"CourseOrgConfig":{"properties":{"enabled":{"type":"boolean","title":"Enabled","default":true},"limit":{"type":"integer","title":"Limit","default":10}},"type":"object","title":"CourseOrgConfig"},"CoursePlan":{"properties":{"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"},"learnings":{"type":"string","title":"Learnings","default":""},"tags":{"type":"string","title":"Tags","default":""},"chapters":{"items":{"$ref":"#/components/schemas/ChapterPlan"},"type":"array","title":"Chapters","default":[]}},"type":"object","required":["name","description"],"title":"CoursePlan","description":"Complete course plan generated by AI"},"CoursePlanningMessage":{"properties":{"role":{"type":"string","title":"Role"},"content":{"type":"string","title":"Content"}},"type":"object","required":["role","content"],"title":"CoursePlanningMessage","description":"Single message in the conversation history"},"CoursePlanningSessionResponse":{"properties":{"session_uuid":{"type":"string","title":"Session Uuid"},"planning_iteration_count":{"type":"integer","title":"Planning Iteration Count"},"max_planning_iterations":{"type":"integer","title":"Max Planning Iterations"},"current_plan":{"anyOf":[{"$ref":"#/components/schemas/CoursePlan"},{"type":"null"}]},"message_history":{"items":{"$ref":"#/components/schemas/CoursePlanningMessage"},"type":"array","title":"Message History"},"course_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Course Id"}},"type":"object","required":["session_uuid","planning_iteration_count","max_planning_iterations","current_plan","message_history"],"title":"CoursePlanningSessionResponse","description":"Response when getting session state"},"CourseRead":{"properties":{"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"about":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"About"},"learnings":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Learnings"},"tags":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tags"},"thumbnail_type":{"anyOf":[{"$ref":"#/components/schemas/ThumbnailType"},{"type":"null"}],"default":"image"},"thumbnail_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnail Image","default":""},"thumbnail_video":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnail Video","default":""},"public":{"type":"boolean","title":"Public"},"published":{"type":"boolean","title":"Published","default":false},"open_to_contributors":{"type":"boolean","title":"Open To Contributors"},"id":{"type":"integer","title":"Id"},"org_id":{"type":"integer","title":"Org Id"},"authors":{"items":{"$ref":"#/components/schemas/AuthorWithRole"},"type":"array","title":"Authors"},"course_uuid":{"type":"string","title":"Course Uuid"},"creation_date":{"type":"string","title":"Creation Date"},"update_date":{"type":"string","title":"Update Date"},"seo":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Seo"},"extra_metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Extra Metadata"}},"type":"object","required":["name","public","open_to_contributors","id","authors","course_uuid","creation_date","update_date"],"title":"CourseRead"},"CourseUpdate":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"about":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"About"},"learnings":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Learnings"},"tags":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tags"},"thumbnail_type":{"anyOf":[{"$ref":"#/components/schemas/ThumbnailType"},{"type":"null"}]},"thumbnail_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnail Image"},"thumbnail_video":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnail Video"},"public":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Public"},"published":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Published"},"open_to_contributors":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Open To Contributors"},"seo":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Seo"},"extra_metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Extra Metadata"}},"type":"object","title":"CourseUpdate"},"CourseUpdateCreate":{"properties":{"title":{"type":"string","title":"Title"},"content":{"type":"string","title":"Content"},"linked_activity_uuids":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Linked Activity Uuids"},"org_id":{"type":"integer","title":"Org Id"}},"type":"object","required":["title","content","org_id"],"title":"CourseUpdateCreate"},"CourseUpdateRead":{"properties":{"id":{"type":"integer","title":"Id"},"title":{"type":"string","title":"Title"},"content":{"type":"string","title":"Content"},"course_id":{"type":"integer","title":"Course Id"},"courseupdate_uuid":{"type":"string","title":"Courseupdate Uuid"},"linked_activity_uuids":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Linked Activity Uuids"},"org_id":{"type":"integer","title":"Org Id"},"creation_date":{"type":"string","title":"Creation Date"},"update_date":{"type":"string","title":"Update Date"}},"type":"object","required":["id","title","content","course_id","courseupdate_uuid","org_id","creation_date","update_date"],"title":"CourseUpdateRead"},"CourseUpdateUpdate":{"properties":{"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content"},"linked_activity_uuids":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Linked Activity Uuids"}},"type":"object","title":"CourseUpdateUpdate"},"CreateFromMigrationRequest":{"properties":{"temp_id":{"type":"string","title":"Temp Id"},"structure":{"$ref":"#/components/schemas/MigrationTreeStructure"}},"type":"object","required":["temp_id","structure"],"title":"CreateFromMigrationRequest","description":"Request to create a course from the migration tree."},"CreateUserGroupRequest":{"properties":{"name":{"type":"string","minLength":1,"title":"Name"},"description":{"type":"string","title":"Description","default":""}},"type":"object","required":["name"],"title":"CreateUserGroupRequest"},"CustomDomainCreate":{"properties":{"domain":{"type":"string","title":"Domain"}},"type":"object","required":["domain"],"title":"CustomDomainCreate","description":"Model for creating a new Custom Domain"},"CustomDomainRead":{"properties":{"id":{"type":"integer","title":"Id"},"domain_uuid":{"type":"string","title":"Domain Uuid"},"domain":{"type":"string","title":"Domain"},"org_id":{"type":"integer","title":"Org Id"},"status":{"type":"string","title":"Status"},"primary":{"type":"boolean","title":"Primary"},"verification_token":{"type":"string","title":"Verification Token"},"creation_date":{"type":"string","title":"Creation Date"},"update_date":{"type":"string","title":"Update Date"},"verified_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Verified At"},"last_check_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Check At"},"check_error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Check Error"}},"type":"object","required":["id","domain_uuid","domain","org_id","status","primary","verification_token","creation_date","update_date"],"title":"CustomDomainRead","description":"Model for reading a Custom Domain"},"CustomDomainResolveResponse":{"properties":{"org_id":{"type":"integer","title":"Org Id"},"org_slug":{"type":"string","title":"Org Slug"},"org_uuid":{"type":"string","title":"Org Uuid"}},"type":"object","required":["org_id","org_slug","org_uuid"],"title":"CustomDomainResolveResponse","description":"Response model for domain resolution"},"CustomDomainVerificationInfo":{"properties":{"domain":{"type":"string","title":"Domain"},"status":{"type":"string","title":"Status"},"txt_record_host":{"type":"string","title":"Txt Record Host"},"txt_record_value":{"type":"string","title":"Txt Record Value"},"cname_record_host":{"type":"string","title":"Cname Record Host"},"cname_record_value":{"type":"string","title":"Cname Record Value"},"instructions":{"type":"string","title":"Instructions"}},"type":"object","required":["domain","status","txt_record_host","txt_record_value","cname_record_host","cname_record_value","instructions"],"title":"CustomDomainVerificationInfo","description":"Model containing DNS verification instructions"},"DashboardPermission":{"properties":{"action_access":{"type":"boolean","title":"Action Access"}},"type":"object","required":["action_access"],"title":"DashboardPermission"},"DeactivatePackRequest":{"properties":{"platform_subscription_id":{"type":"string","title":"Platform Subscription Id"}},"type":"object","required":["platform_subscription_id"],"title":"DeactivatePackRequest"},"DeleteUserGroupResponse":{"properties":{"detail":{"type":"string","title":"Detail"},"usergroup_uuid":{"type":"string","title":"Usergroup Uuid"}},"type":"object","required":["detail","usergroup_uuid"],"title":"DeleteUserGroupResponse"},"DiscussionCommentReadWithVoteStatus":{"properties":{"content":{"type":"string","title":"Content"},"id":{"type":"integer","title":"Id"},"discussion_id":{"type":"integer","title":"Discussion Id"},"author_id":{"type":"integer","title":"Author Id"},"comment_uuid":{"type":"string","title":"Comment Uuid"},"upvote_count":{"type":"integer","title":"Upvote Count","default":0},"creation_date":{"type":"string","title":"Creation Date"},"update_date":{"type":"string","title":"Update Date"},"author":{"anyOf":[{"$ref":"#/components/schemas/UserReadAuthor"},{"type":"null"}]},"has_voted":{"type":"boolean","title":"Has Voted","default":false}},"type":"object","required":["content","id","comment_uuid","creation_date","update_date"],"title":"DiscussionCommentReadWithVoteStatus"},"DiscussionCommentUpdate":{"properties":{"content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content"}},"type":"object","title":"DiscussionCommentUpdate"},"DiscussionCommentVoteRead":{"properties":{"id":{"type":"integer","title":"Id"},"comment_id":{"type":"integer","title":"Comment Id"},"user_id":{"type":"integer","title":"User Id"},"vote_uuid":{"type":"string","title":"Vote Uuid"},"creation_date":{"type":"string","title":"Creation Date"}},"type":"object","required":["id","vote_uuid","creation_date"],"title":"DiscussionCommentVoteRead"},"DiscussionCreateRequest":{"properties":{"title":{"type":"string","title":"Title"},"content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content"},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label","default":"general"},"emoji":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Emoji"}},"type":"object","required":["title"],"title":"DiscussionCreateRequest"},"DiscussionLabelInfo":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"color":{"type":"string","title":"Color"},"icon":{"type":"string","title":"Icon"}},"type":"object","required":["id","name","color","icon"],"title":"DiscussionLabelInfo"},"DiscussionLockUpdate":{"properties":{"is_locked":{"type":"boolean","title":"Is Locked"}},"type":"object","required":["is_locked"],"title":"DiscussionLockUpdate"},"DiscussionOrgConfig":{"properties":{"enabled":{"type":"boolean","title":"Enabled","default":true},"limit":{"type":"integer","title":"Limit","default":10}},"type":"object","title":"DiscussionOrgConfig"},"DiscussionPinUpdate":{"properties":{"is_pinned":{"type":"boolean","title":"Is Pinned"}},"type":"object","required":["is_pinned"],"title":"DiscussionPinUpdate"},"DiscussionReactionSummary":{"properties":{"emoji":{"type":"string","title":"Emoji"},"count":{"type":"integer","title":"Count"},"users":{"items":{"$ref":"#/components/schemas/src__db__communities__discussion_reactions__ReactionUser"},"type":"array","title":"Users"},"has_reacted":{"type":"boolean","title":"Has Reacted"}},"type":"object","required":["emoji","count","users","has_reacted"],"title":"DiscussionReactionSummary","description":"Summary of reactions for a single emoji."},"DiscussionReadWithVoteStatus":{"properties":{"id":{"type":"integer","title":"Id"},"title":{"type":"string","title":"Title"},"content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content"},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label","default":"general"},"emoji":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Emoji"},"community_id":{"type":"integer","title":"Community Id"},"org_id":{"type":"integer","title":"Org Id"},"author_id":{"type":"integer","title":"Author Id"},"discussion_uuid":{"type":"string","title":"Discussion Uuid"},"upvote_count":{"type":"integer","title":"Upvote Count"},"edit_count":{"type":"integer","title":"Edit Count","default":0},"is_pinned":{"type":"boolean","title":"Is Pinned","default":false},"is_locked":{"type":"boolean","title":"Is Locked","default":false},"creation_date":{"type":"string","title":"Creation Date"},"update_date":{"type":"string","title":"Update Date"},"author":{"anyOf":[{"$ref":"#/components/schemas/UserReadAuthor"},{"type":"null"}]},"has_voted":{"type":"boolean","title":"Has Voted","default":false}},"type":"object","required":["id","title","discussion_uuid","upvote_count","creation_date","update_date"],"title":"DiscussionReadWithVoteStatus"},"DiscussionSortBy":{"type":"string","enum":["recent","upvotes","hot"],"title":"DiscussionSortBy"},"DiscussionUpdate":{"properties":{"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content"},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label"},"emoji":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Emoji"}},"type":"object","title":"DiscussionUpdate"},"DiscussionVoteRead":{"properties":{"id":{"type":"integer","title":"Id"},"discussion_id":{"type":"integer","title":"Discussion Id"},"user_id":{"type":"integer","title":"User Id"},"vote_uuid":{"type":"string","title":"Vote Uuid"},"creation_date":{"type":"string","title":"Creation Date"}},"type":"object","required":["id","vote_uuid","creation_date"],"title":"DiscussionVoteRead"},"EditorBootstrapCourse":{"properties":{"course_uuid":{"type":"string","title":"Course Uuid"},"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"thumbnail_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnail Image"},"org_uuid":{"type":"string","title":"Org Uuid"},"org_id":{"type":"integer","title":"Org Id"}},"type":"object","required":["course_uuid","name","org_uuid","org_id"],"title":"EditorBootstrapCourse"},"EditorBootstrapResponse":{"properties":{"activity":{"$ref":"#/components/schemas/ActivityRead"},"course":{"$ref":"#/components/schemas/EditorBootstrapCourse"},"org":{"$ref":"#/components/schemas/OrganizationRead"}},"type":"object","required":["activity","course","org"],"title":"EditorBootstrapResponse"},"ExecuteBatchRequest":{"properties":{"language_id":{"type":"integer","title":"Language Id"},"source_code":{"type":"string","title":"Source Code"},"test_cases":{"items":{"$ref":"#/components/schemas/TestCase"},"type":"array","title":"Test Cases"},"sqlite_db_path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sqlite Db Path"},"additional_files":{"anyOf":[{"items":{"$ref":"#/components/schemas/AdditionalFile"},"type":"array"},{"type":"null"}],"title":"Additional Files"}},"type":"object","required":["language_id","source_code","test_cases"],"title":"ExecuteBatchRequest"},"ExecuteRequest":{"properties":{"language_id":{"type":"integer","title":"Language Id"},"source_code":{"type":"string","title":"Source Code"},"stdin":{"type":"string","title":"Stdin","default":""},"sqlite_db_path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sqlite Db Path"},"additional_files":{"anyOf":[{"items":{"$ref":"#/components/schemas/AdditionalFile"},"type":"array"},{"type":"null"}],"title":"Additional Files"}},"type":"object","required":["language_id","source_code"],"title":"ExecuteRequest"},"ExternalVideo":{"properties":{"name":{"type":"string","title":"Name"},"uri":{"type":"string","title":"Uri"},"type":{"type":"string","enum":["youtube","vimeo"],"title":"Type"},"chapter_id":{"type":"integer","title":"Chapter Id"},"details":{"type":"string","title":"Details","default":"{}"},"extra_metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Extra Metadata"}},"type":"object","required":["name","uri","type","chapter_id"],"title":"ExternalVideo"},"ExternalVideoUpdateBody":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"uri":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Uri"},"startTime":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Starttime"},"endTime":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Endtime"},"autoplay":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Autoplay"},"muted":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Muted"}},"type":"object","title":"ExternalVideoUpdateBody"},"FinalizeCoursePlanRequest":{"properties":{"session_uuid":{"type":"string","title":"Session Uuid"},"plan":{"$ref":"#/components/schemas/CoursePlan"}},"type":"object","required":["session_uuid","plan"],"title":"FinalizeCoursePlanRequest","description":"Request to finalize the plan and create course structure"},"FinalizeCoursePlanResponse":{"properties":{"course_uuid":{"type":"string","title":"Course Uuid"},"course_id":{"type":"integer","title":"Course Id"},"chapters":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Chapters"}},"type":"object","required":["course_uuid","course_id","chapters"],"title":"FinalizeCoursePlanResponse","description":"Response after finalizing the course plan"},"FolderBreadcrumb":{"properties":{"folder_uuid":{"type":"string","title":"Folder Uuid"},"name":{"type":"string","title":"Name"}},"type":"object","required":["folder_uuid","name"],"title":"FolderBreadcrumb"},"FolderContentItem":{"properties":{"resource_uuid":{"type":"string","title":"Resource Uuid"},"resource_type":{"type":"string","title":"Resource Type"},"position":{"type":"integer","title":"Position","default":0},"resource":{"additionalProperties":true,"type":"object","title":"Resource"}},"type":"object","required":["resource_uuid","resource_type","resource"],"title":"FolderContentItem","description":"A resolved leaf item inside a folder (any resource type)."},"FolderContentUpdateOrder":{"properties":{"resource_uuids":{"items":{"type":"string"},"type":"array","title":"Resource Uuids"}},"type":"object","required":["resource_uuids"],"title":"FolderContentUpdateOrder"},"FolderCreate":{"properties":{"name":{"type":"string","title":"Name"},"public":{"type":"boolean","title":"Public","default":true},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","default":""},"thumbnail_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnail Image","default":""},"color":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Color","default":"violet"},"org_id":{"type":"integer","title":"Org Id"},"parent_folder_uuid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Folder Uuid"}},"type":"object","required":["name"],"title":"FolderCreate"},"FolderOrder":{"properties":{"folder_id":{"type":"integer","title":"Folder Id"}},"type":"object","required":["folder_id"],"title":"FolderOrder"},"FolderRead":{"properties":{"name":{"type":"string","title":"Name"},"public":{"type":"boolean","title":"Public","default":true},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","default":""},"thumbnail_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnail Image","default":""},"color":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Color","default":"violet"},"id":{"type":"integer","title":"Id"},"org_id":{"type":"integer","title":"Org Id"},"folder_uuid":{"type":"string","title":"Folder Uuid"},"parent_folder_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Parent Folder Id"},"order":{"type":"integer","title":"Order","default":0},"creation_date":{"type":"string","title":"Creation Date"},"update_date":{"type":"string","title":"Update Date"},"total_items":{"type":"integer","title":"Total Items","default":0},"subfolders":{"items":{"$ref":"#/components/schemas/FolderRead"},"type":"array","title":"Subfolders","default":[]},"items":{"items":{"$ref":"#/components/schemas/FolderContentItem"},"type":"array","title":"Items","default":[]},"breadcrumbs":{"items":{"$ref":"#/components/schemas/FolderBreadcrumb"},"type":"array","title":"Breadcrumbs","default":[]}},"type":"object","required":["name","id","org_id","folder_uuid","creation_date","update_date"],"title":"FolderRead"},"FolderUpdate":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"public":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Public"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"thumbnail_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnail Image"},"color":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Color"},"parent_folder_uuid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Folder Uuid"}},"type":"object","title":"FolderUpdate"},"FolderUpdateOrder":{"properties":{"folder_order_by_ids":{"items":{"$ref":"#/components/schemas/FolderOrder"},"type":"array","title":"Folder Order By Ids"}},"type":"object","required":["folder_order_by_ids"],"title":"FolderUpdateOrder"},"FoldersOrgConfig":{"properties":{"enabled":{"type":"boolean","title":"Enabled","default":true},"sort_mode":{"type":"string","title":"Sort Mode","default":"name_asc"}},"type":"object","title":"FoldersOrgConfig"},"FrontendEvent":{"properties":{"event_name":{"type":"string","title":"Event Name"},"org_id":{"type":"integer","title":"Org Id"},"session_id":{"type":"string","title":"Session Id","default":""},"properties":{"additionalProperties":true,"type":"object","title":"Properties","default":{}}},"type":"object","required":["event_name","org_id"],"title":"FrontendEvent"},"FullCourseRead":{"properties":{"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"about":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"About"},"learnings":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Learnings"},"tags":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tags"},"thumbnail_type":{"anyOf":[{"$ref":"#/components/schemas/ThumbnailType"},{"type":"null"}],"default":"image"},"thumbnail_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnail Image","default":""},"thumbnail_video":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnail Video","default":""},"public":{"type":"boolean","title":"Public"},"published":{"type":"boolean","title":"Published","default":false},"open_to_contributors":{"type":"boolean","title":"Open To Contributors"},"id":{"type":"integer","title":"Id"},"org_id":{"type":"integer","title":"Org Id"},"org_uuid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Org Uuid"},"course_uuid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Course Uuid"},"creation_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Creation Date"},"update_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Update Date"},"seo":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Seo"},"extra_metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Extra Metadata"},"chapters":{"items":{"$ref":"#/components/schemas/ChapterRead"},"type":"array","title":"Chapters"},"authors":{"items":{"$ref":"#/components/schemas/AuthorWithRole"},"type":"array","title":"Authors"}},"type":"object","required":["name","public","open_to_contributors","id","org_id","chapters","authors"],"title":"FullCourseRead"},"GenerateActivityContentRequest":{"properties":{"session_uuid":{"type":"string","title":"Session Uuid"},"activity_uuid":{"type":"string","title":"Activity Uuid"},"activity_name":{"type":"string","title":"Activity Name"},"activity_description":{"type":"string","title":"Activity Description"},"chapter_name":{"type":"string","title":"Chapter Name"},"course_name":{"type":"string","title":"Course Name"},"course_description":{"type":"string","title":"Course Description"},"prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Prompt"}},"type":"object","required":["session_uuid","activity_uuid","activity_name","activity_description","chapter_name","course_name","course_description"],"title":"GenerateActivityContentRequest","description":"Request to generate content for a specific activity"},"GenerateAssignmentRequest":{"properties":{"org_id":{"type":"integer","title":"Org Id"},"course_uuid":{"type":"string","title":"Course Uuid"},"prompt":{"type":"string","title":"Prompt"},"session_uuid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Uuid"},"num_tasks":{"type":"integer","title":"Num Tasks","default":3},"allowed_task_types":{"anyOf":[{"items":{"type":"string","enum":["QUIZ","FORM","SHORT_ANSWER","NUMBER_ANSWER","FILE_SUBMISSION"]},"type":"array"},{"type":"null"}],"title":"Allowed Task Types"}},"type":"object","required":["org_id","course_uuid","prompt"],"title":"GenerateAssignmentRequest"},"GenerateAssignmentResponse":{"properties":{"ai_generation_uuid":{"type":"string","title":"Ai Generation Uuid"},"session_uuid":{"type":"string","title":"Session Uuid"},"plan":{"$ref":"#/components/schemas/GeneratedAssignmentPlan"}},"type":"object","required":["ai_generation_uuid","session_uuid","plan"],"title":"GenerateAssignmentResponse"},"GenerateAudioRequest":{"properties":{"activity_uuid":{"type":"string","title":"Activity Uuid"},"mode":{"type":"string","enum":["tts","podcast"],"title":"Mode","default":"tts"},"text":{"type":"string","title":"Text"},"voice":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Voice"},"speakers":{"anyOf":[{"items":{"$ref":"#/components/schemas/GenerateAudioSpeaker"},"type":"array"},{"type":"null"}],"title":"Speakers"},"style":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Style"},"language":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Language"}},"type":"object","required":["activity_uuid","text"],"title":"GenerateAudioRequest"},"GenerateAudioSpeaker":{"properties":{"name":{"type":"string","title":"Name"},"voice":{"type":"string","title":"Voice"}},"type":"object","required":["name","voice"],"title":"GenerateAudioSpeaker","description":"A named speaker bound to a prebuilt Gemini voice (podcast mode)."},"GenerateImageRequest":{"properties":{"org_id":{"type":"integer","title":"Org Id"},"prompt":{"type":"string","title":"Prompt"},"session_uuid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Uuid"},"source_file_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source File Id"},"source_image_base64":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Image Base64"},"course_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Course Id"},"activity_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Activity Id"}},"type":"object","required":["org_id","prompt"],"title":"GenerateImageRequest"},"GenerateImageResponse":{"properties":{"ai_generation_uuid":{"type":"string","title":"Ai Generation Uuid"},"session_uuid":{"type":"string","title":"Session Uuid"},"file_id":{"type":"string","title":"File Id"},"media_url":{"type":"string","title":"Media Url"},"prompt":{"type":"string","title":"Prompt"}},"type":"object","required":["ai_generation_uuid","session_uuid","file_id","media_url","prompt"],"title":"GenerateImageResponse"},"GenerateQuizRequest":{"properties":{"org_id":{"type":"integer","title":"Org Id"},"prompt":{"type":"string","title":"Prompt"},"activity_uuid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Activity Uuid"},"session_uuid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Uuid"},"num_questions":{"type":"integer","title":"Num Questions","default":5},"difficulty":{"anyOf":[{"type":"string","enum":["easy","medium","hard"]},{"type":"null"}],"title":"Difficulty"}},"type":"object","required":["org_id","prompt"],"title":"GenerateQuizRequest"},"GenerateQuizResponse":{"properties":{"ai_generation_uuid":{"type":"string","title":"Ai Generation Uuid"},"session_uuid":{"type":"string","title":"Session Uuid"},"quiz":{"additionalProperties":true,"type":"object","title":"Quiz"}},"type":"object","required":["ai_generation_uuid","session_uuid","quiz"],"title":"GenerateQuizResponse"},"GenerateScenarioRequest":{"properties":{"org_id":{"type":"integer","title":"Org Id"},"prompt":{"type":"string","title":"Prompt"},"activity_uuid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Activity Uuid"},"session_uuid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Uuid"},"num_scenarios":{"type":"integer","title":"Num Scenarios","default":5}},"type":"object","required":["org_id","prompt"],"title":"GenerateScenarioRequest"},"GenerateScenarioResponse":{"properties":{"ai_generation_uuid":{"type":"string","title":"Ai Generation Uuid"},"session_uuid":{"type":"string","title":"Session Uuid"},"scenario":{"additionalProperties":true,"type":"object","title":"Scenario"}},"type":"object","required":["ai_generation_uuid","session_uuid","scenario"],"title":"GenerateScenarioResponse"},"GenerateScriptRequest":{"properties":{"activity_uuid":{"type":"string","title":"Activity Uuid"},"mode":{"type":"string","enum":["podcast","speak"],"title":"Mode","default":"podcast"},"text":{"type":"string","title":"Text"},"speakers":{"anyOf":[{"items":{"$ref":"#/components/schemas/GenerateAudioSpeaker"},"type":"array"},{"type":"null"}],"title":"Speakers"},"style":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Style"},"language":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Language"},"minutes":{"type":"integer","maximum":60.0,"minimum":1.0,"title":"Minutes","default":2}},"type":"object","required":["activity_uuid","text"],"title":"GenerateScriptRequest"},"GenerateScriptResponse":{"properties":{"transcript":{"type":"string","title":"Transcript"}},"type":"object","required":["transcript"],"title":"GenerateScriptResponse"},"GeneratedAssignmentPlan":{"properties":{"title":{"type":"string","title":"Title"},"description":{"type":"string","title":"Description"},"grading_type":{"type":"string","title":"Grading Type"},"tasks":{"items":{"$ref":"#/components/schemas/GeneratedTask"},"type":"array","title":"Tasks"}},"type":"object","required":["title","description","grading_type"],"title":"GeneratedAssignmentPlan"},"GeneratedTask":{"properties":{"title":{"type":"string","title":"Title"},"description":{"type":"string","title":"Description"},"hint":{"type":"string","title":"Hint","default":""},"assignment_type":{"type":"string","title":"Assignment Type"},"contents":{"additionalProperties":true,"type":"object","title":"Contents"},"max_grade_value":{"type":"integer","title":"Max Grade Value","default":100}},"type":"object","required":["title","description","assignment_type","contents"],"title":"GeneratedTask","description":"A task ready to POST to /assignments/{uuid}/tasks (server assigns ids)."},"GradeSubmissionBody":{"properties":{"overall_feedback":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Overall Feedback"}},"type":"object","title":"GradeSubmissionBody","description":"Optional body for the final-grade endpoint. Lets the instructor leave\nan overall feedback note at the same time they finalize the grade."},"GradingTypeEnum":{"type":"string","enum":["ALPHABET","NUMERIC","PERCENTAGE","PASS_FAIL","GPA_SCALE"],"title":"GradingTypeEnum"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ImportAnalysisResponse":{"properties":{"temp_id":{"type":"string","title":"Temp Id"},"version":{"type":"string","title":"Version"},"courses":{"items":{"$ref":"#/components/schemas/ImportCourseInfo"},"type":"array","title":"Courses"}},"type":"object","required":["temp_id","version","courses"],"title":"ImportAnalysisResponse","description":"Response from analyzing an import package"},"ImportCourseInfo":{"properties":{"course_uuid":{"type":"string","title":"Course Uuid"},"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"chapters_count":{"type":"integer","title":"Chapters Count","default":0},"activities_count":{"type":"integer","title":"Activities Count","default":0},"has_thumbnail":{"type":"boolean","title":"Has Thumbnail","default":false}},"type":"object","required":["course_uuid","name"],"title":"ImportCourseInfo","description":"Information about a course found in an import package"},"ImportCourseResult":{"properties":{"original_uuid":{"type":"string","title":"Original Uuid"},"new_uuid":{"type":"string","title":"New Uuid"},"name":{"type":"string","title":"Name"},"success":{"type":"boolean","title":"Success"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"}},"type":"object","required":["original_uuid","new_uuid","name","success"],"title":"ImportCourseResult","description":"Result for a single course import"},"ImportRequest":{"properties":{"temp_id":{"type":"string","title":"Temp Id"},"course_uuids":{"items":{"type":"string"},"type":"array","title":"Course Uuids"},"name_prefix":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name Prefix"},"set_private":{"type":"boolean","title":"Set Private","default":true},"set_unpublished":{"type":"boolean","title":"Set Unpublished","default":true}},"type":"object","required":["temp_id","course_uuids"],"title":"ImportRequest","description":"Request model for course import.\n\nSECURITY: Limited to 20 courses per import request."},"ImportResult":{"properties":{"total_courses":{"type":"integer","title":"Total Courses"},"successful":{"type":"integer","title":"Successful"},"failed":{"type":"integer","title":"Failed"},"courses":{"items":{"$ref":"#/components/schemas/ImportCourseResult"},"type":"array","title":"Courses"}},"type":"object","required":["total_courses","successful","failed","courses"],"title":"ImportResult","description":"Result of importing courses"},"IssueTokenRequest":{"properties":{"user_id":{"type":"integer","title":"User Id","description":"ID of the user to issue a token for"}},"type":"object","required":["user_id"],"title":"IssueTokenRequest","description":"Request body for issuing a user token."},"JoinOrg":{"properties":{"org_id":{"type":"integer","title":"Org Id"},"user_id":{"anyOf":[{"type":"string"},{"type":"integer"}],"title":"User Id"},"invite_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Invite Code"}},"type":"object","required":["org_id","user_id"],"title":"JoinOrg"},"LockType":{"type":"string","enum":["public","authenticated","restricted"],"title":"LockType"},"MagicBlockContext":{"properties":{"course_title":{"type":"string","title":"Course Title"},"course_description":{"type":"string","title":"Course Description"},"activity_name":{"type":"string","title":"Activity Name"},"activity_content_summary":{"type":"string","title":"Activity Content Summary"}},"type":"object","required":["course_title","course_description","activity_name","activity_content_summary"],"title":"MagicBlockContext"},"MagicBlockMessage":{"properties":{"role":{"type":"string","title":"Role"},"content":{"type":"string","title":"Content"}},"type":"object","required":["role","content"],"title":"MagicBlockMessage"},"MagicBlockSessionResponse":{"properties":{"session_uuid":{"type":"string","title":"Session Uuid"},"iteration_count":{"type":"integer","title":"Iteration Count"},"max_iterations":{"type":"integer","title":"Max Iterations"},"html_content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Html Content"},"message_history":{"items":{"$ref":"#/components/schemas/MagicBlockMessage"},"type":"array","title":"Message History"}},"type":"object","required":["session_uuid","iteration_count","max_iterations","html_content","message_history"],"title":"MagicBlockSessionResponse"},"MagicLinkRequest":{"properties":{"user_id":{"type":"integer","title":"User Id"},"redirect_to":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Redirect To","description":"Path to redirect to after the user lands on the consume endpoint"},"ttl_seconds":{"type":"integer","maximum":900.0,"minimum":60.0,"title":"Ttl Seconds","description":"Token lifetime in seconds (60–900)","default":300}},"type":"object","required":["user_id"],"title":"MagicLinkRequest","description":"Request body for issuing a magic sign-in link."},"MagicLinkResponse":{"properties":{"url":{"type":"string","title":"Url","description":"Clickable URL to deliver to the user"},"token":{"type":"string","title":"Token","description":"Raw JWT (for integrations that prefer to build their own URL)"},"expires_at":{"type":"string","title":"Expires At","description":"ISO8601 timestamp when the token expires"}},"type":"object","required":["url","token","expires_at"],"title":"MagicLinkResponse"},"MarkCancelingRequest":{"properties":{"platform_subscription_id":{"type":"string","title":"Platform Subscription Id"}},"type":"object","required":["platform_subscription_id"],"title":"MarkCancelingRequest"},"MediaRead":{"properties":{"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","default":""},"media_type":{"$ref":"#/components/schemas/MediaTypeEnum","default":"UPLOAD"},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url","default":""},"thumbnail_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnail Image","default":""},"public":{"type":"boolean","title":"Public","default":true},"id":{"type":"integer","title":"Id"},"org_id":{"type":"integer","title":"Org Id"},"media_uuid":{"type":"string","title":"Media Uuid"},"file_format":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"File Format","default":""},"file_size":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"File Size"},"file_mime":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"File Mime","default":""},"creation_date":{"type":"string","title":"Creation Date"},"update_date":{"type":"string","title":"Update Date"}},"type":"object","required":["name","id","org_id","media_uuid","creation_date","update_date"],"title":"MediaRead"},"MediaTypeEnum":{"type":"string","enum":["UPLOAD","EMBED"],"title":"MediaTypeEnum","description":"Kind of media asset. Extensible — add new embeddable kinds here."},"MediaUpdate":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url"},"thumbnail_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnail Image"},"public":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Public"}},"type":"object","title":"MediaUpdate"},"MemberOrgConfig":{"properties":{"enabled":{"type":"boolean","title":"Enabled","default":true},"signup_mode":{"type":"string","enum":["open","inviteOnly"],"title":"Signup Mode","default":"open"},"admin_limit":{"type":"integer","title":"Admin Limit","default":1},"limit":{"type":"integer","title":"Limit","default":10}},"type":"object","title":"MemberOrgConfig"},"MigrationActivityNode":{"properties":{"name":{"type":"string","title":"Name"},"activity_type":{"type":"string","title":"Activity Type"},"activity_sub_type":{"type":"string","title":"Activity Sub Type"},"file_ids":{"items":{"type":"string"},"type":"array","title":"File Ids"}},"type":"object","required":["name","activity_type","activity_sub_type","file_ids"],"title":"MigrationActivityNode","description":"An activity in the proposed tree structure."},"MigrationChapterNode":{"properties":{"name":{"type":"string","title":"Name"},"activities":{"items":{"$ref":"#/components/schemas/MigrationActivityNode"},"type":"array","title":"Activities"}},"type":"object","required":["name","activities"],"title":"MigrationChapterNode","description":"A chapter in the proposed tree structure."},"MigrationCreateResult":{"properties":{"course_uuid":{"type":"string","title":"Course Uuid"},"course_name":{"type":"string","title":"Course Name"},"chapters_created":{"type":"integer","title":"Chapters Created"},"activities_created":{"type":"integer","title":"Activities Created"},"success":{"type":"boolean","title":"Success"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"}},"type":"object","required":["course_uuid","course_name","chapters_created","activities_created","success"],"title":"MigrationCreateResult","description":"Result of creating a course from migration."},"MigrationTreeStructure":{"properties":{"course_name":{"type":"string","title":"Course Name"},"course_description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Course Description"},"chapters":{"items":{"$ref":"#/components/schemas/MigrationChapterNode"},"type":"array","title":"Chapters"}},"type":"object","required":["course_name","chapters"],"title":"MigrationTreeStructure","description":"The full course tree structure (proposed by AI or built manually)."},"MigrationUploadResponse":{"properties":{"temp_id":{"type":"string","title":"Temp Id"},"files":{"items":{"$ref":"#/components/schemas/UploadedFileInfo"},"type":"array","title":"Files"},"skipped":{"items":{"type":"string"},"type":"array","title":"Skipped","default":[]}},"type":"object","required":["temp_id","files"],"title":"MigrationUploadResponse","description":"Response from bulk file upload."},"OfferPriceTypeEnum":{"type":"string","enum":["customer_choice","fixed_price"],"title":"OfferPriceTypeEnum"},"OfferTypeEnum":{"type":"string","enum":["subscription","one_time"],"title":"OfferTypeEnum"},"OrgCloudConfig":{"properties":{"plan":{"type":"string","enum":["free","personal","personal-family","standard","pro","enterprise","oss"],"title":"Plan","default":"free"},"custom_domain":{"type":"boolean","title":"Custom Domain","default":false}},"type":"object","title":"OrgCloudConfig"},"OrgConfigUpdateBody":{"properties":{"config":{"additionalProperties":true,"type":"object","title":"Config"}},"type":"object","required":["config"],"title":"OrgConfigUpdateBody"},"OrgConfigUpdateRequest":{"properties":{"config":{"additionalProperties":true,"type":"object","title":"Config"}},"type":"object","required":["config"],"title":"OrgConfigUpdateRequest"},"OrgCreateRequest":{"properties":{"name":{"type":"string","title":"Name"},"slug":{"type":"string","title":"Slug"},"email":{"type":"string","title":"Email"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"plan":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plan"}},"type":"object","required":["name","slug","email"],"title":"OrgCreateRequest"},"OrgDetailResponse":{"properties":{"id":{"type":"integer","title":"Id"},"org_uuid":{"type":"string","title":"Org Uuid"},"name":{"type":"string","title":"Name"},"slug":{"type":"string","title":"Slug"},"email":{"type":"string","title":"Email"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"about":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"About"},"logo_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Logo Image"},"thumbnail_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnail Image"},"creation_date":{"type":"string","title":"Creation Date"},"update_date":{"type":"string","title":"Update Date"},"user_count":{"type":"integer","title":"User Count","default":0},"course_count":{"type":"integer","title":"Course Count","default":0},"plan":{"type":"string","title":"Plan","default":"free"},"custom_domains":{"items":{"type":"string"},"type":"array","title":"Custom Domains","default":[]},"admin_users":{"items":{"$ref":"#/components/schemas/AdminUserInfo"},"type":"array","title":"Admin Users","default":[]},"config":{"additionalProperties":true,"type":"object","title":"Config","default":{}}},"type":"object","required":["id","org_uuid","name","slug","email","creation_date","update_date"],"title":"OrgDetailResponse"},"OrgFeatureConfig":{"properties":{"courses":{"$ref":"#/components/schemas/CourseOrgConfig","default":{"enabled":true,"limit":10}},"members":{"$ref":"#/components/schemas/MemberOrgConfig","default":{"enabled":true,"signup_mode":"open","admin_limit":1,"limit":10}},"usergroups":{"$ref":"#/components/schemas/UserGroupOrgConfig","default":{"enabled":true,"limit":10}},"storage":{"$ref":"#/components/schemas/StorageOrgConfig","default":{"enabled":true,"limit":10}},"ai":{"$ref":"#/components/schemas/AIOrgConfig","default":{"enabled":true,"limit":10,"model":""}},"assignments":{"$ref":"#/components/schemas/AssignmentOrgConfig","default":{"enabled":false,"limit":10}},"payments":{"$ref":"#/components/schemas/PaymentOrgConfig","default":{"enabled":false}},"discussions":{"$ref":"#/components/schemas/DiscussionOrgConfig","default":{"enabled":true,"limit":10}},"communities":{"$ref":"#/components/schemas/CommunitiesOrgConfig","default":{"enabled":true}},"folders":{"$ref":"#/components/schemas/FoldersOrgConfig","default":{"enabled":true,"sort_mode":"name_asc"}},"analytics":{"$ref":"#/components/schemas/AnalyticsOrgConfig","default":{"enabled":true,"limit":10}},"collaboration":{"$ref":"#/components/schemas/CollaborationOrgConfig","default":{"enabled":true,"limit":10}},"api":{"$ref":"#/components/schemas/APIOrgConfig","default":{"enabled":true,"limit":10}},"podcasts":{"$ref":"#/components/schemas/PodcastsOrgConfig","default":{"enabled":false,"limit":10}},"boards":{"$ref":"#/components/schemas/BoardsOrgConfig","default":{"enabled":false,"limit":10}},"playgrounds":{"$ref":"#/components/schemas/PlaygroundsOrgConfig","default":{"enabled":false,"limit":10}}},"type":"object","title":"OrgFeatureConfig"},"OrgGeneralConfig":{"properties":{"enabled":{"type":"boolean","title":"Enabled","default":true},"color":{"type":"string","title":"Color","default":""},"footer_text":{"type":"string","title":"Footer Text","default":""},"watermark":{"type":"boolean","title":"Watermark","default":true},"favicon_image":{"type":"string","title":"Favicon Image","default":""},"auth_branding":{"$ref":"#/components/schemas/AuthBrandingConfig","default":{"welcome_message":"","background_type":"gradient","background_image":"","text_color":"light","unsplash_photographer_name":"","unsplash_photographer_url":"","unsplash_photo_url":""}}},"type":"object","title":"OrgGeneralConfig"},"OrgPackRead":{"properties":{"id":{"type":"integer","title":"Id"},"org_id":{"type":"integer","title":"Org Id"},"pack_type":{"type":"string","title":"Pack Type"},"pack_id":{"type":"string","title":"Pack Id"},"quantity":{"type":"integer","title":"Quantity"},"status":{"type":"string","title":"Status"},"activated_at":{"type":"string","format":"date-time","title":"Activated At"},"cancelled_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Cancelled At"},"cancel_at_period_end":{"type":"boolean","title":"Cancel At Period End"},"platform_subscription_id":{"type":"string","title":"Platform Subscription Id"}},"type":"object","required":["id","org_id","pack_type","pack_id","quantity","status","activated_at","cancelled_at","cancel_at_period_end","platform_subscription_id"],"title":"OrgPackRead"},"OrgPacksResponse":{"properties":{"active_packs":{"items":{"$ref":"#/components/schemas/OrgPackRead"},"type":"array","title":"Active Packs"},"available_packs":{"items":{"$ref":"#/components/schemas/PackCatalogItem"},"type":"array","title":"Available Packs"}},"type":"object","required":["active_packs","available_packs"],"title":"OrgPacksResponse"},"OrgSettingsUpdateRequest":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Slug"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"}},"type":"object","title":"OrgSettingsUpdateRequest"},"OrganizationConfig":{"properties":{"id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Id"},"org_id":{"type":"integer","title":"Org Id"},"config":{"additionalProperties":true,"type":"object","title":"Config"},"creation_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Creation Date"},"update_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Update Date"}},"type":"object","required":["org_id"],"title":"OrganizationConfig"},"OrganizationConfigBase":{"properties":{"config_version":{"type":"string","title":"Config Version","default":"1.4"},"general":{"$ref":"#/components/schemas/OrgGeneralConfig"},"features":{"$ref":"#/components/schemas/OrgFeatureConfig"},"cloud":{"$ref":"#/components/schemas/OrgCloudConfig"},"landing":{"additionalProperties":true,"type":"object","title":"Landing"},"seo":{"$ref":"#/components/schemas/SeoOrgConfig","default":{"default_meta_title_suffix":"","default_meta_description":"","default_og_image":"","google_site_verification":"","twitter_handle":"","noindex_communities":false}}},"type":"object","required":["general","features","cloud"],"title":"OrganizationConfigBase"},"OrganizationCreate":{"properties":{"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"about":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"About"},"socials":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Socials"},"links":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Links"},"scripts":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Scripts"},"logo_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Logo Image"},"thumbnail_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnail Image"},"previews":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Previews"},"explore":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Explore","default":false},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label"},"slug":{"type":"string","title":"Slug"},"email":{"type":"string","title":"Email"}},"type":"object","required":["name","slug","email"],"title":"OrganizationCreate"},"OrganizationRead":{"properties":{"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"about":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"About"},"socials":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Socials"},"links":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Links"},"scripts":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Scripts"},"logo_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Logo Image"},"thumbnail_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnail Image"},"previews":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Previews"},"explore":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Explore","default":false},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label"},"slug":{"type":"string","title":"Slug"},"email":{"type":"string","title":"Email"},"id":{"type":"integer","title":"Id"},"org_uuid":{"type":"string","title":"Org Uuid"},"config":{"anyOf":[{"$ref":"#/components/schemas/OrganizationConfig"},{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Config"},"creation_date":{"type":"string","title":"Creation Date"},"update_date":{"type":"string","title":"Update Date"}},"type":"object","required":["name","slug","email","id","org_uuid","creation_date","update_date"],"title":"OrganizationRead"},"OrganizationUpdate":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"about":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"About"},"socials":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Socials"},"links":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Links"},"scripts":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Scripts"},"logo_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Logo Image"},"thumbnail_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnail Image"},"previews":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Previews"},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label"},"slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Slug"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"}},"type":"object","title":"OrganizationUpdate"},"PackCatalogItem":{"properties":{"pack_id":{"type":"string","title":"Pack Id"},"type":{"type":"string","title":"Type"},"quantity":{"type":"integer","title":"Quantity"},"label":{"type":"string","title":"Label"}},"type":"object","required":["pack_id","type","quantity","label"],"title":"PackCatalogItem"},"PackSummaryResponse":{"properties":{"ai_credits":{"type":"integer","title":"Ai Credits"},"member_seats":{"type":"integer","title":"Member Seats"},"active_pack_count":{"type":"integer","title":"Active Pack Count"}},"type":"object","required":["ai_credits","member_seats","active_pack_count"],"title":"PackSummaryResponse"},"PaginatedResponse":{"properties":{"items":{"items":{},"type":"array","title":"Items","default":[]},"total":{"type":"integer","title":"Total","default":0},"page":{"type":"integer","title":"Page","default":1},"limit":{"type":"integer","title":"Limit","default":20}},"type":"object","title":"PaginatedResponse"},"PaymentOrgConfig":{"properties":{"enabled":{"type":"boolean","title":"Enabled","default":false}},"type":"object","title":"PaymentOrgConfig"},"PaymentProviderEnum":{"type":"string","enum":["stripe"],"title":"PaymentProviderEnum"},"PaymentsConfig":{"properties":{"enabled":{"type":"boolean","title":"Enabled","default":true},"active":{"type":"boolean","title":"Active","default":false},"provider":{"$ref":"#/components/schemas/PaymentProviderEnum","default":"stripe"},"mode":{"$ref":"#/components/schemas/PaymentsModeEnum","default":"standard"},"provider_specific_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider Specific Id"},"provider_config":{"additionalProperties":true,"type":"object","title":"Provider Config"},"id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Id"},"org_id":{"type":"integer","title":"Org Id"},"creation_date":{"type":"string","format":"date-time","title":"Creation Date"},"update_date":{"type":"string","format":"date-time","title":"Update Date"}},"type":"object","required":["org_id"],"title":"PaymentsConfig"},"PaymentsConfigRead":{"properties":{"enabled":{"type":"boolean","title":"Enabled","default":true},"active":{"type":"boolean","title":"Active","default":false},"provider":{"$ref":"#/components/schemas/PaymentProviderEnum","default":"stripe"},"mode":{"$ref":"#/components/schemas/PaymentsModeEnum","default":"standard"},"provider_specific_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider Specific Id"},"provider_config":{"additionalProperties":true,"type":"object","title":"Provider Config"},"id":{"type":"integer","title":"Id"},"org_id":{"type":"integer","title":"Org Id"},"creation_date":{"type":"string","format":"date-time","title":"Creation Date"},"update_date":{"type":"string","format":"date-time","title":"Update Date"}},"type":"object","required":["id","org_id","creation_date","update_date"],"title":"PaymentsConfigRead"},"PaymentsGroupCreate":{"properties":{"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description","default":""}},"type":"object","required":["name"],"title":"PaymentsGroupCreate"},"PaymentsGroupRead":{"properties":{"id":{"type":"integer","title":"Id"},"org_id":{"type":"integer","title":"Org Id"},"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"},"creation_date":{"type":"string","format":"date-time","title":"Creation Date"},"update_date":{"type":"string","format":"date-time","title":"Update Date"}},"type":"object","required":["id","org_id","name","description","creation_date","update_date"],"title":"PaymentsGroupRead"},"PaymentsGroupUpdate":{"properties":{"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description","default":""}},"type":"object","required":["name"],"title":"PaymentsGroupUpdate"},"PaymentsModeEnum":{"type":"string","enum":["standard","express"],"title":"PaymentsModeEnum"},"PaymentsOfferCreate":{"properties":{"name":{"type":"string","title":"Name","default":""},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","default":""},"offer_type":{"$ref":"#/components/schemas/OfferTypeEnum","default":"one_time"},"price_type":{"$ref":"#/components/schemas/OfferPriceTypeEnum","default":"fixed_price"},"benefits":{"type":"string","title":"Benefits","default":""},"amount":{"type":"number","title":"Amount","default":0.0},"currency":{"type":"string","title":"Currency","default":"USD"},"is_publicly_listed":{"type":"boolean","title":"Is Publicly Listed","default":true},"payments_group_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Payments Group Id"},"resource_uuids":{"items":{"type":"string"},"type":"array","title":"Resource Uuids","default":[]}},"type":"object","title":"PaymentsOfferCreate"},"PaymentsOfferRead":{"properties":{"name":{"type":"string","title":"Name","default":""},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","default":""},"offer_type":{"$ref":"#/components/schemas/OfferTypeEnum","default":"one_time"},"price_type":{"$ref":"#/components/schemas/OfferPriceTypeEnum","default":"fixed_price"},"benefits":{"type":"string","title":"Benefits","default":""},"amount":{"type":"number","title":"Amount","default":0.0},"currency":{"type":"string","title":"Currency","default":"USD"},"is_publicly_listed":{"type":"boolean","title":"Is Publicly Listed","default":true},"id":{"type":"integer","title":"Id"},"offer_uuid":{"type":"string","title":"Offer Uuid"},"org_id":{"type":"integer","title":"Org Id"},"payments_config_id":{"type":"integer","title":"Payments Config Id"},"payments_group_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Payments Group Id"},"provider_product_id":{"type":"string","title":"Provider Product Id"},"creation_date":{"type":"string","format":"date-time","title":"Creation Date"},"update_date":{"type":"string","format":"date-time","title":"Update Date"}},"type":"object","required":["id","offer_uuid","org_id","payments_config_id","payments_group_id","provider_product_id","creation_date","update_date"],"title":"PaymentsOfferRead"},"PaymentsOfferUpdate":{"properties":{"name":{"type":"string","title":"Name","default":""},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","default":""},"offer_type":{"$ref":"#/components/schemas/OfferTypeEnum","default":"one_time"},"price_type":{"$ref":"#/components/schemas/OfferPriceTypeEnum","default":"fixed_price"},"benefits":{"type":"string","title":"Benefits","default":""},"amount":{"type":"number","title":"Amount","default":0.0},"currency":{"type":"string","title":"Currency","default":"USD"},"is_publicly_listed":{"type":"boolean","title":"Is Publicly Listed","default":true}},"type":"object","title":"PaymentsOfferUpdate"},"Permission":{"properties":{"action_create":{"type":"boolean","title":"Action Create"},"action_read":{"type":"boolean","title":"Action Read"},"action_update":{"type":"boolean","title":"Action Update"},"action_delete":{"type":"boolean","title":"Action Delete"}},"type":"object","required":["action_create","action_read","action_update","action_delete"],"title":"Permission"},"PermissionsWithOwn":{"properties":{"action_create":{"type":"boolean","title":"Action Create"},"action_read":{"type":"boolean","title":"Action Read"},"action_read_own":{"type":"boolean","title":"Action Read Own"},"action_update":{"type":"boolean","title":"Action Update"},"action_update_own":{"type":"boolean","title":"Action Update Own"},"action_delete":{"type":"boolean","title":"Action Delete"},"action_delete_own":{"type":"boolean","title":"Action Delete Own"}},"type":"object","required":["action_create","action_read","action_read_own","action_update","action_update_own","action_delete","action_delete_own"],"title":"PermissionsWithOwn"},"PlanUpdateRequest":{"properties":{"plan":{"type":"string","title":"Plan"}},"type":"object","required":["plan"],"title":"PlanUpdateRequest"},"PlatformResetPasswordRequest":{"properties":{"email":{"anyOf":[{"type":"string","format":"email"},{"type":"null"}],"title":"Email"},"new_password":{"type":"string","title":"New Password"},"reset_code":{"type":"string","title":"Reset Code"}},"type":"object","required":["new_password","reset_code"],"title":"PlatformResetPasswordRequest"},"PlaygroundAccessType":{"type":"string","enum":["public","authenticated","restricted"],"title":"PlaygroundAccessType"},"PlaygroundContext":{"properties":{"playground_name":{"type":"string","title":"Playground Name"},"playground_description":{"type":"string","title":"Playground Description"},"course_uuid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Course Uuid"},"course_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Course Name"}},"type":"object","required":["playground_name","playground_description"],"title":"PlaygroundContext"},"PlaygroundCreate":{"properties":{"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"thumbnail_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnail Image"},"access_type":{"$ref":"#/components/schemas/PlaygroundAccessType","default":"authenticated"},"course_uuid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Course Uuid"},"html_content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Html Content"}},"type":"object","required":["name"],"title":"PlaygroundCreate"},"PlaygroundMessage":{"properties":{"role":{"type":"string","title":"Role"},"content":{"type":"string","title":"Content"}},"type":"object","required":["role","content"],"title":"PlaygroundMessage"},"PlaygroundReactionSummary":{"properties":{"emoji":{"type":"string","title":"Emoji"},"count":{"type":"integer","title":"Count"},"users":{"items":{"$ref":"#/components/schemas/src__db__playground_reactions__ReactionUser"},"type":"array","title":"Users"},"has_reacted":{"type":"boolean","title":"Has Reacted"}},"type":"object","required":["emoji","count","users","has_reacted"],"title":"PlaygroundReactionSummary"},"PlaygroundRead":{"properties":{"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"thumbnail_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnail Image"},"access_type":{"$ref":"#/components/schemas/PlaygroundAccessType","default":"authenticated"},"published":{"type":"boolean","title":"Published","default":false},"course_uuid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Course Uuid"},"html_content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Html Content"},"id":{"type":"integer","title":"Id"},"org_id":{"type":"integer","title":"Org Id"},"org_uuid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Org Uuid"},"org_slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Org Slug"},"playground_uuid":{"type":"string","title":"Playground Uuid"},"course_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Course Id"},"created_by":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Created By"},"author_username":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Author Username"},"author_first_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Author First Name"},"author_last_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Author Last Name"},"author_user_uuid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Author User Uuid"},"author_avatar_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Author Avatar Image"},"creation_date":{"type":"string","title":"Creation Date"},"update_date":{"type":"string","title":"Update Date"}},"type":"object","required":["name","id","org_id","playground_uuid","creation_date","update_date"],"title":"PlaygroundRead"},"PlaygroundSessionResponse":{"properties":{"session_uuid":{"type":"string","title":"Session Uuid"},"iteration_count":{"type":"integer","title":"Iteration Count"},"max_iterations":{"type":"integer","title":"Max Iterations"},"html_content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Html Content"},"message_history":{"items":{"$ref":"#/components/schemas/PlaygroundMessage"},"type":"array","title":"Message History"}},"type":"object","required":["session_uuid","iteration_count","max_iterations","html_content","message_history"],"title":"PlaygroundSessionResponse"},"PlaygroundUpdate":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"thumbnail_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnail Image"},"access_type":{"anyOf":[{"$ref":"#/components/schemas/PlaygroundAccessType"},{"type":"null"}]},"published":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Published"},"course_uuid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Course Uuid"},"html_content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Html Content"}},"type":"object","title":"PlaygroundUpdate"},"PlaygroundsOrgConfig":{"properties":{"enabled":{"type":"boolean","title":"Enabled","default":false},"limit":{"type":"integer","title":"Limit","default":10}},"type":"object","title":"PlaygroundsOrgConfig"},"PodcastEpisodeRead":{"properties":{"title":{"type":"string","title":"Title"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"audio_file":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Audio File","default":""},"duration_seconds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Duration Seconds","default":0},"episode_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Episode Number","default":1},"thumbnail_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnail Image","default":""},"published":{"type":"boolean","title":"Published","default":false},"order":{"type":"integer","title":"Order","default":0},"id":{"type":"integer","title":"Id"},"podcast_id":{"type":"integer","title":"Podcast Id"},"org_id":{"type":"integer","title":"Org Id"},"episode_uuid":{"type":"string","title":"Episode Uuid"},"creation_date":{"type":"string","title":"Creation Date"},"update_date":{"type":"string","title":"Update Date"}},"type":"object","required":["title","id","episode_uuid","creation_date","update_date"],"title":"PodcastEpisodeRead"},"PodcastEpisodeUpdate":{"properties":{"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"audio_file":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Audio File"},"duration_seconds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Duration Seconds"},"episode_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Episode Number"},"thumbnail_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnail Image"},"published":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Published"},"order":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Order"}},"type":"object","title":"PodcastEpisodeUpdate"},"PodcastRead":{"properties":{"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"about":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"About"},"tags":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tags"},"thumbnail_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnail Image","default":""},"public":{"type":"boolean","title":"Public"},"published":{"type":"boolean","title":"Published","default":false},"id":{"type":"integer","title":"Id"},"org_id":{"type":"integer","title":"Org Id"},"authors":{"items":{"$ref":"#/components/schemas/AuthorWithRole"},"type":"array","title":"Authors"},"podcast_uuid":{"type":"string","title":"Podcast Uuid"},"creation_date":{"type":"string","title":"Creation Date"},"update_date":{"type":"string","title":"Update Date"},"seo":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Seo"}},"type":"object","required":["name","public","id","authors","podcast_uuid","creation_date","update_date"],"title":"PodcastRead"},"PodcastReadWithEpisodeCount":{"properties":{"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"about":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"About"},"tags":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tags"},"thumbnail_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnail Image","default":""},"public":{"type":"boolean","title":"Public"},"published":{"type":"boolean","title":"Published","default":false},"id":{"type":"integer","title":"Id"},"org_id":{"type":"integer","title":"Org Id"},"authors":{"items":{"$ref":"#/components/schemas/AuthorWithRole"},"type":"array","title":"Authors"},"podcast_uuid":{"type":"string","title":"Podcast Uuid"},"creation_date":{"type":"string","title":"Creation Date"},"update_date":{"type":"string","title":"Update Date"},"seo":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Seo"},"episode_count":{"type":"integer","title":"Episode Count","default":0}},"type":"object","required":["name","public","id","authors","podcast_uuid","creation_date","update_date"],"title":"PodcastReadWithEpisodeCount"},"PodcastUpdate":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"about":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"About"},"tags":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tags"},"thumbnail_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnail Image","default":""},"public":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Public"},"published":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Published"},"seo":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Seo"}},"type":"object","title":"PodcastUpdate"},"PodcastsOrgConfig":{"properties":{"enabled":{"type":"boolean","title":"Enabled","default":false},"limit":{"type":"integer","title":"Limit","default":10}},"type":"object","title":"PodcastsOrgConfig"},"ProgressResponse":{"properties":{"course_uuid":{"type":"string","title":"Course Uuid"},"user_id":{"type":"integer","title":"User Id"},"total_activities":{"type":"integer","title":"Total Activities","description":"Total number of activities in the course"},"completed_activities":{"type":"integer","title":"Completed Activities","description":"Number of activities the user has completed"},"completion_percentage":{"type":"number","title":"Completion Percentage","description":"Completion percentage (0-100)"},"completed_activity_ids":{"items":{"type":"integer"},"type":"array","title":"Completed Activity Ids","description":"IDs of completed activities"}},"type":"object","required":["course_uuid","user_id","total_activities","completed_activities","completion_percentage","completed_activity_ids"],"title":"ProgressResponse","description":"User's progress in a specific course."},"ProgressSummaryItem":{"properties":{"course_uuid":{"type":"string","title":"Course Uuid"},"course_name":{"type":"string","title":"Course Name"},"status":{"type":"string","title":"Status","description":"Enrollment status (STATUS_IN_PROGRESS, STATUS_COMPLETED, etc.)"},"total_activities":{"type":"integer","title":"Total Activities"},"completed_activities":{"type":"integer","title":"Completed Activities"},"completion_percentage":{"type":"number","title":"Completion Percentage"},"enrolled_at":{"type":"string","title":"Enrolled At"}},"type":"object","required":["course_uuid","course_name","status","total_activities","completed_activities","completion_percentage","enrolled_at"],"title":"ProgressSummaryItem","description":"Progress summary for a single course enrollment."},"ProvisionUserRequest":{"properties":{"email":{"type":"string","maxLength":320,"format":"email","title":"Email"},"username":{"type":"string","maxLength":150,"minLength":1,"title":"Username"},"first_name":{"type":"string","maxLength":150,"title":"First Name","default":""},"last_name":{"type":"string","maxLength":150,"title":"Last Name","default":""},"password":{"anyOf":[{"type":"string","maxLength":256},{"type":"null"}],"title":"Password","description":"Optional — if omitted, treated as SSO user with empty password"},"role_id":{"type":"integer","minimum":1.0,"title":"Role Id","description":"Role id for the org membership (default 4 = student)","default":4},"extra_metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Extra Metadata","description":"Optional arbitrary JSON metadata attached to the user for headless integrations"}},"type":"object","required":["email","username"],"title":"ProvisionUserRequest","description":"Request body for provisioning a new user."},"RAGChatRequest":{"properties":{"message":{"type":"string","title":"Message"},"course_uuid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Course Uuid"},"aichat_uuid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Aichat Uuid"},"mode":{"type":"string","enum":["course_only","general"],"title":"Mode","default":"course_only"},"org_slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Org Slug"}},"type":"object","required":["message"],"title":"RAGChatRequest"},"RAGIndexRequest":{"properties":{"course_uuid":{"type":"string","title":"Course Uuid"}},"type":"object","required":["course_uuid"],"title":"RAGIndexRequest"},"RAGIndexResponse":{"properties":{"status":{"type":"string","title":"Status"},"chunks_indexed":{"type":"integer","title":"Chunks Indexed"}},"type":"object","required":["status","chunks_indexed"],"title":"RAGIndexResponse"},"RAGSessionUpdateRequest":{"properties":{"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"favorite":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Favorite"}},"type":"object","title":"RAGSessionUpdateRequest"},"ReactionRequest":{"properties":{"emoji":{"type":"string","title":"Emoji"}},"type":"object","required":["emoji"],"title":"ReactionRequest"},"ReconcileAdminsResponse":{"properties":{"detail":{"type":"string","title":"Detail"},"admins_synced":{"type":"integer","title":"Admins Synced"}},"type":"object","required":["detail","admins_synced"],"title":"ReconcileAdminsResponse"},"RemoveUserResponse":{"properties":{"detail":{"type":"string","title":"Detail"}},"type":"object","required":["detail"],"title":"RemoveUserResponse"},"ResendVerificationRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"org_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Org Id"}},"type":"object","required":["email"],"title":"ResendVerificationRequest"},"ResetCreditsResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"message":{"type":"string","title":"Message"}},"type":"object","required":["success","message"],"title":"ResetCreditsResponse","description":"Response for resetting AI credits usage."},"ResetPasswordRequest":{"properties":{"email":{"anyOf":[{"type":"string","format":"email"},{"type":"null"}],"title":"Email"},"new_password":{"type":"string","title":"New Password"},"org_id":{"type":"integer","title":"Org Id"},"reset_code":{"type":"string","title":"Reset Code"}},"type":"object","required":["new_password","org_id","reset_code"],"title":"ResetPasswordRequest"},"ResetProgressResponse":{"properties":{"course_uuid":{"type":"string","title":"Course Uuid"},"user_id":{"type":"integer","title":"User Id"},"steps_deleted":{"type":"integer","title":"Steps Deleted"}},"type":"object","required":["course_uuid","user_id","steps_deleted"],"title":"ResetProgressResponse"},"ResourceAuthorshipEnum":{"type":"string","enum":["CREATOR","CONTRIBUTOR","MAINTAINER","REPORTER"],"title":"ResourceAuthorshipEnum"},"ResourceAuthorshipStatusEnum":{"type":"string","enum":["ACTIVE","PENDING","INACTIVE"],"title":"ResourceAuthorshipStatusEnum"},"RevokeCertificateResponse":{"properties":{"detail":{"type":"string","title":"Detail"},"user_certification_uuid":{"type":"string","title":"User Certification Uuid"}},"type":"object","required":["detail","user_certification_uuid"],"title":"RevokeCertificateResponse"},"Rights":{"properties":{"courses":{"$ref":"#/components/schemas/PermissionsWithOwn"},"users":{"$ref":"#/components/schemas/Permission"},"usergroups":{"$ref":"#/components/schemas/Permission"},"folders":{"$ref":"#/components/schemas/Permission","default":{"action_create":false,"action_read":true,"action_update":false,"action_delete":false}},"media":{"$ref":"#/components/schemas/Permission","default":{"action_create":false,"action_read":true,"action_update":false,"action_delete":false}},"organizations":{"$ref":"#/components/schemas/Permission"},"coursechapters":{"$ref":"#/components/schemas/Permission"},"activities":{"$ref":"#/components/schemas/Permission"},"assignments":{"$ref":"#/components/schemas/Permission","default":{"action_create":false,"action_read":false,"action_update":false,"action_delete":false}},"roles":{"$ref":"#/components/schemas/Permission"},"dashboard":{"$ref":"#/components/schemas/DashboardPermission"},"communities":{"$ref":"#/components/schemas/Permission"},"discussions":{"$ref":"#/components/schemas/PermissionsWithOwn"},"podcasts":{"$ref":"#/components/schemas/PermissionsWithOwn"},"boards":{"$ref":"#/components/schemas/PermissionsWithOwn","default":{"action_create":false,"action_read":true,"action_read_own":true,"action_update":false,"action_update_own":false,"action_delete":false,"action_delete_own":false}},"playgrounds":{"$ref":"#/components/schemas/PermissionsWithOwn","default":{"action_create":false,"action_read":true,"action_read_own":true,"action_update":false,"action_update_own":false,"action_delete":false,"action_delete_own":false}}},"type":"object","required":["courses","users","usergroups","organizations","coursechapters","activities","roles","dashboard","communities","discussions","podcasts"],"title":"Rights"},"RoleCreate":{"properties":{"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"rights":{"anyOf":[{"$ref":"#/components/schemas/Rights"},{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Rights"},"org_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Org Id"}},"type":"object","required":["name"],"title":"RoleCreate"},"RoleRead":{"properties":{"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"rights":{"anyOf":[{"$ref":"#/components/schemas/Rights"},{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Rights"},"id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Id"},"org_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Org Id"},"role_type":{"$ref":"#/components/schemas/RoleTypeEnum","default":"TYPE_GLOBAL"},"role_uuid":{"type":"string","title":"Role Uuid"},"creation_date":{"type":"string","title":"Creation Date"},"update_date":{"type":"string","title":"Update Date"}},"type":"object","required":["name","role_uuid","creation_date","update_date"],"title":"RoleRead"},"RoleTypeEnum":{"type":"string","enum":["TYPE_ORGANIZATION","TYPE_ORGANIZATION_API_TOKEN","TYPE_GLOBAL"],"title":"RoleTypeEnum"},"RoleUpdate":{"properties":{"role_id":{"type":"integer","title":"Role Id"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"rights":{"anyOf":[{"$ref":"#/components/schemas/Rights"},{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Rights"}},"type":"object","title":"RoleUpdate"},"SSOAuthorizationResponse":{"properties":{"authorization_url":{"type":"string","title":"Authorization Url"},"state":{"type":"string","title":"State"}},"type":"object","required":["authorization_url","state"],"title":"SSOAuthorizationResponse","description":"Response for SSO authorization initiation."},"SSOConnectionCreate":{"properties":{"provider":{"type":"string","title":"Provider"},"enabled":{"type":"boolean","title":"Enabled","default":false},"domains":{"items":{"type":"string"},"type":"array","title":"Domains","default":[]},"auto_provision_users":{"type":"boolean","title":"Auto Provision Users","default":true},"default_role_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Default Role Id"},"provider_config":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Provider Config"}},"type":"object","required":["provider"],"title":"SSOConnectionCreate","description":"Request model for creating SSO connection."},"SSOConnectionRead":{"properties":{"provider":{"type":"string","title":"Provider"},"enabled":{"type":"boolean","title":"Enabled","default":false},"domains":{"items":{"type":"string"},"type":"array","title":"Domains"},"auto_provision_users":{"type":"boolean","title":"Auto Provision Users","default":true},"provider_config":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Provider Config"},"id":{"type":"integer","title":"Id"},"org_id":{"type":"integer","title":"Org Id"},"default_role_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Default Role Id"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["provider","id","org_id","created_at","updated_at"],"title":"SSOConnectionRead","description":"Response model for SSO connection."},"SSOConnectionUpdate":{"properties":{"provider":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider"},"enabled":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Enabled"},"domains":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Domains"},"auto_provision_users":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Auto Provision Users"},"default_role_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Default Role Id"},"provider_config":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Provider Config"}},"type":"object","title":"SSOConnectionUpdate","description":"Request model for updating SSO connection."},"SSOLoginCheckResponse":{"properties":{"sso_enabled":{"type":"boolean","title":"Sso Enabled"},"provider":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider"}},"type":"object","required":["sso_enabled"],"title":"SSOLoginCheckResponse","description":"Response for checking if SSO is available for an organization."},"SSOProviderInfo":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"},"has_setup_portal":{"type":"boolean","title":"Has Setup Portal"},"available":{"type":"boolean","title":"Available"},"config_fields":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Config Fields"}},"type":"object","required":["id","name","description","has_setup_portal","available","config_fields"],"title":"SSOProviderInfo","description":"Information about an available SSO provider."},"SaveActivityContentRequest":{"properties":{"activity_uuid":{"type":"string","title":"Activity Uuid"},"content":{"additionalProperties":true,"type":"object","title":"Content"}},"type":"object","required":["activity_uuid","content"],"title":"SaveActivityContentRequest","description":"Request to save AI-generated content to an activity"},"SaveSubmissionRequest":{"properties":{"activity_uuid":{"type":"string","title":"Activity Uuid"},"block_id":{"type":"string","title":"Block Id"},"language_id":{"type":"integer","title":"Language Id"},"source_code":{"type":"string","title":"Source Code"},"results":{"additionalProperties":true,"type":"object","title":"Results"},"passed":{"type":"boolean","title":"Passed"},"total_tests":{"type":"integer","title":"Total Tests"},"passed_tests":{"type":"integer","title":"Passed Tests"},"execution_time_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Execution Time Ms"}},"type":"object","required":["activity_uuid","block_id","language_id","source_code","results","passed","total_tests","passed_tests"],"title":"SaveSubmissionRequest"},"ScormActivityResultRead":{"properties":{"user_id":{"type":"integer","title":"User Id"},"user_uuid":{"type":"string","title":"User Uuid"},"first_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"First Name"},"last_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Name"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"completion_status":{"$ref":"#/components/schemas/CompletionStatusEnum"},"success_status":{"$ref":"#/components/schemas/SuccessStatusEnum"},"score_raw":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Score Raw"},"score_scaled":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Score Scaled"},"total_time":{"type":"string","title":"Total Time"},"location":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Location"},"update_date":{"type":"string","title":"Update Date"}},"type":"object","required":["user_id","user_uuid","completion_status","success_status","total_time","update_date"],"title":"ScormActivityResultRead","description":"One learner's SCORM result for an activity (instructor reporting)."},"ScormAnalysisResponse":{"properties":{"temp_package_id":{"type":"string","title":"Temp Package Id"},"scorm_version":{"$ref":"#/components/schemas/ScormVersionEnum"},"package_title":{"type":"string","title":"Package Title"},"scos":{"items":{"$ref":"#/components/schemas/ScormScoInfo"},"type":"array","title":"Scos"},"file_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"File Count"},"total_size_bytes":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Total Size Bytes"},"largest_files":{"anyOf":[{"items":{"$ref":"#/components/schemas/ScormPackageFileInfo"},"type":"array"},{"type":"null"}],"title":"Largest Files"}},"type":"object","required":["temp_package_id","scorm_version","package_title","scos"],"title":"ScormAnalysisResponse","description":"Response from SCORM package analysis"},"ScormCourseImportRequest":{"properties":{"org_id":{"type":"integer","title":"Org Id"},"temp_package_id":{"type":"string","title":"Temp Package Id"},"course_name":{"type":"string","title":"Course Name"},"course_description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Course Description","default":""},"sco_assignments":{"items":{"$ref":"#/components/schemas/ScormCourseImportScoAssignment"},"type":"array","title":"Sco Assignments"}},"type":"object","required":["org_id","temp_package_id","course_name","sco_assignments"],"title":"ScormCourseImportRequest","description":"Request to import SCORM package as a new course"},"ScormCourseImportResponse":{"properties":{"course_uuid":{"type":"string","title":"Course Uuid"},"course_name":{"type":"string","title":"Course Name"},"activities_created":{"type":"integer","title":"Activities Created"}},"type":"object","required":["course_uuid","course_name","activities_created"],"title":"ScormCourseImportResponse","description":"Response from importing SCORM as a new course"},"ScormCourseImportScoAssignment":{"properties":{"sco_identifier":{"type":"string","title":"Sco Identifier"},"activity_name":{"type":"string","title":"Activity Name"},"chapter_name":{"type":"string","title":"Chapter Name"}},"type":"object","required":["sco_identifier","activity_name","chapter_name"],"title":"ScormCourseImportScoAssignment","description":"Assignment of a SCO for course import (with chapter name instead of ID)"},"ScormImportRequest":{"properties":{"temp_package_id":{"type":"string","title":"Temp Package Id"},"sco_assignments":{"items":{"$ref":"#/components/schemas/ScormScoAssignment"},"type":"array","title":"Sco Assignments"}},"type":"object","required":["temp_package_id","sco_assignments"],"title":"ScormImportRequest","description":"Request to import SCORM package with chapter assignments"},"ScormPackageFileInfo":{"properties":{"path":{"type":"string","title":"Path"},"size_bytes":{"type":"integer","title":"Size Bytes"}},"type":"object","required":["path","size_bytes"],"title":"ScormPackageFileInfo","description":"A file inside an analyzed SCORM package (for the analysis summary)"},"ScormRuntimeDataRead":{"properties":{"completion_status":{"$ref":"#/components/schemas/CompletionStatusEnum","default":"not_attempted"},"success_status":{"$ref":"#/components/schemas/SuccessStatusEnum","default":"unknown"},"score_raw":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Score Raw"},"score_min":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Score Min"},"score_max":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Score Max"},"score_scaled":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Score Scaled"},"total_time":{"type":"string","title":"Total Time","default":"PT0S"},"session_time":{"type":"string","title":"Session Time","default":"PT0S"},"location":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Location"},"suspend_data":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Suspend Data"},"cmi_data":{"additionalProperties":true,"type":"object","title":"Cmi Data"},"id":{"type":"integer","title":"Id"},"user_id":{"type":"integer","title":"User Id"},"activity_id":{"type":"integer","title":"Activity Id"},"org_id":{"type":"integer","title":"Org Id"},"runtime_uuid":{"type":"string","title":"Runtime Uuid"},"creation_date":{"type":"string","title":"Creation Date"},"update_date":{"type":"string","title":"Update Date"}},"type":"object","required":["id","user_id","activity_id","org_id","runtime_uuid","creation_date","update_date"],"title":"ScormRuntimeDataRead"},"ScormRuntimeDataUpdate":{"properties":{"completion_status":{"anyOf":[{"$ref":"#/components/schemas/CompletionStatusEnum"},{"type":"null"}]},"success_status":{"anyOf":[{"$ref":"#/components/schemas/SuccessStatusEnum"},{"type":"null"}]},"score_raw":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Score Raw"},"score_min":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Score Min"},"score_max":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Score Max"},"score_scaled":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Score Scaled"},"total_time":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Total Time"},"session_time":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Time"},"location":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Location"},"suspend_data":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Suspend Data"},"cmi_data":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Cmi Data"}},"type":"object","title":"ScormRuntimeDataUpdate"},"ScormScoAssignment":{"properties":{"sco_identifier":{"type":"string","title":"Sco Identifier"},"chapter_id":{"type":"integer","title":"Chapter Id"},"activity_name":{"type":"string","title":"Activity Name"}},"type":"object","required":["sco_identifier","chapter_id","activity_name"],"title":"ScormScoAssignment","description":"Assignment of a SCO to a chapter"},"ScormScoInfo":{"properties":{"identifier":{"type":"string","title":"Identifier"},"title":{"type":"string","title":"Title"},"launch_path":{"type":"string","title":"Launch Path"},"prerequisites":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Prerequisites"},"max_time_allowed":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Max Time Allowed"},"time_limit_action":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Time Limit Action"},"mastery_score":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mastery Score"}},"type":"object","required":["identifier","title","launch_path"],"title":"ScormScoInfo","description":"Information about a single SCO extracted from manifest"},"ScormVersionEnum":{"type":"string","enum":["SCORM_12","SCORM_2004"],"title":"ScormVersionEnum"},"SearchDiscussionRead":{"properties":{"id":{"type":"integer","title":"Id"},"title":{"type":"string","title":"Title"},"content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content"},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label","default":"general"},"emoji":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Emoji"},"community_id":{"type":"integer","title":"Community Id"},"org_id":{"type":"integer","title":"Org Id"},"author_id":{"type":"integer","title":"Author Id"},"discussion_uuid":{"type":"string","title":"Discussion Uuid"},"upvote_count":{"type":"integer","title":"Upvote Count"},"edit_count":{"type":"integer","title":"Edit Count","default":0},"is_pinned":{"type":"boolean","title":"Is Pinned","default":false},"is_locked":{"type":"boolean","title":"Is Locked","default":false},"creation_date":{"type":"string","title":"Creation Date"},"update_date":{"type":"string","title":"Update Date"},"community_uuid":{"type":"string","title":"Community Uuid","default":""}},"type":"object","required":["id","title","discussion_uuid","upvote_count","creation_date","update_date"],"title":"SearchDiscussionRead","description":"DiscussionRead plus the parent community UUID so the UI can deep-link\nto `/community/{uuid}/discussion/{uuid}` without another round trip."},"SearchResult":{"properties":{"courses":{"items":{"$ref":"#/components/schemas/CourseRead"},"type":"array","title":"Courses"},"folders":{"items":{"$ref":"#/components/schemas/FolderRead"},"type":"array","title":"Folders"},"users":{"items":{"$ref":"#/components/schemas/UserRead"},"type":"array","title":"Users"},"communities":{"items":{"$ref":"#/components/schemas/CommunityRead"},"type":"array","title":"Communities"},"discussions":{"items":{"$ref":"#/components/schemas/SearchDiscussionRead"},"type":"array","title":"Discussions"},"playgrounds":{"items":{"$ref":"#/components/schemas/PlaygroundRead"},"type":"array","title":"Playgrounds"},"podcasts":{"items":{"$ref":"#/components/schemas/PodcastRead"},"type":"array","title":"Podcasts"},"total_courses":{"type":"integer","title":"Total Courses","default":0},"total_folders":{"type":"integer","title":"Total Folders","default":0},"total_users":{"type":"integer","title":"Total Users","default":0},"total_communities":{"type":"integer","title":"Total Communities","default":0},"total_discussions":{"type":"integer","title":"Total Discussions","default":0},"total_playgrounds":{"type":"integer","title":"Total Playgrounds","default":0},"total_podcasts":{"type":"integer","title":"Total Podcasts","default":0}},"type":"object","required":["courses","folders","users","communities","discussions","playgrounds","podcasts"],"title":"SearchResult","description":"Paginated search result grouped by resource type.\n\nEach resource list is capped at `limit` per page; `total_*` holds the full\ncount for the whole query so the UI can show per-tab totals."},"SendActivityAIChatMessage":{"properties":{"aichat_uuid":{"type":"string","title":"Aichat Uuid"},"activity_uuid":{"type":"string","title":"Activity Uuid"},"message":{"type":"string","title":"Message"}},"type":"object","required":["aichat_uuid","activity_uuid","message"],"title":"SendActivityAIChatMessage"},"SendBoardsPlaygroundMessage":{"properties":{"session_uuid":{"type":"string","title":"Session Uuid"},"board_uuid":{"type":"string","title":"Board Uuid"},"block_uuid":{"type":"string","title":"Block Uuid"},"message":{"type":"string","title":"Message"},"current_html":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Current Html"}},"type":"object","required":["session_uuid","board_uuid","block_uuid","message"],"title":"SendBoardsPlaygroundMessage"},"SendCoursePlanningMessage":{"properties":{"session_uuid":{"type":"string","title":"Session Uuid"},"message":{"type":"string","title":"Message"},"current_plan":{"anyOf":[{"$ref":"#/components/schemas/CoursePlan"},{"type":"null"}]},"attachments":{"anyOf":[{"items":{"$ref":"#/components/schemas/AttachmentData"},"type":"array"},{"type":"null"}],"title":"Attachments"}},"type":"object","required":["session_uuid","message"],"title":"SendCoursePlanningMessage","description":"Request to continue planning with a new message"},"SendEditorAIChatMessage":{"properties":{"aichat_uuid":{"type":"string","title":"Aichat Uuid"},"activity_uuid":{"type":"string","title":"Activity Uuid"},"message":{"type":"string","title":"Message"},"current_content":{"title":"Current Content"},"selected_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Selected Text"},"cursor_position":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Cursor Position"}},"type":"object","required":["aichat_uuid","activity_uuid","message","current_content"],"title":"SendEditorAIChatMessage","description":"Request to send a message in an existing editor AI chat session"},"SendMagicBlockMessage":{"properties":{"session_uuid":{"type":"string","title":"Session Uuid"},"activity_uuid":{"type":"string","title":"Activity Uuid"},"block_uuid":{"type":"string","title":"Block Uuid"},"message":{"type":"string","title":"Message"},"current_html":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Current Html"}},"type":"object","required":["session_uuid","activity_uuid","block_uuid","message"],"title":"SendMagicBlockMessage"},"SendPlatformResetCodeRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"}},"type":"object","required":["email"],"title":"SendPlatformResetCodeRequest"},"SendPlaygroundMessage":{"properties":{"session_uuid":{"type":"string","title":"Session Uuid"},"playground_uuid":{"type":"string","title":"Playground Uuid"},"message":{"type":"string","title":"Message"},"current_html":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Current Html"}},"type":"object","required":["session_uuid","playground_uuid","message"],"title":"SendPlaygroundMessage"},"SendResetCodeRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"org_id":{"type":"integer","title":"Org Id"}},"type":"object","required":["email","org_id"],"title":"SendResetCodeRequest"},"SeoOrgConfig":{"properties":{"default_meta_title_suffix":{"type":"string","title":"Default Meta Title Suffix","default":""},"default_meta_description":{"type":"string","title":"Default Meta Description","default":""},"default_og_image":{"type":"string","title":"Default Og Image","default":""},"google_site_verification":{"type":"string","title":"Google Site Verification","default":""},"twitter_handle":{"type":"string","title":"Twitter Handle","default":""},"noindex_communities":{"type":"boolean","title":"Noindex Communities","default":false}},"type":"object","title":"SeoOrgConfig"},"SetCreditsRequest":{"properties":{"amount":{"type":"integer","title":"Amount"}},"type":"object","required":["amount"],"title":"SetCreditsRequest","description":"Request body for setting purchased AI credits to an absolute value."},"SetCreditsResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"purchased_total":{"type":"integer","title":"Purchased Total"},"message":{"type":"string","title":"Message"}},"type":"object","required":["success","purchased_total","message"],"title":"SetCreditsResponse","description":"Response for setting purchased AI credits."},"StartActivityAIChatSession":{"properties":{"activity_uuid":{"type":"string","title":"Activity Uuid"},"message":{"type":"string","title":"Message"}},"type":"object","required":["activity_uuid","message"],"title":"StartActivityAIChatSession"},"StartBoardsPlaygroundSession":{"properties":{"board_uuid":{"type":"string","title":"Board Uuid"},"block_uuid":{"type":"string","title":"Block Uuid"},"prompt":{"type":"string","title":"Prompt"},"context":{"$ref":"#/components/schemas/BoardsPlaygroundContext"}},"type":"object","required":["board_uuid","block_uuid","prompt","context"],"title":"StartBoardsPlaygroundSession"},"StartCoursePlanningSession":{"properties":{"org_id":{"type":"integer","title":"Org Id"},"prompt":{"type":"string","title":"Prompt"},"language":{"type":"string","title":"Language","default":"en"},"attachments":{"anyOf":[{"items":{"$ref":"#/components/schemas/AttachmentData"},"type":"array"},{"type":"null"}],"title":"Attachments"}},"type":"object","required":["org_id","prompt"],"title":"StartCoursePlanningSession","description":"Request to start a new course planning session"},"StartEditorAIChatSession":{"properties":{"activity_uuid":{"type":"string","title":"Activity Uuid"},"message":{"type":"string","title":"Message"},"current_content":{"title":"Current Content"},"selected_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Selected Text"},"cursor_position":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Cursor Position"}},"type":"object","required":["activity_uuid","message","current_content"],"title":"StartEditorAIChatSession","description":"Request to start a new AI editor chat session"},"StartMagicBlockSession":{"properties":{"activity_uuid":{"type":"string","title":"Activity Uuid"},"block_uuid":{"type":"string","title":"Block Uuid"},"prompt":{"type":"string","title":"Prompt"},"context":{"$ref":"#/components/schemas/MagicBlockContext"}},"type":"object","required":["activity_uuid","block_uuid","prompt","context"],"title":"StartMagicBlockSession"},"StartPlaygroundSession":{"properties":{"playground_uuid":{"type":"string","title":"Playground Uuid"},"prompt":{"type":"string","title":"Prompt"},"context":{"$ref":"#/components/schemas/PlaygroundContext"}},"type":"object","required":["playground_uuid","prompt","context"],"title":"StartPlaygroundSession"},"StatusEnum":{"type":"string","enum":["STATUS_IN_PROGRESS","STATUS_COMPLETED","STATUS_PAUSED","STATUS_CANCELLED"],"title":"StatusEnum"},"StorageOrgConfig":{"properties":{"enabled":{"type":"boolean","title":"Enabled","default":true},"limit":{"type":"integer","title":"Limit","default":10}},"type":"object","title":"StorageOrgConfig"},"SuccessStatusEnum":{"type":"string","enum":["passed","failed","unknown"],"title":"SuccessStatusEnum"},"SuggestStructureRequest":{"properties":{"temp_id":{"type":"string","title":"Temp Id"},"course_name":{"type":"string","title":"Course Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"}},"type":"object","required":["temp_id","course_name"],"title":"SuggestStructureRequest","description":"Request to AI for structure suggestion."},"SuperadminAPITokenCreate":{"properties":{"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"expires_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expires At"}},"type":"object","required":["name"],"title":"SuperadminAPITokenCreate"},"SuperadminAPITokenCreatedResponse":{"properties":{"token":{"type":"string","title":"Token"},"token_uuid":{"type":"string","title":"Token Uuid"},"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"token_prefix":{"type":"string","title":"Token Prefix"},"created_by_user_id":{"type":"integer","title":"Created By User Id"},"creation_date":{"type":"string","title":"Creation Date"},"expires_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expires At"}},"type":"object","required":["token","token_uuid","name","token_prefix","created_by_user_id","creation_date"],"title":"SuperadminAPITokenCreatedResponse","description":"Returned only on creation — the only response that includes the plaintext token."},"SuperadminAPITokenRead":{"properties":{"id":{"type":"integer","title":"Id"},"token_uuid":{"type":"string","title":"Token Uuid"},"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"token_prefix":{"type":"string","title":"Token Prefix"},"created_by_user_id":{"type":"integer","title":"Created By User Id"},"creation_date":{"type":"string","title":"Creation Date"},"update_date":{"type":"string","title":"Update Date"},"last_used_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Used At"},"expires_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expires At"},"is_active":{"type":"boolean","title":"Is Active"}},"type":"object","required":["id","token_uuid","name","token_prefix","created_by_user_id","creation_date","update_date","is_active"],"title":"SuperadminAPITokenRead"},"SuperadminAPITokenUpdate":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"expires_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expires At"}},"type":"object","title":"SuperadminAPITokenUpdate"},"SuperadminStatusResponse":{"properties":{"is_superadmin":{"type":"boolean","title":"Is Superadmin"}},"type":"object","required":["is_superadmin"],"title":"SuperadminStatusResponse"},"TestCase":{"properties":{"id":{"type":"string","title":"Id"},"label":{"type":"string","title":"Label"},"stdin":{"type":"string","title":"Stdin"},"expected_stdout":{"type":"string","title":"Expected Stdout"}},"type":"object","required":["id","label","stdin","expected_stdout"],"title":"TestCase"},"ThirdPartyLogin":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"provider":{"type":"string","const":"google","title":"Provider"},"access_token":{"type":"string","title":"Access Token"}},"type":"object","required":["email","provider","access_token"],"title":"ThirdPartyLogin"},"ThumbnailType":{"type":"string","enum":["image","video","both"],"title":"ThumbnailType"},"TokenResponse":{"properties":{"access_token":{"type":"string","title":"Access Token","description":"JWT access token"},"token_type":{"type":"string","title":"Token Type","description":"Token type (always 'bearer')","default":"bearer"},"user_id":{"type":"integer","title":"User Id","description":"ID of the user the token was issued for"},"user_uuid":{"type":"string","title":"User Uuid","description":"UUID of the user"}},"type":"object","required":["access_token","user_id","user_uuid"],"title":"TokenResponse","description":"JWT token issued on behalf of a user."},"Trail":{"properties":{"org_id":{"type":"integer","title":"Org Id"},"user_id":{"type":"integer","title":"User Id"},"id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Id"},"trail_uuid":{"type":"string","title":"Trail Uuid","default":""},"creation_date":{"type":"string","title":"Creation Date","default":""},"update_date":{"type":"string","title":"Update Date","default":""}},"type":"object","required":["org_id","user_id"],"title":"Trail"},"TrailActivityProgress":{"properties":{"activity_uuid":{"type":"string","title":"Activity Uuid"},"activity_id":{"type":"integer","title":"Activity Id"},"name":{"type":"string","title":"Name"},"activity_type":{"type":"string","title":"Activity Type"},"activity_sub_type":{"type":"string","title":"Activity Sub Type"},"order":{"type":"integer","title":"Order","description":"Order of this activity within its chapter"},"published":{"type":"boolean","title":"Published"},"completed":{"type":"boolean","title":"Completed"},"teacher_verified":{"type":"boolean","title":"Teacher Verified","description":"Whether a teacher has verified the completion (assignments)","default":false},"grade":{"type":"string","title":"Grade","description":"Grade/feedback recorded on the trail step, when set","default":""},"completed_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Completed At","description":"ISO timestamp when the activity was marked complete; null if not completed"}},"type":"object","required":["activity_uuid","activity_id","name","activity_type","activity_sub_type","order","published","completed"],"title":"TrailActivityProgress","description":"A single activity within a chapter, annotated with the user's completion state."},"TrailChapterProgress":{"properties":{"chapter_uuid":{"type":"string","title":"Chapter Uuid"},"chapter_id":{"type":"integer","title":"Chapter Id"},"name":{"type":"string","title":"Name"},"order":{"type":"integer","title":"Order"},"total_activities":{"type":"integer","title":"Total Activities"},"completed_activities":{"type":"integer","title":"Completed Activities"},"activities":{"items":{"$ref":"#/components/schemas/TrailActivityProgress"},"type":"array","title":"Activities"}},"type":"object","required":["chapter_uuid","chapter_id","name","order","total_activities","completed_activities","activities"],"title":"TrailChapterProgress","description":"A chapter inside a course with its activities and per-chapter counts."},"TrailCourseProgress":{"properties":{"course_uuid":{"type":"string","title":"Course Uuid"},"course_id":{"type":"integer","title":"Course Id"},"course_name":{"type":"string","title":"Course Name"},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status","description":"TrailRun status (STATUS_IN_PROGRESS, STATUS_COMPLETED, …); null when there is no enrollment row"},"enrolled_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Enrolled At","description":"ISO timestamp the user was enrolled; null when there is no enrollment row"},"total_activities":{"type":"integer","title":"Total Activities"},"completed_activities":{"type":"integer","title":"Completed Activities"},"completion_percentage":{"type":"number","title":"Completion Percentage"},"chapters":{"items":{"$ref":"#/components/schemas/TrailChapterProgress"},"type":"array","title":"Chapters"}},"type":"object","required":["course_uuid","course_id","course_name","total_activities","completed_activities","completion_percentage","chapters"],"title":"TrailCourseProgress","description":"A course the user is enrolled in (or has touched), with the full chapter/activity breakdown."},"TrailCreate":{"properties":{"org_id":{"type":"integer","title":"Org Id"},"user_id":{"type":"integer","title":"User Id"}},"type":"object","required":["org_id","user_id"],"title":"TrailCreate"},"TrailRead":{"properties":{"id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Id"},"trail_uuid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Trail Uuid"},"org_id":{"type":"integer","title":"Org Id"},"user_id":{"type":"integer","title":"User Id"},"creation_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Creation Date"},"update_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Update Date"},"runs":{"items":{"$ref":"#/components/schemas/TrailRunRead"},"type":"array","title":"Runs"}},"type":"object","required":["org_id","user_id","runs"],"title":"TrailRead"},"TrailRunRead":{"properties":{"id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Id"},"data":{"additionalProperties":true,"type":"object","title":"Data"},"status":{"$ref":"#/components/schemas/StatusEnum","default":"STATUS_IN_PROGRESS"},"trail_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Trail Id"},"course_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Course Id"},"org_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Org Id"},"user_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"User Id"},"course":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Course"},"creation_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Creation Date"},"update_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Update Date"},"course_total_steps":{"type":"integer","title":"Course Total Steps","default":0},"steps":{"items":{"$ref":"#/components/schemas/TrailStep"},"type":"array","title":"Steps"}},"type":"object","title":"TrailRunRead"},"TrailStep":{"properties":{"id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Id"},"complete":{"type":"boolean","title":"Complete"},"teacher_verified":{"type":"boolean","title":"Teacher Verified"},"grade":{"type":"string","title":"Grade"},"data":{"additionalProperties":true,"type":"object","title":"Data"},"trailrun_id":{"type":"integer","title":"Trailrun Id"},"trail_id":{"type":"integer","title":"Trail Id"},"activity_id":{"type":"integer","title":"Activity Id"},"course_id":{"type":"integer","title":"Course Id"},"org_id":{"type":"integer","title":"Org Id"},"user_id":{"type":"integer","title":"User Id"},"creation_date":{"type":"string","title":"Creation Date"},"update_date":{"type":"string","title":"Update Date"}},"type":"object","required":["complete","teacher_verified","grade","trailrun_id","trail_id","activity_id","course_id","org_id","user_id","creation_date","update_date"],"title":"TrailStep"},"UnenrollResponse":{"properties":{"detail":{"type":"string","title":"Detail"}},"type":"object","required":["detail"],"title":"UnenrollResponse"},"UpdateOrgPlanRequest":{"properties":{"org_id":{"type":"integer","title":"Org Id"},"plan":{"type":"string","title":"Plan"}},"type":"object","required":["org_id","plan"],"title":"UpdateOrgPlanRequest"},"UpdateOrgPlanResponse":{"properties":{"detail":{"type":"string","title":"Detail"},"org_id":{"type":"integer","title":"Org Id"},"plan":{"type":"string","title":"Plan"}},"type":"object","required":["detail","org_id","plan"],"title":"UpdateOrgPlanResponse"},"UpdateUserRequest":{"properties":{"username":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Username"},"first_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"First Name"},"last_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Name"},"email":{"anyOf":[{"type":"string","format":"email"},{"type":"null"}],"title":"Email"},"avatar_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Avatar Image"},"bio":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bio"},"details":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Details"},"profile":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Profile"}},"type":"object","title":"UpdateUserRequest","description":"Fields that can be updated via the admin profile PATCH."},"UploadedFileInfo":{"properties":{"file_id":{"type":"string","title":"File Id"},"filename":{"type":"string","title":"Filename"},"file_type":{"type":"string","title":"File Type"},"size":{"type":"integer","title":"Size"},"extension":{"type":"string","title":"Extension"}},"type":"object","required":["file_id","filename","file_type","size","extension"],"title":"UploadedFileInfo","description":"Info about a single uploaded file."},"UserCreate":{"properties":{"username":{"type":"string","title":"Username"},"first_name":{"type":"string","title":"First Name","default":""},"last_name":{"type":"string","title":"Last Name","default":""},"email":{"type":"string","format":"email","title":"Email"},"avatar_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Avatar Image","default":""},"bio":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bio","default":""},"details":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Details"},"profile":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Profile"},"extra_metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Extra Metadata"},"password":{"type":"string","title":"Password"}},"type":"object","required":["username","email","password"],"title":"UserCreate"},"UserDataExportResponse":{"properties":{"profile":{"additionalProperties":true,"type":"object","title":"Profile","description":"The user's profile (scrubbed of sensitive fields)"},"memberships":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Memberships","description":"Org memberships scoped to the caller's org"},"trails":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Trails","description":"Learning trails in the caller's org"},"trail_runs":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Trail Runs","description":"Course enrollments / trail runs"},"trail_steps":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Trail Steps","description":"Activity completions"},"certificates":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Certificates","description":"Certificates awarded in the caller's org"},"user_groups":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"User Groups","description":"Cohort memberships in the caller's org"},"exported_at":{"type":"string","title":"Exported At","description":"ISO8601 timestamp when the export was generated"}},"type":"object","required":["profile","memberships","trails","trail_runs","trail_steps","certificates","user_groups","exported_at"],"title":"UserDataExportResponse","description":"Full GDPR data export bundle."},"UserGroupCourseResponse":{"properties":{"detail":{"type":"string","title":"Detail"},"usergroup_uuid":{"type":"string","title":"Usergroup Uuid"},"course_uuid":{"type":"string","title":"Course Uuid"}},"type":"object","required":["detail","usergroup_uuid","course_uuid"],"title":"UserGroupCourseResponse"},"UserGroupCreate":{"properties":{"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"},"org_id":{"type":"integer","title":"Org Id"}},"type":"object","required":["name","description"],"title":"UserGroupCreate"},"UserGroupMemberListItem":{"properties":{"user":{"additionalProperties":true,"type":"object","title":"User"},"added_at":{"type":"string","title":"Added At"}},"type":"object","required":["user","added_at"],"title":"UserGroupMemberListItem"},"UserGroupMemberResponse":{"properties":{"detail":{"type":"string","title":"Detail"},"usergroup_uuid":{"type":"string","title":"Usergroup Uuid"},"user_id":{"type":"integer","title":"User Id"}},"type":"object","required":["detail","usergroup_uuid","user_id"],"title":"UserGroupMemberResponse"},"UserGroupOrgConfig":{"properties":{"enabled":{"type":"boolean","title":"Enabled","default":true},"limit":{"type":"integer","title":"Limit","default":10}},"type":"object","title":"UserGroupOrgConfig"},"UserGroupRead":{"properties":{"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"},"id":{"type":"integer","title":"Id"},"org_id":{"type":"integer","title":"Org Id"},"usergroup_uuid":{"type":"string","title":"Usergroup Uuid"},"creation_date":{"type":"string","title":"Creation Date"},"update_date":{"type":"string","title":"Update Date"}},"type":"object","required":["name","description","id","usergroup_uuid","creation_date","update_date"],"title":"UserGroupRead"},"UserGroupResponse":{"properties":{"id":{"type":"integer","title":"Id"},"org_id":{"type":"integer","title":"Org Id"},"usergroup_uuid":{"type":"string","title":"Usergroup Uuid"},"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"},"creation_date":{"type":"string","title":"Creation Date"},"update_date":{"type":"string","title":"Update Date"}},"type":"object","required":["id","org_id","usergroup_uuid","name","description","creation_date","update_date"],"title":"UserGroupResponse","description":"A user group / cohort."},"UserGroupUpdate":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"}},"type":"object","title":"UserGroupUpdate"},"UserRead":{"properties":{"username":{"type":"string","title":"Username"},"first_name":{"type":"string","title":"First Name"},"last_name":{"type":"string","title":"Last Name"},"email":{"type":"string","format":"email","title":"Email"},"avatar_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Avatar Image","default":""},"bio":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bio","default":""},"details":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Details"},"profile":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Profile"},"extra_metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Extra Metadata"},"id":{"type":"integer","title":"Id"},"user_uuid":{"type":"string","title":"User Uuid"},"email_verified":{"type":"boolean","title":"Email Verified","default":false},"last_login_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Login At"},"signup_method":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Signup Method"},"is_superadmin":{"type":"boolean","title":"Is Superadmin","default":false}},"type":"object","required":["username","first_name","last_name","email","id","user_uuid"],"title":"UserRead"},"UserReadAuthor":{"properties":{"id":{"type":"integer","title":"Id"},"user_uuid":{"type":"string","title":"User Uuid"},"username":{"type":"string","title":"Username"},"first_name":{"type":"string","title":"First Name"},"last_name":{"type":"string","title":"Last Name"},"avatar_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Avatar Image","default":""}},"type":"object","required":["id","user_uuid","username","first_name","last_name"],"title":"UserReadAuthor","description":"Minimal author projection for community comments/discussions.\n\nSECURITY: comment/discussion authors are returned to *every* reader of a\nthread (often anonymous). It must therefore expose ONLY the fields needed to\nrender an author chip — never ``email``, ``is_superadmin``, ``signup_method``\nor the raw ``details``/``profile``/``extra_metadata`` blobs that ``UserRead``\ncarries. The frontend reads only id/user_uuid/username/name/avatar."},"UserReadPublic":{"properties":{"id":{"type":"integer","title":"Id"},"user_uuid":{"type":"string","title":"User Uuid"},"username":{"type":"string","title":"Username"},"first_name":{"type":"string","title":"First Name"},"last_name":{"type":"string","title":"Last Name"},"email_verified":{"type":"boolean","title":"Email Verified","default":false},"avatar_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Avatar Image","default":""},"bio":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bio","default":""},"details":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Details"},"profile":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Profile"}},"type":"object","required":["id","user_uuid","username","first_name","last_name"],"title":"UserReadPublic","description":"User model for public-facing endpoints — excludes sensitive fields.\n\nSECURITY: This is the view returned to *any* authenticated user when they\nlook up *another* user (by id/uuid/username, or via usergroup member lists).\nIt must therefore NOT inherit from ``UserBase``, because ``UserBase`` (and\n``UserRead``) expose PII / internal fields — ``email``, ``signup_method``,\n``is_superadmin``, ``extra_metadata`` — that would leak to anyone who can\nenumerate user ids. ``details`` and ``profile`` ARE included: they are the\nuser's own public profile content (bio extension, links, etc.) that the\npublic profile page renders, so they are intentionally exposed."},"UserRoleWithOrg":{"properties":{"role":{"$ref":"#/components/schemas/RoleRead"},"org":{"$ref":"#/components/schemas/OrganizationRead"}},"type":"object","required":["role","org"],"title":"UserRoleWithOrg"},"UserSession":{"properties":{"user":{"$ref":"#/components/schemas/UserRead"},"roles":{"items":{"$ref":"#/components/schemas/UserRoleWithOrg"},"type":"array","title":"Roles"}},"type":"object","required":["user","roles"],"title":"UserSession"},"UserTrailDetail":{"properties":{"trail_uuid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Trail Uuid","description":"Null if the user has never started a trail in this org"},"user_id":{"type":"integer","title":"User Id"},"org_id":{"type":"integer","title":"Org Id"},"creation_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Creation Date"},"update_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Update Date"},"courses":{"items":{"$ref":"#/components/schemas/TrailCourseProgress"},"type":"array","title":"Courses"}},"type":"object","required":["user_id","org_id","courses"],"title":"UserTrailDetail","description":"Full breakdown of a user's trail across courses in the org."},"UserUpdate":{"properties":{"username":{"type":"string","title":"Username"},"first_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"First Name"},"last_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Name"},"email":{"type":"string","format":"email","title":"Email"},"avatar_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Avatar Image","default":""},"bio":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bio","default":""},"details":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Details"},"profile":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Profile"},"extra_metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Extra Metadata"}},"type":"object","required":["username","email"],"title":"UserUpdate"},"UserUpdatePassword":{"properties":{"old_password":{"type":"string","title":"Old Password"},"new_password":{"type":"string","title":"New Password"}},"type":"object","required":["old_password","new_password"],"title":"UserUpdatePassword"},"UserUserGroupItem":{"properties":{"usergroup":{"additionalProperties":true,"type":"object","title":"Usergroup"},"added_at":{"type":"string","title":"Added At"}},"type":"object","required":["usergroup","added_at"],"title":"UserUserGroupItem"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"VerifyEmailRequest":{"properties":{"token":{"type":"string","title":"Token"},"user_uuid":{"type":"string","title":"User Uuid"},"org_uuid":{"type":"string","title":"Org Uuid"},"email":{"anyOf":[{"type":"string","format":"email"},{"type":"null"}],"title":"Email"}},"type":"object","required":["token","user_uuid","org_uuid"],"title":"VerifyEmailRequest"},"WebhookDeliveryLogRead":{"properties":{"id":{"type":"integer","title":"Id"},"webhook_id":{"type":"integer","title":"Webhook Id"},"event_name":{"type":"string","title":"Event Name"},"delivery_uuid":{"type":"string","title":"Delivery Uuid"},"request_payload":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Request Payload"},"response_status":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Response Status"},"response_body":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Response Body"},"success":{"type":"boolean","title":"Success"},"attempt":{"type":"integer","title":"Attempt"},"error_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Message"},"created_at":{"type":"string","title":"Created At"}},"type":"object","required":["id","webhook_id","event_name","delivery_uuid","success","attempt","created_at"],"title":"WebhookDeliveryLogRead"},"WebhookEndpointCreate":{"properties":{"url":{"type":"string","title":"Url"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"events":{"items":{"type":"string"},"type":"array","title":"Events"}},"type":"object","required":["url","events"],"title":"WebhookEndpointCreate"},"WebhookEndpointCreatedResponse":{"properties":{"webhook_uuid":{"type":"string","title":"Webhook Uuid"},"url":{"type":"string","title":"Url"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"events":{"items":{"type":"string"},"type":"array","title":"Events"},"is_active":{"type":"boolean","title":"Is Active"},"secret":{"type":"string","title":"Secret"},"created_by_user_id":{"type":"integer","title":"Created By User Id"},"creation_date":{"type":"string","title":"Creation Date"}},"type":"object","required":["webhook_uuid","url","events","is_active","secret","created_by_user_id","creation_date"],"title":"WebhookEndpointCreatedResponse","description":"Returned only on create / regenerate -- the only time the secret is shown."},"WebhookEndpointRead":{"properties":{"id":{"type":"integer","title":"Id"},"webhook_uuid":{"type":"string","title":"Webhook Uuid"},"org_id":{"type":"integer","title":"Org Id"},"url":{"type":"string","title":"Url"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"events":{"items":{"type":"string"},"type":"array","title":"Events"},"is_active":{"type":"boolean","title":"Is Active"},"has_secret":{"type":"boolean","title":"Has Secret","default":true},"source":{"type":"string","title":"Source","default":"manual"},"zap_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Zap Name"},"zap_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Zap Id"},"created_by_user_id":{"type":"integer","title":"Created By User Id"},"creation_date":{"type":"string","title":"Creation Date"},"update_date":{"type":"string","title":"Update Date"}},"type":"object","required":["id","webhook_uuid","org_id","url","events","is_active","created_by_user_id","creation_date","update_date"],"title":"WebhookEndpointRead"},"WebhookEndpointUpdate":{"properties":{"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"events":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Events"},"is_active":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Active"}},"type":"object","title":"WebhookEndpointUpdate"},"ZapierCourseItem":{"properties":{"id":{"type":"integer","title":"Id"},"course_uuid":{"type":"string","title":"Course Uuid"},"name":{"type":"string","title":"Name"}},"type":"object","required":["id","course_uuid","name"],"title":"ZapierCourseItem"},"ZapierMeResponse":{"properties":{"org_id":{"type":"integer","title":"Org Id"},"org_name":{"type":"string","title":"Org Name"},"org_slug":{"type":"string","title":"Org Slug"},"token_id":{"type":"integer","title":"Token Id"},"token_name":{"type":"string","title":"Token Name"}},"type":"object","required":["org_id","org_name","org_slug","token_id","token_name"],"title":"ZapierMeResponse"},"ZapierSubscriptionCreate":{"properties":{"target_url":{"type":"string","title":"Target Url","description":"Zapier's REST Hook callback URL"},"event":{"type":"string","title":"Event","description":"A single event name from /events"},"zap_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Zap Id","description":"Zapier's internal Zap identifier"},"zap_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Zap Name","description":"Human-readable Zap name"}},"type":"object","required":["target_url","event"],"title":"ZapierSubscriptionCreate"},"ZapierSubscriptionResponse":{"properties":{"id":{"type":"integer","title":"Id"},"webhook_uuid":{"type":"string","title":"Webhook Uuid"},"target_url":{"type":"string","title":"Target Url"},"event":{"type":"string","title":"Event"},"zap_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Zap Id"},"zap_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Zap Name"},"is_active":{"type":"boolean","title":"Is Active"}},"type":"object","required":["id","webhook_uuid","target_url","event","is_active"],"title":"ZapierSubscriptionResponse"},"ZapierUserGroupItem":{"properties":{"id":{"type":"integer","title":"Id"},"usergroup_uuid":{"type":"string","title":"Usergroup Uuid"},"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"}},"type":"object","required":["id","usergroup_uuid","name","description"],"title":"ZapierUserGroupItem"},"ZapierUserItem":{"properties":{"id":{"type":"integer","title":"Id"},"user_uuid":{"type":"string","title":"User Uuid"},"email":{"type":"string","title":"Email"},"username":{"type":"string","title":"Username"},"first_name":{"type":"string","title":"First Name"},"last_name":{"type":"string","title":"Last Name"}},"type":"object","required":["id","user_uuid","email","username","first_name","last_name"],"title":"ZapierUserItem"},"src__db__communities__discussion_reactions__ReactionUser":{"properties":{"id":{"type":"integer","title":"Id"},"user_uuid":{"type":"string","title":"User Uuid"},"username":{"type":"string","title":"Username"},"first_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"First Name"},"last_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Name"},"avatar_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Avatar Image"}},"type":"object","required":["id","user_uuid","username"],"title":"ReactionUser","description":"User info for reaction display."},"src__db__playground_reactions__ReactionUser":{"properties":{"id":{"type":"integer","title":"Id"},"user_uuid":{"type":"string","title":"User Uuid"},"username":{"type":"string","title":"Username"},"first_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"First Name"},"last_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Name"},"avatar_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Avatar Image"}},"type":"object","required":["id","user_uuid","username"],"title":"ReactionUser"}}}}