{"openapi":"3.1.0","info":{"title":"YAR API","description":"Backend API for YAR (Yezh ar vRo) - geolocalised audio clips","version":"0.1.0"},"paths":{"/auth/register":{"post":{"tags":["auth"],"summary":"Register","description":"Register a new user (or re-issue OTP if already registered but unverified).\n\nAlways returns 201 with no body to avoid leaking whether the email is\nalready known. The OTP is sent regardless; if the address is already a\nverified account, the OTP is harmless (verify_otp will succeed but the\nflow ends in an access token, which is the desired UX anyway).","operationId":"register_auth_register_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/request-otp":{"post":{"tags":["auth"],"summary":"Request Otp","description":"Issue a fresh OTP for the given email + purpose.\n\nAlways returns 200 to avoid leaking which emails exist. For login /\npassword_reset, an OTP is only useful if a user exists with this email;\nwe still issue and \"send\" so timing does not reveal existence.","operationId":"request_otp_auth_request_otp_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RequestOtpRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/verify-otp":{"post":{"tags":["auth"],"summary":"Verify Otp Endpoint","description":"Validate an OTP and produce the appropriate response for its purpose.\n\n- signup_verify: marks email verified, returns an access token.\n- login: returns an access token.\n- password_reset: returns a short-lived reset token (not a full session).","operationId":"verify_otp_endpoint_auth_verify_otp_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyOtpRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/login":{"post":{"tags":["auth"],"summary":"Login","operationId":"login_auth_login_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/set-password":{"post":{"tags":["auth"],"summary":"Set Password","description":"Set or change the current user's password.\n\nUsed during onboarding (Option A's optional password step) and from the\nprofile screen to change a password later.","operationId":"set_password_auth_set_password_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetPasswordRequest"}}},"required":true},"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/auth/reset-password":{"post":{"tags":["auth"],"summary":"Reset Password","description":"Set a new password using a reset token from verify-otp.","operationId":"reset_password_auth_reset_password_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResetPasswordRequest"}}},"required":true},"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/logout":{"post":{"tags":["auth"],"summary":"Logout","description":"Invalidate all of this user's outstanding native JWTs.\n\nImplemented by bumping `token_version`. Single-device logout (drop the\nlocal token) does not need a server call; this endpoint is for\n\"log out everywhere\" and is also called when a user requests account\ndeletion (ISS #344).","operationId":"logout_auth_logout_post","responses":{"204":{"description":"Successful Response"}},"security":[{"HTTPBearer":[]}]}},"/auth/update-email":{"post":{"tags":["auth"],"summary":"Update Email","description":"Step 1 of email change: send an OTP to the requested new address.\n\nThe user must already be authenticated. Possession of the new address is\nproved by entering the OTP via /auth/verify-email-update.","operationId":"update_email_auth_update_email_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateEmailRequest"}}},"required":true},"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/auth/verify-email-update":{"post":{"tags":["auth"],"summary":"Verify Email Update","description":"Step 2 of email change: consume the OTP and apply the new address.\n\nOn success, also bumps token_version so the new email is reflected the\nnext time the client refreshes; the current access token still works\nuntil the client re-fetches /auth/me.","operationId":"verify_email_update_auth_verify_email_update_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyEmailUpdateRequest"}}},"required":true},"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/auth/me":{"get":{"tags":["auth"],"summary":"Me","operationId":"me_auth_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/health":{"get":{"summary":"Health Check","description":"Health check endpoint.","operationId":"health_check_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/clips":{"get":{"summary":"Get Clips","description":"Get audio clips, optionally filtered by uploader(s).\n\nReturns public clips, plus user's own clips (including staged/private ones).\nSupports multiple user_id parameters: ?user_id=abc&user_id=def\nAdditional AND-composable filters: speaker_id, language_id, date_from, date_to.","operationId":"get_clips_clips_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"mine","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Mine"}},{"name":"user_id","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string","format":"uuid"}},{"type":"null"}],"title":"User Id"}},{"name":"speaker_id","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string","format":"uuid"}},{"type":"null"}],"title":"Speaker Id"}},{"name":"language_id","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"integer"}},{"type":"null"}],"title":"Language Id"}},{"name":"date_from","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Date From"}},{"name":"date_to","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Date To"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/RecordingResponse"},"title":"Response Get Clips Clips Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"summary":"Create Clip","description":"Upload a new audio clip with geolocation.","operationId":"create_clip_clips_post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_create_clip_clips_post"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordingResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/clips/{sound_id}/audio":{"get":{"summary":"Get Clip Audio","description":"Download the audio file for a clip.\n\nFor S3 storage: redirects to a presigned URL (client fetches directly from S3).\nFor local storage: streams the file from disk.","operationId":"get_clip_audio_clips__sound_id__audio_get","parameters":[{"name":"sound_id","in":"path","required":true,"schema":{"type":"integer","title":"Sound Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/users":{"get":{"summary":"Get Users","description":"List all users (for frontend user picker).","operationId":"get_users_users_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/UserResponse"},"type":"array","title":"Response Get Users Users Get"}}}}}}},"/speakers":{"get":{"summary":"Get Speakers","description":"List users who appear as speakers on at least one public recording.","operationId":"get_speakers_speakers_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/UserResponse"},"type":"array","title":"Response Get Speakers Speakers Get"}}}}}}},"/users/me":{"put":{"summary":"Update Current User","description":"Update the current user's profile.","operationId":"update_current_user_users_me_put","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserUpdate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]},"delete":{"summary":"Delete Own Account","description":"Delete your own account and all associated data.","operationId":"delete_own_account_users_me_delete","responses":{"204":{"description":"Successful Response"}},"security":[{"HTTPBearer":[]}]}},"/users/{user_id}":{"delete":{"summary":"Delete User","description":"Delete a user and all their data (admin only).","operationId":"delete_user_users__user_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/users/me/onboarding":{"get":{"summary":"Get Onboarding Status","description":"Get the current user's onboarding status.","operationId":"get_onboarding_status_users_me_onboarding_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnboardingStatusResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/users/me/accept-terms":{"post":{"summary":"Accept Terms","description":"Accept the terms and conditions.","operationId":"accept_terms_users_me_accept_terms_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AcceptTermsRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnboardingStatusResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/users/me/accept-consent":{"post":{"summary":"Accept Consent","description":"Accept the license and consent agreement.","operationId":"accept_consent_users_me_accept_consent_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AcceptTermsRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnboardingStatusResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/users/me/withdraw-consent":{"post":{"summary":"Withdraw Consent","description":"Withdraw consent. Unpublishes any recordings where this user is a speaker.","operationId":"withdraw_consent_users_me_withdraw_consent_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnboardingStatusResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/users/me/export":{"get":{"summary":"Export User Data","description":"Export all data the server holds about the user (GDPR right of access).\n\nReturns a ZIP containing profile.json, recordings.json, collections.json,\nconsent_tokens.json, and audio files.","operationId":"export_user_data_users_me_export_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/users/me/validate-invite":{"post":{"summary":"Validate Invite Code","description":"Validate an invite code to complete onboarding.","operationId":"validate_invite_code_users_me_validate_invite_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidateInviteCodeRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnboardingStatusResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/clips/{sound_id}/speakers":{"put":{"summary":"Update Clip Speakers","description":"Update the speakers associated with a recording.\n\nOnly the uploader can modify speakers.","operationId":"update_clip_speakers_clips__sound_id__speakers_put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"sound_id","in":"path","required":true,"schema":{"type":"integer","title":"Sound Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSpeakers"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordingResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/clips/{sound_id}/location":{"put":{"summary":"Update Clip Location","description":"Update the location of a recording.\n\nOnly the uploader can modify location.","operationId":"update_clip_location_clips__sound_id__location_put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"sound_id","in":"path","required":true,"schema":{"type":"integer","title":"Sound Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateLocation"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordingResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/clips/{sound_id}/publish":{"put":{"summary":"Toggle Clip Publish","description":"Toggle the publish status of a recording.\n\nOnly the uploader can change publish status.\nToggles between staged (is_public=False) and published (is_public=True).","operationId":"toggle_clip_publish_clips__sound_id__publish_put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"sound_id","in":"path","required":true,"schema":{"type":"integer","title":"Sound Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordingResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/clips/{sound_id}":{"delete":{"summary":"Delete Clip","description":"Delete a recording permanently.\n\nOnly the uploader can delete their recording.\nThis removes both the database record and the audio file.","operationId":"delete_clip_clips__sound_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"sound_id","in":"path","required":true,"schema":{"type":"integer","title":"Sound Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/collections":{"get":{"summary":"Get Collections","description":"List collections visible to the current user.\n\nReturns public collections and the user's own collections.","operationId":"get_collections_collections_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/CollectionResponse"},"type":"array","title":"Response Get Collections Collections Get"}}}}},"security":[{"HTTPBearer":[]}]},"post":{"summary":"Create Collection","description":"Create a new collection.","operationId":"create_collection_collections_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/collections/{collection_id}":{"delete":{"summary":"Delete Collection","description":"Delete a collection.\n\nOnly the owner can delete their collection.","operationId":"delete_collection_collections__collection_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"collection_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Collection Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"summary":"Get Collection Detail","description":"Get collection details with recordings.\n\nPublic collections are visible to everyone.\nPrivate collections are only visible to their owner.","operationId":"get_collection_detail_collections__collection_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"collection_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Collection Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionDetailResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"summary":"Update Collection","description":"Update a collection's name or visibility.\n\nOnly the owner can update their collection.","operationId":"update_collection_collections__collection_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"collection_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Collection Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/collections/{collection_id}/reorder":{"put":{"summary":"Reorder Collection Recordings","description":"Reorder recordings in a collection.\n\nOnly the owner can reorder their collection.\nThe sound_ids list should contain all recordings in the desired order.","operationId":"reorder_collection_recordings_collections__collection_id__reorder_put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"collection_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Collection Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReorderRecordingsRequest"}}}},"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/collections/{collection_id}/recordings/{sound_id}":{"put":{"summary":"Add Clip To Collection","description":"Add a clip to a collection.\n\nOnly the collection owner can add clips.\nClips are automatically added at the end of the collection.","operationId":"add_clip_to_collection_collections__collection_id__recordings__sound_id__put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"collection_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Collection Id"}},{"name":"sound_id","in":"path","required":true,"schema":{"type":"integer","title":"Sound Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"summary":"Remove Clip From Collection","description":"Remove a clip from a collection.\n\nOnly the collection owner can remove clips.","operationId":"remove_clip_from_collection_collections__collection_id__recordings__sound_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"collection_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Collection Id"}},{"name":"sound_id","in":"path","required":true,"schema":{"type":"integer","title":"Sound Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/languages":{"get":{"summary":"Get Languages","description":"List all available languages.","operationId":"get_languages_languages_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/LanguageResponse"},"type":"array","title":"Response Get Languages Languages Get"}}}}}}},"/languages/suggest":{"post":{"summary":"Suggest Language","description":"Suggest a new dialect/language not in the list.\n\nThe suggestion is usable immediately by the submitter but flagged\nas is_suggested=True for moderator review. A unique code is\nauto-generated from the name.","operationId":"suggest_language_languages_suggest_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuggestLanguage"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LanguageResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/users/me/languages":{"get":{"summary":"Get User Languages","description":"Get the current user's languages with proficiency.","operationId":"get_user_languages_users_me_languages_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/UserLanguageResponse"},"type":"array","title":"Response Get User Languages Users Me Languages Get"}}}}},"security":[{"HTTPBearer":[]}]},"post":{"summary":"Add User Language","description":"Add a language to the current user's profile.","operationId":"add_user_language_users_me_languages_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserLanguageCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserLanguageResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/users/me/languages/{language_id}":{"delete":{"summary":"Remove User Language","description":"Remove a language from the current user's profile.","operationId":"remove_user_language_users_me_languages__language_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"language_id","in":"path","required":true,"schema":{"type":"integer","title":"Language Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/clips/{sound_id}/languages":{"put":{"summary":"Update Clip Languages","description":"Update the languages of a recording.\n\nOnly the uploader can modify languages.\nPublished clips must retain at least one language.","operationId":"update_clip_languages_clips__sound_id__languages_put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"sound_id","in":"path","required":true,"schema":{"type":"integer","title":"Sound Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateRecordingLanguages"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordingResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/keywords":{"get":{"summary":"Get Keywords","description":"List all available keywords.","operationId":"get_keywords_keywords_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/KeywordResponse"},"type":"array","title":"Response Get Keywords Keywords Get"}}}}}},"post":{"summary":"Create Keyword","description":"Create a new keyword.","operationId":"create_keyword_keywords_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/KeywordCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KeywordResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/clips/{sound_id}/keywords":{"put":{"summary":"Update Clip Keywords","description":"Update the keywords of a recording.\n\nOnly the uploader can modify keywords.","operationId":"update_clip_keywords_clips__sound_id__keywords_put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"sound_id","in":"path","required":true,"schema":{"type":"integer","title":"Sound Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateRecordingKeywords"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordingResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/clips/{sound_id}/description":{"put":{"summary":"Update Clip Description","description":"Update the description of a recording.\n\nOnly the uploader can modify description.","operationId":"update_clip_description_clips__sound_id__description_put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"sound_id","in":"path","required":true,"schema":{"type":"integer","title":"Sound Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateRecordingDescription"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordingResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/clips/{sound_id}/title":{"put":{"summary":"Update Clip Title","description":"Update the title of a recording.\n\nOnly the uploader can modify title.","operationId":"update_clip_title_clips__sound_id__title_put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"sound_id","in":"path","required":true,"schema":{"type":"integer","title":"Sound Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateRecordingTitle"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordingResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/collections/{collection_id}/keywords":{"put":{"summary":"Update Collection Keywords","description":"Update the keywords of a collection.\n\nOnly the owner can modify keywords.","operationId":"update_collection_keywords_collections__collection_id__keywords_put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"collection_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Collection Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCollectionKeywords"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api-keys":{"get":{"summary":"List Api Keys","description":"List the current user's API keys (without the raw key values).","operationId":"list_api_keys_api_keys_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ApiKeyResponse"},"type":"array","title":"Response List Api Keys Api Keys Get"}}}}},"security":[{"HTTPBearer":[]}]},"post":{"summary":"Create Api Key","description":"Create a new API key for programmatic access.\n\nThe raw key is returned only once in the response. Store it securely.","operationId":"create_api_key_api_keys_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyCreated"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api-keys/{key_id}":{"delete":{"summary":"Revoke Api Key","description":"Revoke (delete) an API key.","operationId":"revoke_api_key_api_keys__key_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"key_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Key Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/consent-tokens":{"get":{"summary":"List Consent Tokens","description":"List token-only speakers created by the current user.","operationId":"list_consent_tokens_consent_tokens_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ConsentTokenResponse"},"type":"array","title":"Response List Consent Tokens Consent Tokens Get"}}}}},"security":[{"HTTPBearer":[]}]},"post":{"summary":"Create Consent Token","description":"Create a token-only speaker (field consent).","operationId":"create_consent_token_consent_tokens_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConsentTokenCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConsentTokenResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/consent-tokens/{token}/withdraw":{"post":{"summary":"Withdraw Consent Token","description":"Withdraw consent for a token-only speaker. No auth required — the token is the credential.\n\nAlso unpublishes any recordings where this speaker is tagged.","operationId":"withdraw_consent_token_consent_tokens__token__withdraw_post","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"}}}}}}},"/consent-tokens/{token}/claim":{"post":{"summary":"Claim Consent Token","description":"Claim a token identity — transfer recordings to authenticated user.","operationId":"claim_consent_token_consent_tokens__token__claim_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"AcceptTermsRequest":{"properties":{"accepted":{"type":"boolean","title":"Accepted"}},"type":"object","required":["accepted"],"title":"AcceptTermsRequest","description":"Schema for accepting terms or consent."},"ApiKeyCreate":{"properties":{"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label"}},"type":"object","title":"ApiKeyCreate","description":"Schema for creating an API key."},"ApiKeyCreated":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"key_prefix":{"type":"string","title":"Key Prefix"},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"last_used_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Used At"},"key":{"type":"string","title":"Key"}},"type":"object","required":["id","key_prefix","created_at","key"],"title":"ApiKeyCreated","description":"Response when creating a new API key. Includes the raw key (shown only once)."},"ApiKeyResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"key_prefix":{"type":"string","title":"Key Prefix"},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"last_used_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Used At"}},"type":"object","required":["id","key_prefix","created_at"],"title":"ApiKeyResponse","description":"Schema for API key responses (excludes the raw key)."},"Body_create_clip_clips_post":{"properties":{"file":{"type":"string","format":"binary","title":"File"},"device_id":{"type":"string","maxLength":64,"minLength":1,"title":"Device Id"},"latitude":{"type":"number","maximum":90.0,"minimum":-90.0,"title":"Latitude"},"longitude":{"type":"number","maximum":180.0,"minimum":-180.0,"title":"Longitude"},"visibility_km":{"type":"number","maximum":1000.0,"minimum":0.0,"title":"Visibility Km","default":10.0},"title":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Title"},"speaker_ids":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Speaker Ids"},"language_ids":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Language Ids"},"duration":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Duration"}},"type":"object","required":["file","device_id","latitude","longitude"],"title":"Body_create_clip_clips_post"},"CollectionCreate":{"properties":{"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"}},"type":"object","required":["name"],"title":"CollectionCreate","description":"Schema for creating a collection."},"CollectionDetailResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"owner_id":{"type":"string","format":"uuid","title":"Owner Id"},"is_public":{"type":"boolean","title":"Is Public"},"keywords":{"items":{"$ref":"#/components/schemas/KeywordInfo"},"type":"array","title":"Keywords","default":[]},"created_at":{"type":"string","format":"date-time","title":"Created At"},"recordings":{"items":{"$ref":"#/components/schemas/RecordingResponse"},"type":"array","title":"Recordings"}},"type":"object","required":["id","name","owner_id","is_public","created_at","recordings"],"title":"CollectionDetailResponse","description":"Schema for collection detail with recordings."},"CollectionInfo":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"type":"string","title":"Name"}},"type":"object","required":["id","name"],"title":"CollectionInfo","description":"Minimal collection info for recording responses."},"CollectionResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"owner_id":{"type":"string","format":"uuid","title":"Owner Id"},"is_public":{"type":"boolean","title":"Is Public"},"recording_count":{"type":"integer","title":"Recording Count"},"keywords":{"items":{"$ref":"#/components/schemas/KeywordInfo"},"type":"array","title":"Keywords","default":[]},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","name","owner_id","is_public","recording_count","created_at"],"title":"CollectionResponse","description":"Schema for collection responses."},"CollectionUpdate":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"is_public":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Public"}},"type":"object","title":"CollectionUpdate","description":"Schema for updating a collection."},"ConsentTokenCreate":{"properties":{"consent_token":{"type":"string","title":"Consent Token"},"display_name":{"type":"string","title":"Display Name"},"birth_year":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Birth Year"},"consent_method":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Consent Method","default":"digital_tap"},"consent_text_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Consent Text Version"}},"type":"object","required":["consent_token","display_name"],"title":"ConsentTokenCreate","description":"Schema for creating a token-only speaker."},"ConsentTokenResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"consent_token":{"type":"string","title":"Consent Token"},"display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display Name"},"birth_year":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Birth Year"},"is_token_only":{"type":"boolean","title":"Is Token Only","default":true},"accepted_consent_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Accepted Consent At"},"created_by":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Created By"},"consent_method":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Consent Method"},"consent_text_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Consent Text Version"}},"type":"object","required":["id","consent_token"],"title":"ConsentTokenResponse","description":"Schema for consent token speaker responses."},"Geolocation":{"properties":{"lat":{"type":"number","title":"Lat"},"lng":{"type":"number","title":"Lng"},"visibility_km":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Visibility Km","default":10.0}},"type":"object","required":["lat","lng"],"title":"Geolocation","description":"Geolocation data for a recording."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"KeywordCreate":{"properties":{"value":{"type":"string","title":"Value"}},"type":"object","required":["value"],"title":"KeywordCreate","description":"Schema for creating a keyword."},"KeywordInfo":{"properties":{"id":{"type":"integer","title":"Id"},"value":{"type":"string","title":"Value"}},"type":"object","required":["id","value"],"title":"KeywordInfo","description":"Minimal keyword info for recording/collection responses."},"KeywordResponse":{"properties":{"id":{"type":"integer","title":"Id"},"value":{"type":"string","title":"Value"}},"type":"object","required":["id","value"],"title":"KeywordResponse","description":"Schema for keyword responses."},"LanguageInfo":{"properties":{"id":{"type":"integer","title":"Id"},"code":{"type":"string","title":"Code"},"name":{"type":"string","title":"Name"},"native_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Native Name"}},"type":"object","required":["id","code","name"],"title":"LanguageInfo","description":"Minimal language info for recording responses."},"LanguageResponse":{"properties":{"id":{"type":"integer","title":"Id"},"code":{"type":"string","title":"Code"},"name":{"type":"string","title":"Name"},"native_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Native Name"},"toponym":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Toponym"},"parent_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Parent Id"},"is_suggested":{"type":"boolean","title":"Is Suggested","default":false}},"type":"object","required":["id","code","name"],"title":"LanguageResponse","description":"Schema for language responses."},"LoginRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"password":{"type":"string","minLength":1,"title":"Password"}},"type":"object","required":["email","password"],"title":"LoginRequest"},"OnboardingStatusResponse":{"properties":{"is_validated":{"type":"boolean","title":"Is Validated"},"display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display Name"},"birth_year":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Birth Year"},"accepted_terms_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Accepted Terms At"},"accepted_consent_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Accepted Consent At"},"has_languages":{"type":"boolean","title":"Has Languages","default":false}},"type":"object","required":["is_validated"],"title":"OnboardingStatusResponse","description":"Schema for onboarding status."},"Proficiency":{"type":"string","enum":["native","first_language","second_language","third_language"],"title":"Proficiency","description":"Language proficiency levels for users."},"RecordingResponse":{"properties":{"geolocation":{"$ref":"#/components/schemas/Geolocation"},"sound_id":{"type":"integer","title":"Sound Id"},"device_id":{"type":"string","title":"Device Id"},"uploader_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Uploader Id"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"sound_file":{"type":"string","title":"Sound File"},"timestamp":{"type":"string","format":"date-time","title":"Timestamp"},"duration":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Duration"},"is_public":{"type":"boolean","title":"Is Public","default":false},"speakers":{"items":{"$ref":"#/components/schemas/SpeakerInfo"},"type":"array","title":"Speakers","default":[]},"languages":{"items":{"$ref":"#/components/schemas/LanguageInfo"},"type":"array","title":"Languages","default":[]},"keywords":{"items":{"$ref":"#/components/schemas/KeywordInfo"},"type":"array","title":"Keywords","default":[]},"collections":{"items":{"$ref":"#/components/schemas/CollectionInfo"},"type":"array","title":"Collections","default":[]},"metadata_modified_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Metadata Modified At"},"metadata_modified_by":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Metadata Modified By"}},"type":"object","required":["geolocation","sound_id","device_id","sound_file","timestamp"],"title":"RecordingResponse","description":"Schema for recording responses."},"RegisterRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"}},"type":"object","required":["email"],"title":"RegisterRequest"},"ReorderRecordingsRequest":{"properties":{"sound_ids":{"items":{"type":"integer"},"type":"array","title":"Sound Ids"}},"type":"object","required":["sound_ids"],"title":"ReorderRecordingsRequest","description":"Schema for reordering recordings in a collection."},"RequestOtpRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"purpose":{"type":"string","enum":["signup_verify","login","password_reset"],"title":"Purpose"}},"type":"object","required":["email","purpose"],"title":"RequestOtpRequest"},"ResetPasswordRequest":{"properties":{"reset_token":{"type":"string","title":"Reset Token"},"password":{"type":"string","maxLength":200,"minLength":8,"title":"Password"}},"type":"object","required":["reset_token","password"],"title":"ResetPasswordRequest"},"SetPasswordRequest":{"properties":{"password":{"type":"string","maxLength":200,"minLength":8,"title":"Password"}},"type":"object","required":["password"],"title":"SetPasswordRequest"},"SpeakerInfo":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display Name"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"is_token_only":{"type":"boolean","title":"Is Token Only","default":false}},"type":"object","required":["id"],"title":"SpeakerInfo","description":"Minimal speaker info for recording responses."},"SuggestLanguage":{"properties":{"name":{"type":"string","title":"Name"},"native_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Native Name"},"parent_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Parent Id"}},"type":"object","required":["name"],"title":"SuggestLanguage","description":"Schema for suggesting a new dialect/language."},"TokenResponse":{"properties":{"access_token":{"type":"string","title":"Access Token"},"token_type":{"type":"string","const":"bearer","title":"Token Type","default":"bearer"}},"type":"object","required":["access_token"],"title":"TokenResponse","description":"Returned by login and successful OTP verify (signup_verify / login)."},"UpdateCollectionKeywords":{"properties":{"keyword_ids":{"items":{"type":"integer"},"type":"array","title":"Keyword Ids"}},"type":"object","required":["keyword_ids"],"title":"UpdateCollectionKeywords","description":"Schema for updating keywords on a collection."},"UpdateEmailRequest":{"properties":{"new_email":{"type":"string","format":"email","title":"New Email"}},"type":"object","required":["new_email"],"title":"UpdateEmailRequest","description":"Schema for /auth/update-email: requests an OTP to the new address."},"UpdateLocation":{"properties":{"lat":{"type":"number","title":"Lat"},"lng":{"type":"number","title":"Lng"},"visibility_km":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Visibility Km"}},"type":"object","required":["lat","lng"],"title":"UpdateLocation","description":"Schema for updating location on a recording."},"UpdateRecordingDescription":{"properties":{"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"}},"type":"object","title":"UpdateRecordingDescription","description":"Schema for updating description on a recording."},"UpdateRecordingKeywords":{"properties":{"keyword_ids":{"items":{"type":"integer"},"type":"array","title":"Keyword Ids"}},"type":"object","required":["keyword_ids"],"title":"UpdateRecordingKeywords","description":"Schema for updating keywords on a recording."},"UpdateRecordingLanguages":{"properties":{"language_ids":{"items":{"type":"integer"},"type":"array","title":"Language Ids"}},"type":"object","required":["language_ids"],"title":"UpdateRecordingLanguages","description":"Schema for updating languages on a recording."},"UpdateRecordingTitle":{"properties":{"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"}},"type":"object","title":"UpdateRecordingTitle","description":"Schema for updating title on a recording."},"UpdateSpeakers":{"properties":{"speaker_ids":{"items":{"type":"string","format":"uuid"},"type":"array","title":"Speaker Ids"}},"type":"object","required":["speaker_ids"],"title":"UpdateSpeakers","description":"Schema for updating speakers on a recording."},"UserLanguageCreate":{"properties":{"language_id":{"type":"integer","title":"Language Id"},"proficiency":{"$ref":"#/components/schemas/Proficiency"},"learnt_as_adult":{"type":"boolean","title":"Learnt As Adult","default":false},"comment":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Comment"}},"type":"object","required":["language_id","proficiency"],"title":"UserLanguageCreate","description":"Schema for adding a language to user profile."},"UserLanguageResponse":{"properties":{"language_id":{"type":"integer","title":"Language Id"},"language":{"$ref":"#/components/schemas/LanguageResponse"},"proficiency":{"$ref":"#/components/schemas/Proficiency"},"learnt_as_adult":{"type":"boolean","title":"Learnt As Adult"},"comment":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Comment"}},"type":"object","required":["language_id","language","proficiency","learnt_as_adult"],"title":"UserLanguageResponse","description":"Schema for user language proficiency responses."},"UserResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display Name"},"birth_year":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Birth Year"},"role":{"type":"string","title":"Role"},"is_validated":{"type":"boolean","title":"Is Validated","default":false},"is_token_only":{"type":"boolean","title":"Is Token Only","default":false},"created_by":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Created By"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["id","role","created_at"],"title":"UserResponse","description":"Schema for user responses."},"UserUpdate":{"properties":{"display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display Name"},"birth_year":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Birth Year"}},"type":"object","title":"UserUpdate","description":"Schema for updating user profile."},"ValidateInviteCodeRequest":{"properties":{"invite_code":{"type":"string","title":"Invite Code"}},"type":"object","required":["invite_code"],"title":"ValidateInviteCodeRequest","description":"Schema for validating an invite code."},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"VerifyEmailUpdateRequest":{"properties":{"new_email":{"type":"string","format":"email","title":"New Email"},"code":{"type":"string","maxLength":6,"minLength":6,"title":"Code"}},"type":"object","required":["new_email","code"],"title":"VerifyEmailUpdateRequest","description":"Schema for /auth/verify-email-update: applies the email change."},"VerifyOtpRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"purpose":{"type":"string","enum":["signup_verify","login","password_reset"],"title":"Purpose"},"code":{"type":"string","maxLength":6,"minLength":6,"title":"Code"}},"type":"object","required":["email","purpose","code"],"title":"VerifyOtpRequest"}},"securitySchemes":{"HTTPBearer":{"type":"http","scheme":"bearer"}}}}