{"openapi":"3.1.0","info":{"title":"OPEN60 VPN API","version":"5.2.0"},"paths":{"/video.mp4":{"get":{"summary":"Video","operationId":"video_video_mp4_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/favicon.ico":{"get":{"summary":"Favicon","operationId":"favicon_favicon_ico_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/health":{"get":{"summary":"Health","operationId":"health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/session/create":{"post":{"summary":"Session Create","operationId":"session_create_session_create_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionCreateRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/session/refresh":{"post":{"summary":"Session Refresh","operationId":"session_refresh_session_refresh_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionRefreshRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/session/destroy":{"post":{"summary":"Session Destroy","description":"Destroy session (cleanup Redis only)\n\nv5.2: Does NOT notify node - port lives until TTL (6h) on agent.","operationId":"session_destroy_session_destroy_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/session/status":{"get":{"summary":"Session Status","description":"v5.0: Check session status and handle migration\n\nReturns migration object if session expires in < 30 minutes:\n- Creates new session on (possibly different) node\n- Returns new tokens and proxy details\n- Client should switch seamlessly","operationId":"session_status_session_status_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/countries":{"get":{"summary":"Get Countries","operationId":"get_countries_countries_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/premium/status":{"get":{"summary":"Premium Status","operationId":"premium_status_premium_status_get","parameters":[{"name":"install_id","in":"query","required":true,"schema":{"type":"string","title":"Install Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/billing/webhook":{"post":{"summary":"Billing Webhook","description":"Обработка webhook от Wata","operationId":"billing_webhook_billing_webhook_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/billing/create":{"post":{"summary":"Billing Create","description":"Старый URL, который уже захардкожен в опубликованном расширении.\n\nv5.24: раньше здесь была интеграция с Wata, теперь — с Platega. Так\nрасширение переключается на нового провайдера без переиздания и без\nожидания ревью Chrome Web Store.","operationId":"billing_create_billing_create_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingCreateRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/billing/create-platega":{"post":{"summary":"Billing Create Platega","description":"Тот же самый Platega, явный URL — на случай будущей версии расширения.","operationId":"billing_create_platega_billing_create_platega_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingCreateRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/billing/webhook-platega":{"post":{"summary":"Billing Webhook Platega","description":"Приём колбэков Platega.\n\nАутентификация — заголовки X-MerchantId и X-Secret, которые Platega\nприсылает вместе с телом. Сверяем ОБА и строго: ровно та же ошибка\n(необязательная проверка подписи) в вебхуке Wata позволяла кому угодно\nактивировать себе премиум бесплатно.\n\nТело: {id, amount, currency, status, paymentMethod}\nСтатусы: CONFIRMED (успех) / CANCELED (неуспех) / CHARGEBACKED (возврат)","operationId":"billing_webhook_platega_billing_webhook_platega_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/billing/return":{"get":{"summary":"Billing Return","operationId":"billing_return_billing_return_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/admin/nodes":{"get":{"summary":"Admin List Nodes","operationId":"admin_list_nodes_admin_nodes_get","parameters":[{"name":"country","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"summary":"Admin Create Node","operationId":"admin_create_node_admin_nodes_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProxyNodeCreate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/nodes/{node_id}":{"get":{"summary":"Admin Get Node","operationId":"admin_get_node_admin_nodes__node_id__get","parameters":[{"name":"node_id","in":"path","required":true,"schema":{"type":"integer","title":"Node Id"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"summary":"Admin Update Node","operationId":"admin_update_node_admin_nodes__node_id__put","parameters":[{"name":"node_id","in":"path","required":true,"schema":{"type":"integer","title":"Node Id"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProxyNodeUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"summary":"Admin Delete Node","operationId":"admin_delete_node_admin_nodes__node_id__delete","parameters":[{"name":"node_id","in":"path","required":true,"schema":{"type":"integer","title":"Node Id"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/nodes/{node_id}/pool":{"get":{"summary":"Admin Get Node Pool","description":"Get detailed hot pool status from node agent","operationId":"admin_get_node_pool_admin_nodes__node_id__pool_get","parameters":[{"name":"node_id","in":"path","required":true,"schema":{"type":"integer","title":"Node Id"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/nodes/{node_id}/pool/refresh":{"post":{"summary":"Admin Refresh Node Pool","description":"Force refresh of hot pool on node","operationId":"admin_refresh_node_pool_admin_nodes__node_id__pool_refresh_post","parameters":[{"name":"node_id","in":"path","required":true,"schema":{"type":"integer","title":"Node Id"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/nodes/{node_id}/health-check":{"post":{"summary":"Admin Node Health Check","description":"Check health of a specific node","operationId":"admin_node_health_check_admin_nodes__node_id__health_check_post","parameters":[{"name":"node_id","in":"path","required":true,"schema":{"type":"integer","title":"Node Id"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/nodes/health-check-all":{"post":{"summary":"Admin Nodes Health Check All","description":"Check health of all active nodes","operationId":"admin_nodes_health_check_all_admin_nodes_health_check_all_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/nodes/stats":{"get":{"summary":"Admin Nodes Stats","operationId":"admin_nodes_stats_admin_nodes_stats_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/licenses":{"get":{"summary":"Admin List Licenses","operationId":"admin_list_licenses_admin_licenses_get","parameters":[{"name":"active_only","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Active Only"}},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Search"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"date_from","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Date From"}},{"name":"date_to","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Date To"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/licenses/{install_id}":{"get":{"summary":"Admin Get License","operationId":"admin_get_license_admin_licenses__install_id__get","parameters":[{"name":"install_id","in":"path","required":true,"schema":{"type":"string","title":"Install Id"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/licenses/activate":{"post":{"summary":"Admin Activate License","operationId":"admin_activate_license_admin_licenses_activate_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LicenseActivateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/licenses/cancel":{"post":{"summary":"Admin Cancel License","operationId":"admin_cancel_license_admin_licenses_cancel_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LicenseCancelRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/payments":{"get":{"summary":"Admin List Payments","operationId":"admin_list_payments_admin_payments_get","parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"install_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Install Id"}},{"name":"payment_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Payment Id"}},{"name":"date_from","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Date From"}},{"name":"date_to","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Date To"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/payments/stats":{"get":{"summary":"Admin Payments Stats","operationId":"admin_payments_stats_admin_payments_stats_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/audit":{"get":{"summary":"Admin Audit Logs","operationId":"admin_audit_logs_admin_audit_get","parameters":[{"name":"event_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Event Type"}},{"name":"install_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Install Id"}},{"name":"ip","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ip"}},{"name":"date_from","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Date From"}},{"name":"date_to","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Date To"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/stats":{"get":{"summary":"Admin Stats","operationId":"admin_stats_admin_stats_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin":{"get":{"summary":"Admin Page","description":"Serve admin dashboard HTML","operationId":"admin_page_admin_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/admin/sessions/active":{"get":{"summary":"Admin Active Sessions","description":"v5.0: Get detailed list of active sessions\n\nv5.15: результат кешируется на ACTIVE_SESSIONS_CACHE_TTL секунд —\nсм. комментарий у _ACTIVE_SESSIONS_CACHE_TTL.","operationId":"admin_active_sessions_admin_sessions_active_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/analytics/payments/daily":{"get":{"summary":"Analytics Payments Daily","description":"Payment analytics by day for last N days\n\nReturns:\n    - Date series\n    - Count per day\n    - Amount per day (RUB)\n    - Cumulative revenue","operationId":"analytics_payments_daily_admin_analytics_payments_daily_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","default":30,"title":"Days"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/analytics/payments/by-status":{"get":{"summary":"Analytics Payments By Status","description":"Payment distribution by status","operationId":"analytics_payments_by_status_admin_analytics_payments_by_status_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","default":30,"title":"Days"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/analytics/payments/by-method":{"get":{"summary":"Analytics Payments By Method","description":"Payment distribution by payment method","operationId":"analytics_payments_by_method_admin_analytics_payments_by_method_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","default":30,"title":"Days"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/analytics/licenses/expiration":{"get":{"summary":"Analytics Licenses Expiration","description":"License expiration timeline\n\nShows how many licenses expire in next periods:\n- Expired\n- Next 7 days\n- 8-14 days\n- 15-30 days\n- 31-60 days\n- 60+ days","operationId":"analytics_licenses_expiration_admin_analytics_licenses_expiration_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/analytics/licenses/retention":{"get":{"summary":"Analytics Licenses Retention","description":"License retention metrics\n\nShows:\n- New licenses per week\n- Active licenses per week\n- Churn rate","operationId":"analytics_licenses_retention_admin_analytics_licenses_retention_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/analytics/licenses/cohort-revenue":{"get":{"summary":"Analytics Licenses Cohort Revenue","description":"Revenue by license age cohorts\n\nShows how much revenue comes from licenses of different ages","operationId":"analytics_licenses_cohort_revenue_admin_analytics_licenses_cohort_revenue_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/analytics/sessions/timeline":{"get":{"summary":"Analytics Sessions Timeline","description":"Session count timeline (from audit logs)\n\nShows session_created events over time","operationId":"analytics_sessions_timeline_admin_analytics_sessions_timeline_get","parameters":[{"name":"hours","in":"query","required":false,"schema":{"type":"integer","default":24,"title":"Hours"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/analytics/sessions/by-country":{"get":{"summary":"Analytics Sessions By Country","description":"Session distribution by country (from recent audit logs)","operationId":"analytics_sessions_by_country_admin_analytics_sessions_by_country_get","parameters":[{"name":"hours","in":"query","required":false,"schema":{"type":"integer","default":24,"title":"Hours"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/analytics/licenses/mrr":{"get":{"summary":"Analytics Mrr","description":"Monthly Recurring Revenue по месяцам.\n\nСчитает сумму успешных платежей за каждый месяц.\nДополнительно: новые пользователи vs повторные.","operationId":"analytics_mrr_admin_analytics_licenses_mrr_get","parameters":[{"name":"months","in":"query","required":false,"schema":{"type":"integer","default":12,"title":"Months"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/analytics/licenses/churn":{"get":{"summary":"Analytics Churn","description":"Churn rate по месяцам. v3 — переработана логика renewed.\n\nРеальность: пользователи платят каждые ~30 дней, premium_until накапливается вперёд.\nПлатёж ВСЕГДА приходит ДО истечения premium_until — значит искать\np.created_at > premium_until бессмысленно.\n\nПравильная логика:\n- expired = пользователи у которых последний платёж был в данном месяце\n  и с тех пор прошло > 37 дней (30 дней подписки + 7 дней grace period)\n- renewed = те из expired у кого есть ещё один платёж после первого в этом месяце","operationId":"analytics_churn_admin_analytics_licenses_churn_get","parameters":[{"name":"months","in":"query","required":false,"schema":{"type":"integer","default":6,"title":"Months"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/analytics/sessions/by-node":{"get":{"summary":"Analytics Sessions By Node","description":"Distribution of active sessions by node.\nFixed: decode_responses=True → string keys, не bytes.","operationId":"analytics_sessions_by_node_admin_analytics_sessions_by_node_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/analytics/sessions/duration":{"get":{"summary":"Analytics Sessions Duration","description":"Распределение продолжительности сессий из audit_logs.\nТребует: session_destroyed содержит duration_seconds (добавлено в main.py v5.3).\n\nВозвращает:\n- buckets: гистограмма по диапазонам длительности\n- avg/median по premium vs free\n- % \"bounce\" сессий (< 2 минут — пользователь просто протестировал)","operationId":"analytics_sessions_duration_admin_analytics_sessions_duration_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","default":30,"title":"Days"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/analytics/payments/conversion-funnel":{"get":{"summary":"Analytics Payments Conversion Funnel","description":"Воронка конверсии платежей.\n\nПоказывает:\n- Создано платёжных ссылок\n- Оплачено (succeeded)\n- Отклонено (declined)\n- Зависло в pending > 2 часов\n- Конверсия в %\n- Разбивка по методу оплаты","operationId":"analytics_payments_conversion_funnel_admin_analytics_payments_conversion_funnel_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","default":30,"title":"Days"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/analytics/payments/pending-stuck":{"get":{"summary":"Analytics Payments Pending Stuck","description":"Платежи зависшие в статусе pending дольше min_age_minutes минут.\nWebhook не пришёл или потерялся — нужна ручная проверка в Wata.","operationId":"analytics_payments_pending_stuck_admin_analytics_payments_pending_stuck_get","parameters":[{"name":"min_age_minutes","in":"query","required":false,"schema":{"type":"integer","default":120,"title":"Min Age Minutes"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/analytics/users/trial-to-paid":{"get":{"summary":"Analytics Trial To Paid","description":"Trial-to-paid конверсия.\n\nСчитает сколько пользователей, создавших хотя бы одну сессию,\nв итоге совершили платёж. Самая важная product-метрика.\n\nДополнительно: разбивка по времени конверсии (как быстро решают платить).","operationId":"analytics_trial_to_paid_admin_analytics_users_trial_to_paid_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/analytics/licenses/ltv":{"get":{"summary":"Analytics Ltv","description":"Lifetime Value пользователей.\n\n- Average LTV = total_revenue / unique paying users\n- Median LTV\n- Распределение по количеству платежей (1 раз / 2-3 / 4+)","operationId":"analytics_ltv_admin_analytics_licenses_ltv_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/alerts":{"get":{"summary":"Admin Alerts","description":"Единый эндпоинт агрегации тревожных сигналов.\n\nУровни: critical | warning | info\nФронт поллит каждые 60 секунд и показывает badge с числом алертов.","operationId":"admin_alerts_admin_alerts_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/analytics/licenses/active-premium-count":{"get":{"summary":"Analytics Licenses Active Premium Count","description":"#7 Active premium licenses over time — v3 (generate_series, fallback to loop)","operationId":"analytics_licenses_active_premium_count_admin_analytics_licenses_active_premium_count_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","default":90,"title":"Days"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/analytics/nodes/load-timeline":{"get":{"summary":"Analytics Nodes Load Timeline","description":"#2 Node load distribution over time\n\nShows how load is distributed across nodes and countries over time.\nCritical for monitoring load balancing effectiveness.\n\nReturns:\n- timeline: load per node per hour\n- by_country: aggregated load by country\n- current_load: current snapshot\n- balance_score: how evenly distributed the load is (0-100)","operationId":"analytics_nodes_load_timeline_admin_analytics_nodes_load_timeline_get","parameters":[{"name":"hours","in":"query","required":false,"schema":{"type":"integer","default":6,"title":"Hours"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/analytics/nodes/orphan-ports":{"get":{"summary":"Analytics Nodes Orphan Ports","description":"#1 Orphan/Zombie ports analytics\n\nShows difference between Squid open ports and HAProxy allocated ports\nper node over time. Critical for detecting port leaks.\n\nReturns:\n- timeline: hourly snapshots of orphan ports per node\n- current_snapshot: current state of all nodes\n- alerts: nodes with high orphan port count","operationId":"analytics_nodes_orphan_ports_admin_analytics_nodes_orphan_ports_get","parameters":[{"name":"hours","in":"query","required":false,"schema":{"type":"integer","default":24,"title":"Hours"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/analytics/sessions/premium-vs-free":{"get":{"summary":"Analytics Sessions Premium Vs Free","description":"#4 Premium vs Free session analytics\n\nShows resource usage by premium vs free users.\nCritical for understanding monetization vs load.\n\nReturns:\n- distribution: pie chart data (premium vs free counts)\n- timeline: premium % over time\n- avg_ttl: average TTL for premium vs free\n- load_contribution: premium vs free load","operationId":"analytics_sessions_premium_vs_free_admin_analytics_sessions_premium_vs_free_get","parameters":[{"name":"hours","in":"query","required":false,"schema":{"type":"integer","default":24,"title":"Hours"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/pool-status":{"get":{"summary":"Admin Pool Status","description":"v5.1: Get current pool status cache for all nodes\n\nReturns cached pool status with freshness indicator.\nUseful for monitoring the background worker.","operationId":"admin_pool_status_admin_pool_status_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/pool-status/refresh":{"post":{"summary":"Admin Pool Status Refresh","description":"v5.1: Force immediate refresh of pool status cache\n\nUseful for debugging or after node changes.","operationId":"admin_pool_status_refresh_admin_pool_status_refresh_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"BillingCreateRequest":{"properties":{"install_id":{"type":"string","title":"Install Id"}},"type":"object","required":["install_id"],"title":"BillingCreateRequest"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"LicenseActivateRequest":{"properties":{"install_id":{"type":"string","title":"Install Id"},"days":{"type":"integer","title":"Days","default":30},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"}},"type":"object","required":["install_id"],"title":"LicenseActivateRequest"},"LicenseCancelRequest":{"properties":{"install_id":{"type":"string","title":"Install Id"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"}},"type":"object","required":["install_id"],"title":"LicenseCancelRequest"},"ProxyNodeCreate":{"properties":{"ip_address":{"type":"string","title":"Ip Address"},"port_range_start":{"type":"integer","title":"Port Range Start"},"port_range_end":{"type":"integer","title":"Port Range End"},"api_url":{"type":"string","title":"Api Url"},"api_secret":{"type":"string","title":"Api Secret"},"country":{"type":"string","title":"Country","default":"DE"},"city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"City"},"weight":{"type":"integer","title":"Weight","default":100},"max_sessions":{"type":"integer","title":"Max Sessions","default":1000},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"}},"type":"object","required":["ip_address","port_range_start","port_range_end","api_url","api_secret"],"title":"ProxyNodeCreate"},"ProxyNodeUpdate":{"properties":{"ip_address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ip Address"},"port_range_start":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Port Range Start"},"port_range_end":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Port Range End"},"api_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Api Url"},"api_secret":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Api Secret"},"country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country"},"city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"City"},"weight":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Weight"},"max_sessions":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Sessions"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"is_active":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Active"},"is_healthy":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Healthy"}},"type":"object","title":"ProxyNodeUpdate"},"SessionCreateRequest":{"properties":{"install_id":{"type":"string","title":"Install Id"},"country":{"type":"string","title":"Country","default":"de"}},"type":"object","required":["install_id"],"title":"SessionCreateRequest"},"SessionRefreshRequest":{"properties":{"refresh_token":{"type":"string","title":"Refresh Token"}},"type":"object","required":["refresh_token"],"title":"SessionRefreshRequest"},"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"}}}}