{"openapi":"3.0.3","info":{"title":"Astir Support API","version":"0.1.0","description":"Public support chat, FAQs, and admin support desk routes."},"servers":[{"url":"/","description":"Current server"}],"tags":[{"name":"Health"},{"name":"Support"},{"name":"FAQ"}],"components":{"securitySchemes":{"parentToken":{"type":"http","scheme":"bearer","bearerFormat":"JWT"},"deviceToken":{"type":"http","scheme":"bearer","bearerFormat":"JWT"},"legacyBearer":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"ErrorResponse":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Email is required"},"requestId":{"type":"string","example":"7d13c3a7-07d0-4f99-81a1-fb2efc42d1d8"}}}}},"LocalizedText":{"type":"object","required":["en","ru","uz"],"properties":{"en":{"type":"string","example":"Cartoons"},"ru":{"type":"string","example":"Мультфильмы"},"uz":{"type":"string","example":"Multfilmlar"}},"additionalProperties":false},"Parent":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string","example":"Parent"},"email":{"type":"string","example":"parent@example.com"},"tariff":{"type":"string","example":"free"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"LegacyUser":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string","example":"parent@example.com"},"name":{"type":"string","example":"Parent"},"last_name":{"type":"string","example":"User"},"phone":{"type":"string","nullable":true},"role":{"type":"string","example":"parent"},"active":{"type":"boolean","example":true},"avatar_url":{"type":"string","example":""},"last_login_at":{"type":"string","format":"date-time","nullable":true},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"LegacyTokenPair":{"type":"object","properties":{"access_token":{"type":"string"},"access_expires_at":{"type":"string","format":"date-time"},"refresh_token":{"type":"string"},"refresh_expires_at":{"type":"string","format":"date-time"},"user":{"$ref":"#/components/schemas/LegacyUser"}}},"LegacyI18nMessage":{"type":"object","properties":{"uz":{"type":"string","example":"Email yoki parol noto'g'ri. Iltimos, qayta tekshiring."},"ru":{"type":"string","example":"Неверный email или пароль. Пожалуйста, проверьте данные."},"en":{"type":"string","example":"Incorrect email or password. Please check your credentials."}}},"LegacyErrorResponse":{"type":"object","properties":{"error":{"type":"string","example":"invalid credentials"},"message":{"$ref":"#/components/schemas/LegacyI18nMessage"}}},"LegacyOkResponse":{"type":"object","properties":{"message":{"type":"string","example":"ok"}}},"LegacyOtpRequestResult":{"type":"object","properties":{"debug_code":{"type":"string","example":""},"email":{"type":"string","example":"user@example.com"},"expires_at":{"type":"string","format":"date-time"}}},"LegacyOtpVerifyResult":{"type":"object","properties":{"access_expires_at":{"type":"string","format":"date-time"},"access_token":{"type":"string"},"email":{"type":"string","example":"user@example.com"},"refresh_expires_at":{"type":"string","format":"date-time"},"refresh_token":{"type":"string"},"user":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/LegacyUser"}]},"user_exists":{"type":"boolean","example":true}}},"LegacyChild":{"type":"object","properties":{"id":{"type":"string","example":"b219a2f6-0670-44ed-8e18-57f887bd4e94"},"parent_id":{"type":"string","example":"5ca2bf5b-6e18-472e-b7c0-ed37b951e76d"},"name":{"type":"string","example":"Child"},"age":{"type":"integer","example":7},"avatar_url":{"type":"string","example":""},"active":{"type":"boolean","example":true},"extended_until":{"type":"string","format":"date-time","nullable":true},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"LegacyPairingTicket":{"type":"object","properties":{"device_id":{"type":"string","example":"3c52a843-0681-433c-a51e-c2f399dc4f29"},"code":{"type":"string","example":"XsqboTdpHD9Qiv4Q3W3VHQxufUpa2ykm"},"qr_base64":{"type":"string","example":"iVBORw0KGgoAAAANSUhEUgAA..."},"qr_payload":{"type":"string","example":"https://api.astir-animation.uz/child/pair?code=XsqboTdpHD9Qiv4Q3W3VHQxufUpa2ykm"},"expires_at":{"type":"string","format":"date-time"}}},"LegacyChildPairingStatus":{"type":"object","properties":{"device_id":{"type":"string","example":"3c52a843-0681-433c-a51e-c2f399dc4f29"},"status":{"type":"string","example":"pending"},"expires_at":{"type":"string","format":"date-time"},"access_token":{"type":"string"},"refresh_token":{"type":"string"},"refresh_expires_at":{"type":"string","format":"date-time"},"child":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/LegacyChild"}]}}},"LegacyChildDevice":{"type":"object","properties":{"id":{"type":"string","example":"3c52a843-0681-433c-a51e-c2f399dc4f29"},"child_id":{"type":"string","example":"b219a2f6-0670-44ed-8e18-57f887bd4e94"},"device_fingerprint":{"type":"string","example":"string"},"device_name":{"type":"string","example":"string"},"pairing_expires_at":{"type":"string","format":"date-time"},"paired_at":{"type":"string","format":"date-time","nullable":true},"revoked_at":{"type":"string","format":"date-time","nullable":true},"last_seen_at":{"type":"string","format":"date-time","nullable":true},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"LegacyChildPermission":{"type":"object","properties":{"id":{"type":"string"},"child_id":{"type":"string","example":"b219a2f6-0670-44ed-8e18-57f887bd4e94"},"mode":{"type":"string","example":"allow"},"category_id":{"type":"string","nullable":true},"content_id":{"type":"string","nullable":true},"series_id":{"type":"string","nullable":true},"watch_from_min":{"type":"integer","nullable":true,"example":0},"watch_until_min":{"type":"integer","nullable":true,"example":1320},"weekday_mask":{"type":"integer","nullable":true,"example":127},"daily_limit_minutes":{"type":"integer","nullable":true,"example":0},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"LegacyChildConfirmResult":{"type":"object","properties":{"action":{"type":"string","example":"pairing"},"device":{"$ref":"#/components/schemas/LegacyChildDevice"},"ticket_id":{"type":"string"},"extends_until":{"type":"string","format":"date-time"},"permissions":{"type":"array","items":{"$ref":"#/components/schemas/LegacyChildPermission"}}}},"LegacyTVChildProfile":{"type":"object","properties":{"active":{"type":"boolean"},"age":{"type":"integer"},"avatar_url":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"}}},"LegacyTVParentProfile":{"type":"object","properties":{"avatar_url":{"type":"string"},"id":{"type":"string"},"last_name":{"type":"string"},"name":{"type":"string"}}},"LegacyTVProfileList":{"type":"object","properties":{"children":{"type":"array","items":{"$ref":"#/components/schemas/LegacyTVChildProfile"}},"parent":{"$ref":"#/components/schemas/LegacyTVParentProfile"}}},"LegacyTVStatusResult":{"type":"object","properties":{"device_token":{"type":"string"},"profiles":{"$ref":"#/components/schemas/LegacyTVProfileList"},"status":{"type":"string","example":"pending"},"token_expires_at":{"type":"string"}}},"LegacyTVStreamSession":{"type":"object","properties":{"access_token":{"type":"string"},"expires_at":{"type":"string","format":"date-time"},"profile":{},"profile_type":{"type":"string","example":"parent"},"profiles":{"$ref":"#/components/schemas/LegacyTVProfileList"}}},"LegacyTVDevice":{"type":"object","properties":{"confirmed_at":{"type":"string","format":"date-time"},"created_at":{"type":"string","format":"date-time"},"device_fingerprint":{"type":"string"},"device_name":{"type":"string"},"id":{"type":"string"},"last_seen_at":{"type":"string","format":"date-time"},"pairing_expires_at":{"type":"string","format":"date-time"},"parent_id":{"type":"string"},"revoked_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"LegacyAdminCardView":{"type":"object","properties":{"brand":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"expiry_month":{"type":"integer"},"expiry_year":{"type":"integer"},"holder_name":{"type":"string"},"id":{"type":"string"},"is_default":{"type":"boolean"},"masked_pan":{"type":"string"},"provider":{"type":"string","enum":["click","payme","stripe","manual"]},"token_hash":{"type":"string"},"user_id":{"type":"string"},"verified_at":{"type":"string","format":"date-time"}}},"LegacyAdminCardListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/LegacyAdminCardView"}},"limit":{"type":"integer"},"offset":{"type":"integer"},"total":{"type":"integer"}}},"Child":{"type":"object","properties":{"id":{"type":"string"},"parentId":{"type":"string"},"name":{"type":"string","example":"Child"},"birthYear":{"type":"integer","example":2018},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"WatchLimit":{"type":"object","properties":{"id":{"type":"string"},"parentId":{"type":"string"},"childId":{"type":"string"},"dailyMinutes":{"type":"integer","example":60},"allowedFrom":{"type":"string","example":"08:00"},"allowedTo":{"type":"string","example":"20:00"},"allowedDays":{"type":"array","items":{"type":"integer"},"example":[1,2,3,4,5,6,7]},"allowedDates":{"type":"array","items":{"type":"string","format":"date"},"example":["2026-06-17"],"description":"Optional exact local dates. When present, date matching is used instead of recurring allowedDays."},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"PairedDevice":{"type":"object","properties":{"id":{"type":"string"},"parentId":{"type":"string"},"childId":{"type":"string"},"name":{"type":"string","example":"Astir Child Device"},"platform":{"type":"string","example":"ios"},"pairedAt":{"type":"string","format":"date-time"},"revokedAt":{"type":"string","format":"date-time","nullable":true},"revoked_at":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"ChildContentBlacklistItem":{"type":"object","properties":{"id":{"type":"string"},"parentId":{"type":"string"},"parent_id":{"type":"string"},"childId":{"type":"string"},"child_id":{"type":"string"},"contentId":{"type":"string","example":"7d13c3a7-07d0-4f99-81a1-fb2efc42d1d8"},"content_id":{"type":"string","example":"7d13c3a7-07d0-4f99-81a1-fb2efc42d1d8"},"title":{"$ref":"#/components/schemas/LocalizedText"},"title_en":{"type":"string","example":"Smoke Movie"},"title_ru":{"type":"string","example":"Smoke Movie RU"},"title_uz":{"type":"string","example":"Smoke Movie UZ"},"poster":{"type":"object","nullable":true,"properties":{"url":{"type":"string","nullable":true,"example":"/media/uploads/poster.png"},"storage_path":{"type":"string","nullable":true},"original_name":{"type":"string","nullable":true},"mime_type":{"type":"string","nullable":true},"size":{"type":"integer","nullable":true}}},"poster_url":{"type":"string","nullable":true,"example":"/media/uploads/poster.png"},"views":{"type":"integer","example":12},"views_count":{"type":"integer","example":12},"likes":{"type":"integer","example":1},"likes_count":{"type":"integer","example":1},"createdAt":{"type":"string","format":"date-time"},"created_at":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"ContentItem":{"type":"object","properties":{"id":{"type":"string","example":"bluey-001"},"title":{"$ref":"#/components/schemas/LocalizedText"},"type":{"type":"string","example":"cartoon"},"ageRating":{"type":"string","example":"G"},"durationMinutes":{"type":"integer","example":7},"item_type":{"type":"string","example":"content"},"target_type":{"type":"string","example":"content"},"target_id":{"type":"string","example":"bluey-001"},"likes_count":{"type":"integer","example":1},"is_liked":{"type":"boolean","example":true}}},"ContentCategory":{"type":"object","properties":{"id":{"type":"string"},"title":{"$ref":"#/components/schemas/LocalizedText"},"description":{"$ref":"#/components/schemas/LocalizedText"},"type":{"type":"string","example":"cartoon"},"slug":{"type":"string","example":"cartoons"},"active":{"type":"boolean","example":true},"icon_url":{"type":"string","nullable":true,"example":"/media/uploads/category-icon.png"},"icon":{"type":"object","nullable":true,"properties":{"url":{"type":"string","nullable":true,"example":"/media/uploads/category-icon.png"},"storage_path":{"type":"string","nullable":true,"example":"/absolute/storage/path/category-icon.png"},"original_name":{"type":"string","nullable":true,"example":"category-icon.png"},"mime_type":{"type":"string","nullable":true,"example":"image/png"},"size":{"type":"integer","nullable":true,"example":2048}}}}},"ContentTag":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string","example":"Cartoons"},"slug":{"type":"string","example":"cartoons"},"active":{"type":"boolean","example":true},"createdAt":{"type":"string","format":"date-time","nullable":true},"updatedAt":{"type":"string","format":"date-time","nullable":true}}},"SearchResultItem":{"type":"object","description":"Compact search card. Episode matches are returned as the parent series; video source, media and playback fields are intentionally omitted.","properties":{"id":{"type":"string","format":"uuid","example":"7d13c3a7-07d0-4f99-81a1-fb2efc42d1d8"},"item_type":{"type":"string","enum":["movie","series"],"example":"series"},"target_type":{"type":"string","enum":["content","series"],"description":"Resource type used with target_id.","example":"series"},"target_id":{"type":"string","format":"uuid","example":"7d13c3a7-07d0-4f99-81a1-fb2efc42d1d8"},"type":{"type":"string","enum":["movies","series"],"example":"series"},"title":{"$ref":"#/components/schemas/LocalizedText"},"poster":{"type":"object","nullable":true,"properties":{"url":{"type":"string","nullable":true,"example":"/media/uploads/poster.png"},"storage_path":{"type":"string","nullable":true},"original_name":{"type":"string","nullable":true,"example":"poster.png"},"mime_type":{"type":"string","nullable":true,"example":"image/png"},"size":{"type":"integer","nullable":true,"example":250000}}},"poster_url":{"type":"string","nullable":true,"example":"/media/uploads/poster.png"},"transcode_status":{"type":"string","example":"missing_source"},"transcode_error":{"type":"string","nullable":true,"example":null},"error_message":{"type":"string","nullable":true,"example":null},"age_rating":{"type":"integer","example":6},"duration_sec":{"type":"integer","example":1200},"duration_seconds":{"type":"integer","example":1200},"durationSec":{"type":"integer","example":1200},"duration":{"type":"integer","example":1200},"duration_minutes":{"type":"integer","example":20},"durationMinutes":{"type":"integer","example":20}}},"ContentMovie":{"type":"object","properties":{"id":{"type":"string","format":"uuid","readOnly":true,"example":"7d13c3a7-07d0-4f99-81a1-fb2efc42d1d8"},"item_type":{"type":"string","example":"movie"},"target_type":{"type":"string","example":"content"},"target_id":{"type":"string","format":"uuid","example":"7d13c3a7-07d0-4f99-81a1-fb2efc42d1d8"},"title":{"$ref":"#/components/schemas/LocalizedText"},"description":{"$ref":"#/components/schemas/LocalizedText"},"content_type":{"type":"string","example":"movie"},"category_id":{"type":"string","nullable":true,"example":"category-id"},"series_id":{"type":"string","nullable":true,"example":"series-id"},"series":{"type":"array","items":{"oneOf":[{"type":"string"},{"$ref":"#/components/schemas/ContentMovie"}]}},"tag_ids":{"type":"array","items":{"type":"string"},"example":["tag-id"]},"tags":{"type":"array","items":{"$ref":"#/components/schemas/ContentTag"}},"is_premium":{"type":"boolean","example":false},"likes_count":{"type":"integer","example":1},"is_liked":{"type":"boolean","example":true},"views_count":{"type":"integer","example":12},"play_count":{"type":"integer","example":12},"watch_time_sec":{"type":"integer","example":420},"last_viewed_at":{"type":"string","format":"date-time","nullable":true},"series_views_count":{"type":"integer","example":48,"description":"Aggregated view count from episodes linked in this movie's series array."},"series_watch_time_sec":{"type":"integer","example":3600,"description":"Aggregated watch time from episodes linked in this movie's series array."},"series_last_viewed_at":{"type":"string","format":"date-time","nullable":true},"poster_url":{"type":"string","nullable":true,"example":"/media/uploads/poster.png"},"poster":{"type":"object","nullable":true,"properties":{"url":{"type":"string","nullable":true,"example":"/media/uploads/poster.png"},"storage_path":{"type":"string","nullable":true},"original_name":{"type":"string","nullable":true,"example":"poster.png"},"mime_type":{"type":"string","nullable":true,"example":"image/png"},"size":{"type":"integer","nullable":true,"example":250000}}},"source":{"type":"string","nullable":true,"example":"/media/uploads/movie.mp4"},"video_url":{"type":"string","nullable":true,"example":"/media/uploads/movie.mp4"},"storage_path":{"type":"string","nullable":true},"transcode_status":{"type":"string","example":"queued"},"transcode_error":{"type":"string","nullable":true,"example":"ffmpeg exited with code 1","description":"Latest transcoder error. Admin UI can show this as a tooltip when transcode_status/status is failed."},"status_error":{"type":"string","nullable":true,"example":"ffmpeg exited with code 1","description":"Alias for transcode_error for status tooltips."},"error_message":{"type":"string","nullable":true,"example":"ffmpeg exited with code 1","description":"Alias for transcode_error for table UIs."},"age_rating":{"type":"integer","example":6},"duration_sec":{"type":"integer","example":1234,"description":"Video duration in seconds. For uploaded videos, the backend tries to read it with ffprobe."},"duration_seconds":{"type":"integer","example":1234},"durationSec":{"type":"integer","example":1234},"duration":{"type":"number","nullable":true,"example":1234},"duration_minutes":{"type":"integer","example":21},"durationMinutes":{"type":"integer","example":21},"year":{"type":"integer","nullable":true,"example":2026},"published":{"type":"boolean","example":false},"published_at":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time","nullable":true},"updatedAt":{"type":"string","format":"date-time","nullable":true},"media":{"type":"object","properties":{"has_source":{"type":"boolean","example":true},"original_name":{"type":"string","nullable":true,"example":"movie.mp4"},"mime_type":{"type":"string","nullable":true,"example":"video/mp4"},"size":{"type":"integer","nullable":true,"example":1024000},"storage_path":{"type":"string","nullable":true}}},"playback":{"type":"object","properties":{"type":{"type":"string","example":"hls"},"status":{"type":"string","example":"queued"},"hls_url":{"type":"string","nullable":true,"example":"/media/hls/movie_id/master.m3u8"},"auto_url":{"type":"string","nullable":true,"example":"/media/hls/movie_id/master.m3u8"},"qualities":{"type":"array","items":{"type":"string"},"example":["auto","360","480","720","1080"]},"renditions":{"type":"array","items":{"type":"object","properties":{"quality":{"type":"string","example":"720"},"label":{"type":"string","example":"720p"},"width":{"type":"integer","nullable":true,"example":1280},"height":{"type":"integer","nullable":true,"example":720},"bitrate":{"type":"integer","nullable":true,"example":2800000},"playlist_url":{"type":"string","nullable":true,"example":"/media/hls/movie_id/720p/index.m3u8"}}}},"error":{"type":"string","nullable":true}}}}},"LikeStatus":{"type":"object","properties":{"liked":{"type":"boolean","example":true},"content_id":{"type":"string","example":"7d13c3a7-07d0-4f99-81a1-fb2efc42d1d8"},"target_type":{"type":"string","example":"content"},"target_id":{"type":"string","example":"7d13c3a7-07d0-4f99-81a1-fb2efc42d1d8"},"item_type":{"type":"string","example":"movie"},"likes_count":{"type":"integer","example":1},"is_liked":{"type":"boolean","example":true}}},"ContentBlacklistStatus":{"type":"object","properties":{"blacklisted":{"type":"boolean","example":true},"is_blacklisted":{"type":"boolean","example":true},"content_id":{"type":"string","example":"7d13c3a7-07d0-4f99-81a1-fb2efc42d1d8"},"target_type":{"type":"string","example":"content"},"target_id":{"type":"string","example":"7d13c3a7-07d0-4f99-81a1-fb2efc42d1d8"},"item_type":{"type":"string","example":"movie"},"childId":{"type":"string","example":"b219a2f6-0670-44ed-8e18-57f887bd4e94"},"child_id":{"type":"string","example":"b219a2f6-0670-44ed-8e18-57f887bd4e94"},"deleted":{"type":"boolean","example":false},"blacklist_item":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/ChildContentBlacklistItem"}]}}},"ContentStatus":{"type":"string","enum":["uploaded","transcoding","ready","failed"],"example":"uploaded"},"Content":{"type":"object","properties":{"age_rating":{"type":"integer"},"category_id":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"created_by_id":{"type":"string"},"description":{"$ref":"#/components/schemas/LocalizedText"},"duration_sec":{"type":"integer"},"episode_number":{"type":"integer"},"id":{"type":"string"},"poster_url":{"type":"string"},"published":{"type":"boolean"},"published_at":{"type":"string","format":"date-time"},"season_number":{"type":"integer"},"series_id":{"type":"string"},"slug":{"type":"string"},"source_path":{"type":"string","description":"relative under STORAGE_PATH"},"status":{"$ref":"#/components/schemas/ContentStatus"},"title":{"$ref":"#/components/schemas/LocalizedText"},"updated_at":{"type":"string","format":"date-time"},"views_count":{"type":"integer","description":"ViewsCount is incremented atomically each time a stream grant is issued. It counts grant events (play button presses), not individual HLS segments."},"year":{"type":"integer"}}},"Tariff":{"type":"object","properties":{"id":{"type":"string","example":"free"},"code":{"type":"string","example":"free"},"title":{"$ref":"#/components/schemas/LocalizedText"},"description":{"$ref":"#/components/schemas/LocalizedText"},"is_default":{"type":"boolean","example":true},"can_watch_premium":{"type":"boolean","example":false},"price":{"type":"string","example":"49000.00"},"price_cents":{"type":"integer","example":4900000},"currency":{"type":"string","example":"UZS"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"TariffStatus":{"type":"object","properties":{"tariff":{"$ref":"#/components/schemas/Tariff"},"subscription":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/Subscription"}]},"access":{"type":"object","properties":{"can_watch_premium":{"type":"boolean","example":false}}}}},"Subscription":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"parentId":{"type":"string"},"tariffId":{"type":"string","example":"premium"},"provider":{"type":"string","enum":["apple","google","click"],"example":"click"},"providerSubscriptionId":{"type":"string","example":"1000001234567890"},"status":{"type":"string","enum":["active","grace_period","expired","cancelled"],"example":"active"},"startedAt":{"type":"string","format":"date-time"},"expiresAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"BillingPurchaseResponse":{"type":"object","properties":{"subscription":{"$ref":"#/components/schemas/Subscription"},"tariff":{"$ref":"#/components/schemas/Tariff"},"access":{"type":"object","properties":{"can_watch_premium":{"type":"boolean","example":true}}}}},"PaymentProvider":{"type":"string","enum":["click","payme","stripe","manual"],"example":"click"},"TransactionKind":{"type":"string","enum":["subscription","topup","refund"],"example":"subscription"},"TransactionStatus":{"type":"string","enum":["pending","succeeded","failed","refunded","canceled"],"example":"pending"},"Card":{"type":"object","properties":{"brand":{"type":"string","example":"visa"},"created_at":{"type":"string","format":"date-time"},"expiry_month":{"type":"integer","example":3},"expiry_year":{"type":"integer","example":2027},"holder_name":{"type":"string","example":"Alisher Karimov"},"id":{"type":"string"},"is_default":{"type":"boolean","example":true},"masked_pan":{"type":"string","example":"8600****1234"},"provider":{"$ref":"#/components/schemas/PaymentProvider"},"updated_at":{"type":"string","format":"date-time"},"user_id":{"type":"string"},"verified_at":{"type":"string","format":"date-time"}}},"Transaction":{"type":"object","properties":{"amount":{"type":"string","example":"49000.00"},"amount_cents":{"type":"integer","example":10000},"card_id":{"type":"string"},"checkout_url":{"type":"string"},"click_paydoc_id":{"type":"string"},"click_trans_id":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"currency":{"type":"string","example":"UZS"},"description":{"type":"string"},"fiscal_sent_at":{"type":"string","format":"date-time"},"id":{"type":"string"},"kind":{"$ref":"#/components/schemas/TransactionKind"},"merchant_confirm_id":{"type":"integer"},"merchant_prepare_id":{"type":"integer"},"parentId":{"type":"string"},"plan_id":{"type":"string"},"processed_at":{"type":"string","format":"date-time"},"provider":{"$ref":"#/components/schemas/PaymentProvider"},"provider_ref":{"type":"string"},"status":{"$ref":"#/components/schemas/TransactionStatus"},"subscription_id":{"type":"string"},"tariffId":{"type":"string"},"updated_at":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"user_id":{"type":"string"}}},"TxListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Transaction"}},"limit":{"type":"integer"},"offset":{"type":"integer"},"total":{"type":"integer"}}},"CardTokenRequestResult":{"type":"object","properties":{"card_id":{"type":"string"},"phone_number":{"type":"string"}}},"CheckoutResult":{"type":"object","properties":{"checkout_url":{"type":"string"},"payment_url":{"type":"string"},"deeplink_url":{"type":"string"},"subscription":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/Subscription"}]},"transaction":{"$ref":"#/components/schemas/Transaction"},"tariff":{"$ref":"#/components/schemas/Tariff"}}},"ClickCheckoutRequest":{"type":"object","required":["tariff_id"],"properties":{"tariff_id":{"type":"string","example":"premium"},"tariffId":{"type":"string","description":"Alias for tariff_id.","example":"premium"},"plan_id":{"type":"string","description":"Alias for tariff_id.","example":"premium"},"amount":{"type":"number","example":49000,"description":"Optional compatibility field. Backend uses the tariff price and rejects mismatched amounts."},"amount_uzs":{"type":"number","example":49000,"description":"Alias for amount."},"amountUzs":{"type":"number","example":49000,"description":"Alias for amount."},"return_url":{"type":"string","example":"https://astir.example/payments/return"},"returnUrl":{"type":"string","description":"Alias for return_url."},"card_type":{"type":"string","enum":["uzcard","humo"],"example":"uzcard"},"cardType":{"type":"string","description":"Alias for card_type."},"expires_at":{"type":"string","format":"date-time"},"expiresAt":{"type":"string","format":"date-time","description":"Alias for expires_at."}}},"ClickCallbackResponse":{"type":"object","properties":{"click_trans_id":{"type":"integer","example":123456789},"merchant_trans_id":{"type":"string","example":"transaction-id"},"merchant_prepare_id":{"type":"integer","example":123456},"merchant_confirm_id":{"type":"integer","example":123457},"error":{"type":"integer","example":0},"error_note":{"type":"string","example":"Success"}}},"ClickPaymentStatusResult":{"type":"object","properties":{"paymentID":{"type":"integer"},"paymentStatus":{"type":"integer"}}},"SeriesKind":{"type":"string","enum":["seasons","episodes"],"example":"seasons"},"Series":{"type":"object","properties":{"active":{"type":"boolean","example":true},"created_at":{"type":"string","format":"date-time"},"description":{"$ref":"#/components/schemas/LocalizedText"},"id":{"type":"string"},"item_type":{"type":"string","example":"series"},"target_type":{"type":"string","example":"series"},"target_id":{"type":"string","example":"series-id"},"kind":{"$ref":"#/components/schemas/SeriesKind"},"likes_count":{"type":"integer","example":1},"is_liked":{"type":"boolean","example":true},"poster_url":{"type":"string"},"slug":{"type":"string"},"title":{"$ref":"#/components/schemas/LocalizedText"},"updated_at":{"type":"string","format":"date-time"}}},"SeriesRequest":{"type":"object","required":["title"],"properties":{"active":{"type":"boolean"},"description":{"$ref":"#/components/schemas/LocalizedText"},"kind":{"$ref":"#/components/schemas/SeriesKind"},"title":{"$ref":"#/components/schemas/LocalizedText"}}},"FAQ":{"type":"object","properties":{"active":{"type":"boolean"},"answer":{"$ref":"#/components/schemas/LocalizedText"},"created_at":{"type":"string","format":"date-time"},"id":{"type":"string"},"question":{"$ref":"#/components/schemas/LocalizedText"},"sort_order":{"type":"integer"},"updated_at":{"type":"string","format":"date-time"}}},"LocalizedFAQ":{"type":"object","properties":{"answer":{"type":"string"},"id":{"type":"string"},"question":{"type":"string"},"sort_order":{"type":"integer"}}},"FAQRequest":{"type":"object","required":["answer","question"],"properties":{"active":{"type":"boolean"},"answer":{"$ref":"#/components/schemas/LocalizedText"},"question":{"$ref":"#/components/schemas/LocalizedText"},"sort_order":{"type":"integer"}}},"SupportSenderRole":{"type":"string","enum":["user","admin"],"example":"user"},"SupportChat":{"type":"object","properties":{"admin_unread_count":{"type":"integer"},"created_at":{"type":"string","format":"date-time"},"id":{"type":"string"},"last_message_at":{"type":"string","format":"date-time"},"last_message_preview":{"type":"string"},"updated_at":{"type":"string","format":"date-time"},"user":{"$ref":"#/components/schemas/LegacyUser"},"user_id":{"type":"string"},"user_unread_count":{"type":"integer"}}},"SupportMessage":{"type":"object","properties":{"attachment_name":{"type":"string"},"attachment_size":{"type":"integer"},"attachment_type":{"type":"string"},"attachment_url":{"type":"string"},"body":{"type":"string"},"chat_id":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"id":{"type":"string"},"sender":{"$ref":"#/components/schemas/LegacyUser"},"sender_id":{"type":"string"},"sender_role":{"$ref":"#/components/schemas/SupportSenderRole"},"updated_at":{"type":"string","format":"date-time"}}},"UsersListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/LegacyUser"}},"limit":{"type":"integer"},"offset":{"type":"integer"},"total":{"type":"integer"}}},"CreateStaffRequest":{"type":"object","required":["email","name","password","role"],"properties":{"email":{"type":"string"},"name":{"type":"string"},"password":{"type":"string","minLength":8},"role":{"type":"string","enum":["admin","super_admin"]}}},"UpdateUserRequest":{"type":"object","required":["last_name","name","role"],"properties":{"last_name":{"type":"string"},"name":{"type":"string"},"role":{"type":"string","enum":["super_admin","admin","parent"]}}},"AssignPlanRequest":{"type":"object","properties":{"duration_days":{"type":"integer"},"durationDays":{"type":"integer","description":"Alias for duration_days."},"plan_id":{"type":"string","description":"Legacy plan id, slug, or package_code."},"planId":{"type":"string","description":"Alias for plan_id."},"tariff_id":{"type":"string","description":"v1 tariff id accepted for admin compatibility."},"tariffId":{"type":"string","description":"Alias for tariff_id."}}},"CardRequest":{"type":"object","required":["expiry_month","expiry_year","holder_name","pan","provider"],"properties":{"cvc":{"type":"string"},"expiry_month":{"type":"integer"},"expiry_year":{"type":"integer"},"holder_name":{"type":"string"},"pan":{"type":"string","example":"8600123412341234"},"provider":{"type":"string","enum":["click","payme","stripe"],"example":"click"}}},"ClickCardTokenRequestBody":{"type":"object","required":["expire_date","pan"],"properties":{"expire_date":{"type":"string","example":"0327"},"pan":{"type":"string","example":"8600550000003244"}}},"ClickCardTokenVerifyBody":{"type":"object","required":["card_id","sms_code"],"properties":{"card_id":{"type":"string"},"sms_code":{"type":"integer"}}},"CheckoutRequest":{"type":"object","required":["plan_id","provider"],"properties":{"card_id":{"type":"string"},"plan_id":{"type":"string"},"provider":{"type":"string","enum":["click","payme","stripe"],"example":"click"}}},"DeeplinkCheckoutRequest":{"type":"object","required":["plan_id"],"properties":{"plan_id":{"type":"string"}}},"RecurringChargeRequest":{"type":"object","required":["card_id","plan_id"],"properties":{"card_id":{"type":"string"},"plan_id":{"type":"string"}}}},"responses":{"BadRequest":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"Unauthorized":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"Forbidden":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"NotFound":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"Conflict":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"ServiceUnavailable":{"description":"Service unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"paths":{"/health":{"get":{"tags":["Health"],"summary":"Check server status","responses":{"200":{"description":"Server is running","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"ok"}}}}}}}}},"/v1/faqs":{"get":{"tags":["FAQ"],"summary":"List public FAQs","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LocalizedFAQ"}}}}}}}},"/v1/admin/faqs":{"get":{"tags":["FAQ"],"summary":"List all FAQs (admin)","security":[{"legacyBearer":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/FAQ"}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}},"post":{"tags":["FAQ"],"summary":"Create a FAQ entry","security":[{"legacyBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FAQRequest"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FAQ"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/v1/admin/faqs/{id}":{"put":{"tags":["FAQ"],"summary":"Update a FAQ entry","security":[{"legacyBearer":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FAQRequest"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FAQ"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}},"delete":{"tags":["FAQ"],"summary":"Delete a FAQ entry","security":[{"legacyBearer":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegacyOkResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/v1/support/attachments/{path}":{"get":{"tags":["Support"],"summary":"Serve a support chat attachment","security":[{"legacyBearer":[]}],"parameters":[{"name":"path","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/v1/support/chat":{"get":{"tags":["Support"],"summary":"Get the current user's support chat","security":[{"legacyBearer":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupportChat"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/v1/support/chat/messages":{"get":{"tags":["Support"],"summary":"List messages in the current user's support chat","description":"Returns messages ordered ascending by time. Use after to poll for new messages or before to load older history.","security":[{"legacyBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer"}},{"name":"before","in":"query","required":false,"schema":{"type":"string"}},{"name":"after","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"post":{"tags":["Support"],"summary":"Send a message in the current user's support chat","security":[{"legacyBearer":[]}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"body":{"type":"string"},"message":{"type":"string","description":"Alias for body."},"text":{"type":"string","description":"Alias for body."},"content":{"type":"string","description":"Alias for body."}}}},"multipart/form-data":{"schema":{"type":"object","properties":{"body":{"type":"string"},"message":{"type":"string","description":"Alias for body."},"text":{"type":"string","description":"Alias for body."},"content":{"type":"string","description":"Alias for body."},"file":{"type":"string","format":"binary"}}}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupportMessage"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/v1/support/chat/read":{"post":{"tags":["Support"],"summary":"Mark the user's support chat as read","security":[{"legacyBearer":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegacyOkResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/v1/admin/support/chats":{"get":{"tags":["Support"],"summary":"List support chats (admin)","security":[{"legacyBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/v1/admin/support/chats/{id}":{"get":{"tags":["Support"],"summary":"Get a support chat (admin)","security":[{"legacyBearer":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupportChat"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/v1/admin/support/chats/{id}/messages":{"get":{"tags":["Support"],"summary":"List messages in a support chat (admin)","security":[{"legacyBearer":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer"}},{"name":"before","in":"query","required":false,"schema":{"type":"string"}},{"name":"after","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}},"post":{"tags":["Support"],"summary":"Reply in a support chat (admin)","security":[{"legacyBearer":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"body":{"type":"string"},"message":{"type":"string","description":"Alias for body."},"text":{"type":"string","description":"Alias for body."},"content":{"type":"string","description":"Alias for body."}}}},"multipart/form-data":{"schema":{"type":"object","properties":{"body":{"type":"string"},"message":{"type":"string","description":"Alias for body."},"text":{"type":"string","description":"Alias for body."},"content":{"type":"string","description":"Alias for body."},"file":{"type":"string","format":"binary"}}}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupportMessage"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/v1/admin/support/chats/{id}/read":{"post":{"tags":["Support"],"summary":"Mark a support chat as read on the admin side","security":[{"legacyBearer":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegacyOkResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}}}}