{"openapi":"3.1.0","info":{"title":"VideoHub","description":"API pública para transcrever vídeos do YouTube e Instagram. Documentação amigável em https://videohub.pro/docs.","version":"0.5.0"},"paths":{"/api/auth/check-email":{"post":{"summary":"Check Email","description":"Tell the unified `/entrar` form whether to ask for login or signup next.\n\nRate-limited per IP (default 20/hour) to make casual enumeration\nimpractical, accepting the privacy trade-off for the simpler UX.","operationId":"check_email_api_auth_check_email_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckEmailRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckEmailResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/users":{"post":{"summary":"Create User","operationId":"create_user_api_users_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserPublic"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/login":{"post":{"summary":"Login","operationId":"login_api_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/UserPublic"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/logout":{"post":{"summary":"Logout","operationId":"logout_api_auth_logout_post","responses":{"204":{"description":"Successful Response"}}}},"/api/users/me":{"get":{"summary":"Me","operationId":"me_api_users_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserPublic"}}}}}},"delete":{"summary":"Delete Me","operationId":"delete_me_api_users_me_delete","responses":{"204":{"description":"Successful Response"}}},"patch":{"summary":"Update Me","operationId":"update_me_api_users_me_patch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserUpdate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserPublic"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/transcriptions":{"post":{"summary":"Create Transcription","description":"Create a queued transcription and enqueue a background job.\n\nAccepts EITHER `url` (YouTube/Instagram) or `file_id` (previously uploaded), not both.\nReturns immediately with the new id; the SSE endpoint streams progress.","operationId":"create_transcription_api_transcriptions_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTranscriptionRequest"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTranscriptionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"summary":"List My Transcriptions","operationId":"list_my_transcriptions_api_transcriptions_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TranscriptionListItem"},"title":"Response List My Transcriptions Api Transcriptions Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/transcriptions/{transcription_id}":{"get":{"summary":"Get Transcription","operationId":"get_transcription_api_transcriptions__transcription_id__get","parameters":[{"name":"transcription_id","in":"path","required":true,"schema":{"type":"string","title":"Transcription Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TranscriptionDetail"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"summary":"Delete Transcription","operationId":"delete_transcription_api_transcriptions__transcription_id__delete","parameters":[{"name":"transcription_id","in":"path","required":true,"schema":{"type":"string","title":"Transcription Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/transcriptions/{transcription_id}/stream":{"get":{"summary":"Stream Transcription","description":"SSE that hydrates state from DB and tails Redis with race protection.\n\nOrder of operations is intentional to avoid losing the terminal event when\nthe worker finishes between our initial DB read and the pub/sub subscribe:\n\n  1. Subscribe to the Redis channel FIRST (no events lost from now on).\n  2. THEN read the DB. If terminal, emit final and close.\n  3. If still in flight, replay last_event_json so the client sees progress\n     right away, then tail Redis while also polling the DB every few seconds\n     (defense in depth against missed pub/sub messages or worker crash).","operationId":"stream_transcription_api_transcriptions__transcription_id__stream_get","parameters":[{"name":"transcription_id","in":"path","required":true,"schema":{"type":"string","title":"Transcription Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/transcriptions/{transcription_id}/thumbnail":{"get":{"summary":"Get Thumbnail","operationId":"get_thumbnail_api_transcriptions__transcription_id__thumbnail_get","parameters":[{"name":"transcription_id","in":"path","required":true,"schema":{"type":"string","title":"Transcription Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/transcriptions/{transcription_id}/frames":{"get":{"summary":"List Frames","description":"List the frames for this transcription. Includes a `url` field per\nframe so the UI can render an `<img>` without building the URL itself.\n404 when the row has no frames (legacy or extraction-disabled).","operationId":"list_frames_api_transcriptions__transcription_id__frames_get","parameters":[{"name":"transcription_id","in":"path","required":true,"schema":{"type":"string","title":"Transcription Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/transcriptions/{transcription_id}/frames/{frame_index}":{"get":{"summary":"Get Frame","description":"Serve a single JPEG frame. The index is the same as `FrameInfo.index`\n(zero-based, stable across calls).","operationId":"get_frame_api_transcriptions__transcription_id__frames__frame_index__get","parameters":[{"name":"transcription_id","in":"path","required":true,"schema":{"type":"string","title":"Transcription Id"}},{"name":"frame_index","in":"path","required":true,"schema":{"type":"integer","title":"Frame Index"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/transcriptions/{transcription_id}/comments":{"get":{"summary":"List Comments","description":"Top comments for this transcription. Returns `pending: true` while a\nfetch is queued/in-flight so the UI can poll until results land.","operationId":"list_comments_api_transcriptions__transcription_id__comments_get","parameters":[{"name":"transcription_id","in":"path","required":true,"schema":{"type":"string","title":"Transcription Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/transcriptions/{transcription_id}/subtitles.srt":{"get":{"summary":"Download Subtitles Srt","operationId":"download_subtitles_srt_api_transcriptions__transcription_id__subtitles_srt_get","parameters":[{"name":"transcription_id","in":"path","required":true,"schema":{"type":"string","title":"Transcription Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/transcriptions/{transcription_id}/subtitles.vtt":{"get":{"summary":"Download Subtitles Vtt","operationId":"download_subtitles_vtt_api_transcriptions__transcription_id__subtitles_vtt_get","parameters":[{"name":"transcription_id","in":"path","required":true,"schema":{"type":"string","title":"Transcription Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/transcriptions/{transcription_id}/timestamps.md":{"get":{"summary":"Download Timestamps Md","operationId":"download_timestamps_md_api_transcriptions__transcription_id__timestamps_md_get","parameters":[{"name":"transcription_id","in":"path","required":true,"schema":{"type":"string","title":"Transcription Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/transcriptions/{transcription_id}/segments.json":{"get":{"summary":"Download Segments Json","operationId":"download_segments_json_api_transcriptions__transcription_id__segments_json_get","parameters":[{"name":"transcription_id","in":"path","required":true,"schema":{"type":"string","title":"Transcription Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/transcriptions/{transcription_id}/ai.md":{"get":{"summary":"Download Ai Report","description":"Per-user AI-ready report. Same builder as the public route, just gated\nby the user-owns-the-row check rather than canonical visibility.","operationId":"download_ai_report_api_transcriptions__transcription_id__ai_md_get","parameters":[{"name":"transcription_id","in":"path","required":true,"schema":{"type":"string","title":"Transcription Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/transcribe":{"post":{"tags":["public-api-v1"],"summary":"V1 Transcribe","description":"Transcribe a YouTube/Instagram URL.\n\nCache hit returns immediately. Cache miss enqueues a job and waits up to\n`wait_seconds`. If the job finishes within that window the markdown comes\nin the same response; otherwise the caller polls `status_url` / streams\n`stream_url`.","operationId":"v1_transcribe_api_v1_transcribe_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1TranscribeRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1TranscriptionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/transcribe/{transcription_id}":{"get":{"tags":["public-api-v1"],"summary":"V1 Get Transcribe","operationId":"v1_get_transcribe_api_v1_transcribe__transcription_id__get","parameters":[{"name":"transcription_id","in":"path","required":true,"schema":{"type":"string","title":"Transcription Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1TranscriptionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/transcribe/{transcription_id}/stream":{"get":{"tags":["public-api-v1"],"summary":"V1 Stream Transcribe","description":"SSE that hydrates current state and tails Redis. Mirrors the internal\n/api/transcriptions/{id}/stream endpoint, but with public-visibility rules\n(own row OR canonical).","operationId":"v1_stream_transcribe_api_v1_transcribe__transcription_id__stream_get","parameters":[{"name":"transcription_id","in":"path","required":true,"schema":{"type":"string","title":"Transcription Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/keys":{"get":{"tags":["api-keys"],"summary":"List Keys","description":"List all keys belonging to the current user. Secrets are not returned.","operationId":"list_keys_api_v1_keys_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ApiKeyInfo"},"type":"array","title":"Response List Keys Api V1 Keys Get"}}}}}},"post":{"tags":["api-keys"],"summary":"Create Key","description":"Create a new API key. The full secret is returned ONCE in this response;\nthe server only stores its hash. The caller is responsible for saving it\nimmediately (no way to retrieve it later).","operationId":"create_key_api_v1_keys_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyCreateRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyCreateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/keys/{key_id}":{"delete":{"tags":["api-keys"],"summary":"Revoke Key","description":"Soft-revoke: marks `revoked_at`. The key can no longer authenticate.","operationId":"revoke_key_api_v1_keys__key_id__delete","parameters":[{"name":"key_id","in":"path","required":true,"schema":{"type":"integer","title":"Key Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/forgot-password":{"post":{"summary":"Forgot Password","description":"Always returns 200 — never leaks whether the email exists.\n\nIf the email matches a user, we generate a fresh token, persist its hash,\nand email the plain token. If the email doesn't exist, we silently do\nnothing. To the caller, both look the same.","operationId":"forgot_password_api_auth_forgot_password_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForgotPasswordRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/reset-password":{"post":{"summary":"Reset Password","operationId":"reset_password_api_auth_reset_password_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResetPasswordRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/reset":{"get":{"summary":"Reset Password Page","operationId":"reset_password_page_auth_reset_get","parameters":[{"name":"token","in":"query","required":false,"schema":{"type":"string","default":"","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/oauth/{provider}/login":{"get":{"tags":["oauth"],"summary":"Oauth Login","operationId":"oauth_login_auth_oauth__provider__login_get","parameters":[{"name":"provider","in":"path","required":true,"schema":{"type":"string","title":"Provider"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/oauth/{provider}/callback":{"get":{"tags":["oauth"],"summary":"Oauth Callback","operationId":"oauth_callback_auth_oauth__provider__callback_get","parameters":[{"name":"provider","in":"path","required":true,"schema":{"type":"string","title":"Provider"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/chat/{transcription_id}":{"get":{"summary":"Chat State","operationId":"chat_state_api_chat__transcription_id__get","parameters":[{"name":"transcription_id","in":"path","required":true,"schema":{"type":"string","title":"Transcription Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"summary":"Chat Send","operationId":"chat_send_api_chat__transcription_id__post","parameters":[{"name":"transcription_id","in":"path","required":true,"schema":{"type":"string","title":"Transcription Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatSendRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/":{"get":{"summary":"Index","operationId":"index__get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/entrar":{"get":{"summary":"Entrar Page","description":"Unified email-first auth flow. Same template handles login, signup,\nforgot-password — distinguished by an Alpine state machine on the client.","operationId":"entrar_page_entrar_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/login":{"get":{"summary":"Login Page","description":"Compat: old /login URL still works, points at the unified flow.","operationId":"login_page_login_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/signup":{"get":{"summary":"Signup Page","description":"Compat: old /signup URL still works, points at the unified flow.","operationId":"signup_page_signup_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/historico":{"get":{"summary":"History Page","operationId":"history_page_historico_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/app/api-keys":{"get":{"summary":"Api Keys Page","operationId":"api_keys_page_app_api_keys_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/docs":{"get":{"summary":"Docs Page","operationId":"docs_page_docs_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/pricing":{"get":{"summary":"Pricing Page","operationId":"pricing_page_pricing_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/privacy":{"get":{"summary":"Privacy Page","operationId":"privacy_page_privacy_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/terms":{"get":{"summary":"Terms Page","operationId":"terms_page_terms_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/transcricoes/{transcription_id}":{"get":{"summary":"Transcription Page","operationId":"transcription_page_transcricoes__transcription_id__get","parameters":[{"name":"transcription_id","in":"path","required":true,"schema":{"type":"string","title":"Transcription Id"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/chat/{transcription_id}":{"get":{"summary":"Chat Page","operationId":"chat_page_chat__transcription_id__get","parameters":[{"name":"transcription_id","in":"path","required":true,"schema":{"type":"string","title":"Transcription Id"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/upload":{"post":{"summary":"Upload Endpoint","description":"Receive a media upload, persist it, validate basic properties.\n\nReturns a file_id the client can pass to /api/transcribe-stream?file_id=...","operationId":"upload_endpoint_api_upload_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_endpoint_api_upload_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/health":{"get":{"summary":"Health","operationId":"health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/transcript/{short_id}.srt":{"get":{"summary":"Transcript Srt","operationId":"transcript_srt_transcript__short_id__srt_get","parameters":[{"name":"short_id","in":"path","required":true,"schema":{"type":"string","title":"Short Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/transcript/{short_id}.vtt":{"get":{"summary":"Transcript Vtt","operationId":"transcript_vtt_transcript__short_id__vtt_get","parameters":[{"name":"short_id","in":"path","required":true,"schema":{"type":"string","title":"Short Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/transcript/{short_id}.timestamps.md":{"get":{"summary":"Transcript Timestamps Md","operationId":"transcript_timestamps_md_transcript__short_id__timestamps_md_get","parameters":[{"name":"short_id","in":"path","required":true,"schema":{"type":"string","title":"Short Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/transcript/{short_id}.segments.json":{"get":{"summary":"Transcript Segments Json","operationId":"transcript_segments_json_transcript__short_id__segments_json_get","parameters":[{"name":"short_id","in":"path","required":true,"schema":{"type":"string","title":"Short Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/transcript/{short_id}.ai.md":{"get":{"summary":"Transcript Ai Md","description":"The \"AI-ready\" rich markdown report. This is the URL users paste into\na chat with Claude/ChatGPT/Gemini — the model fetches it and gets the\ntitle, metadata, frame URLs (with timestamps) and the full transcript\nin one shot, all aligned by `MM:SS`.\n\nPublic for canonical rows. We deliberately serve `text/markdown` (not\n`text/plain` or HTML) so well-behaved fetchers preserve formatting.","operationId":"transcript_ai_md_transcript__short_id__ai_md_get","parameters":[{"name":"short_id","in":"path","required":true,"schema":{"type":"string","title":"Short Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/transcript/{short_id}.frames.json":{"get":{"summary":"Transcript Frames List","description":"Public frames index for a canonical transcription. Each entry includes\na URL pointing at the per-frame endpoint below.","operationId":"transcript_frames_list_transcript__short_id__frames_json_get","parameters":[{"name":"short_id","in":"path","required":true,"schema":{"type":"string","title":"Short Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/transcript/{short_id}/frames/{frame_index}":{"get":{"summary":"Transcript Frame","description":"Public JPEG of one frame. Long Cache-Control because the bytes are\nimmutable once written (a frame's filename embeds its index).","operationId":"transcript_frame_transcript__short_id__frames__frame_index__get","parameters":[{"name":"short_id","in":"path","required":true,"schema":{"type":"string","title":"Short Id"}},{"name":"frame_index","in":"path","required":true,"schema":{"type":"integer","title":"Frame Index"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/transcript/{short_id}":{"get":{"summary":"Transcript Page","operationId":"transcript_page_transcript__short_id__get","parameters":[{"name":"short_id","in":"path","required":true,"schema":{"type":"string","title":"Short Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/p/transcricoes/{transcription_id}/thumbnail":{"get":{"summary":"Public Thumbnail","operationId":"public_thumbnail_p_transcricoes__transcription_id__thumbnail_get","parameters":[{"name":"transcription_id","in":"path","required":true,"schema":{"type":"string","title":"Transcription Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/{full_url}":{"get":{"summary":"Shortcut","operationId":"shortcut__full_url__get","parameters":[{"name":"full_url","in":"path","required":true,"schema":{"type":"string","title":"Full Url"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"ApiKeyCreateRequest":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}],"title":"Name"}},"type":"object","title":"ApiKeyCreateRequest"},"ApiKeyCreateResponse":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"prefix":{"type":"string","title":"Prefix"},"secret":{"type":"string","title":"Secret"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","name","prefix","secret","created_at"],"title":"ApiKeyCreateResponse"},"ApiKeyInfo":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"prefix":{"type":"string","title":"Prefix"},"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"},"revoked_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Revoked At"}},"type":"object","required":["id","name","prefix","created_at","last_used_at","revoked_at"],"title":"ApiKeyInfo"},"Body_upload_endpoint_api_upload_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"}},"type":"object","required":["file"],"title":"Body_upload_endpoint_api_upload_post"},"ChatSendRequest":{"properties":{"message":{"type":"string","maxLength":4000,"minLength":1,"title":"Message"}},"type":"object","required":["message"],"title":"ChatSendRequest"},"CheckEmailRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"}},"type":"object","required":["email"],"title":"CheckEmailRequest"},"CheckEmailResponse":{"properties":{"exists":{"type":"boolean","title":"Exists"}},"type":"object","required":["exists"],"title":"CheckEmailResponse"},"CreateTranscriptionRequest":{"properties":{"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url"},"file_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"File Id"}},"type":"object","title":"CreateTranscriptionRequest"},"CreateTranscriptionResponse":{"properties":{"transcription_id":{"type":"string","title":"Transcription Id"},"status":{"type":"string","title":"Status"}},"type":"object","required":["transcription_id","status"],"title":"CreateTranscriptionResponse"},"ForgotPasswordRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"}},"type":"object","required":["email"],"title":"ForgotPasswordRequest"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"LoginRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"password":{"type":"string","title":"Password"}},"type":"object","required":["email","password"],"title":"LoginRequest"},"ResetPasswordRequest":{"properties":{"token":{"type":"string","maxLength":128,"minLength":20,"title":"Token"},"new_password":{"type":"string","maxLength":128,"minLength":8,"title":"New Password"}},"type":"object","required":["token","new_password"],"title":"ResetPasswordRequest"},"SignupRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"password":{"type":"string","maxLength":128,"minLength":8,"title":"Password"},"display_name":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}],"title":"Display Name"}},"type":"object","required":["email","password"],"title":"SignupRequest"},"TranscriptionDetail":{"properties":{"id":{"type":"string","title":"Id"},"source_type":{"type":"string","title":"Source Type"},"source_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Url"},"title":{"type":"string","title":"Title"},"channel":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Channel"},"duration_seconds":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Duration Seconds"},"language":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Language"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"has_thumbnail":{"type":"boolean","title":"Has Thumbnail","default":false},"status":{"type":"string","title":"Status","default":"done"},"error_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Message"},"markdown":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Markdown"},"last_event_json":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Event Json"},"retryable":{"type":"boolean","title":"Retryable","default":false},"has_segments":{"type":"boolean","title":"Has Segments","default":false},"frames_count":{"type":"integer","title":"Frames Count","default":0},"comments_count":{"type":"integer","title":"Comments Count","default":0},"comments_pending":{"type":"boolean","title":"Comments Pending","default":false}},"type":"object","required":["id","source_type","source_url","title","channel","duration_seconds","language","created_at","markdown"],"title":"TranscriptionDetail"},"TranscriptionListItem":{"properties":{"id":{"type":"string","title":"Id"},"source_type":{"type":"string","title":"Source Type"},"source_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Url"},"title":{"type":"string","title":"Title"},"channel":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Channel"},"duration_seconds":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Duration Seconds"},"language":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Language"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"has_thumbnail":{"type":"boolean","title":"Has Thumbnail","default":false},"status":{"type":"string","title":"Status","default":"done"},"error_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Message"}},"type":"object","required":["id","source_type","source_url","title","channel","duration_seconds","language","created_at"],"title":"TranscriptionListItem"},"UploadResponse":{"properties":{"file_id":{"type":"string","title":"File Id"},"filename":{"type":"string","title":"Filename"},"size_bytes":{"type":"integer","title":"Size Bytes"},"duration_seconds":{"type":"number","title":"Duration Seconds"},"has_video":{"type":"boolean","title":"Has Video"},"needs_extraction":{"type":"boolean","title":"Needs Extraction"}},"type":"object","required":["file_id","filename","size_bytes","duration_seconds","has_video","needs_extraction"],"title":"UploadResponse"},"UserPublic":{"properties":{"id":{"type":"integer","title":"Id"},"email":{"type":"string","title":"Email"},"display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display Name"},"preferred_language":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Preferred Language"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"last_login_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Login At"}},"type":"object","required":["id","email","display_name","created_at","last_login_at"],"title":"UserPublic"},"UserUpdate":{"properties":{"display_name":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}],"title":"Display Name"},"password":{"anyOf":[{"type":"string","maxLength":128,"minLength":8},{"type":"null"}],"title":"Password"},"current_password":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Current Password"},"preferred_language":{"anyOf":[{"type":"string","pattern":"^(pt|en)$"},{"type":"null"}],"title":"Preferred Language"}},"type":"object","title":"UserUpdate"},"V1TranscribeRequest":{"properties":{"url":{"type":"string","title":"Url","description":"YouTube or Instagram URL"},"wait_seconds":{"anyOf":[{"type":"integer","maximum":300.0,"minimum":1.0},{"type":"null"}],"title":"Wait Seconds","description":"How long to wait synchronously before falling back to polling. Capped by server config; defaults to 60."}},"type":"object","required":["url"],"title":"V1TranscribeRequest"},"V1TranscriptionResponse":{"properties":{"status":{"type":"string","title":"Status"},"transcription_id":{"type":"string","title":"Transcription Id"},"cached":{"type":"boolean","title":"Cached","default":false},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"channel":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Channel"},"duration_seconds":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Duration Seconds"},"language":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Language"},"source_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Type"},"source_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Url"},"markdown":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Markdown"},"canonical_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Canonical Url"},"estimated_completion_seconds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Estimated Completion Seconds"},"estimated_completion_phrase":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Estimated Completion Phrase"},"progress":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Progress"},"stage":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stage"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"},"_meta":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Meta"}},"type":"object","required":["status","transcription_id"],"title":"V1TranscriptionResponse"},"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"}}}}