{"ok": true, "docs": {"name": "Tigr.pro Public API", "version": "v1", "spec_version": "1.2.0", "base_url": "https://tigr.pro/api/v1", "openai_base_url": "https://tigr.pro/api/v1/openai", "auth": {"type": "bearer_token", "header": "Authorization: Bearer <token>", "token_lifecycle": ["\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0442\u043e\u043a\u0435\u043d \u0432 \u043a\u0430\u0431\u0438\u043d\u0435\u0442\u0435 (/cabinet/) \u0438\u043b\u0438 \u0447\u0435\u0440\u0435\u0437 /auth/login/", "Use token in all protected endpoints", "Refresh rotates token and invalidates old one", "Logout / revoke in cabinet invalidates token"]}, "differentiators": ["\u0412\u0435\u0431-\u0441\u0442\u0443\u0434\u0438\u044f + API \u043d\u0430 \u043e\u0434\u043d\u043e\u043c \u0431\u0430\u043b\u0430\u043d\u0441\u0435 \u0432 \u0440\u0443\u0431\u043b\u044f\u0445 (\u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043b\u044e\u0447 \u043a\u0430\u043a \u0443 RouterAI/KupiAPI)", "OpenAI-\u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u044b\u0439 chat/completions \u0434\u043b\u044f SDK / Cursor / n8n", "\u0421\u0442\u0443\u0434\u0438\u044f: \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u0432\u0438\u0434\u0435\u043e, \u0430\u0443\u0434\u0438\u043e, \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0440\u043e\u043c\u043f\u0442\u044b", "\u0412\u0438\u0434\u0435\u043e\u0441\u0442\u0443\u0434\u0438\u044f (\u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439 \u2192 \u043a\u0430\u0434\u0440\u044b \u2192 \u0440\u043e\u043b\u0438\u043a) \u0432 \u0432\u0435\u0431-\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435", "\u0425\u0430\u0431\u044b ChatGPT / GPT Image / Flux / Kling / Suno \u0438 \u0433\u0430\u0439\u0434\u044b \u00ab\u041e \u043d\u0435\u0439\u0440\u043e\u0441\u0435\u0442\u044f\u0445\u00bb"], "platform_notes": {"desktop_windows_mac": "Use HTTPS + JSON; keep token in OS keychain/secure storage.", "android": "Use EncryptedSharedPreferences/Keystore for token.", "ios": "Use Keychain for token.", "all_clients": "Call only this backend API over HTTPS; do not call upstream providers directly.", "openai_sdk": "OpenAI(base_url=\"https://tigr.pro/api/v1/openai\", api_key=\"<token from cabinet>\"). \u041c\u043e\u0434\u0435\u043b\u0438: GET /api/v1/openai/models (id = model_id \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0430)."}, "endpoints": [{"method": "POST", "path": "/auth/register/", "auth_required": false, "content_type": "application/json", "body": {"email": "user@example.com", "password": "Secret123!", "first_name": "Ivan", "last_name": "Ivanov"}, "returns": "token + user OR requires_email_verification=true"}, {"method": "POST", "path": "/auth/login/", "auth_required": false, "content_type": "application/json", "body": {"email": "user@example.com", "password": "Secret123!"}, "returns": "token + user"}, {"method": "POST", "path": "/auth/refresh/", "auth_required": true, "returns": "new token, old token invalidated"}, {"method": "POST", "path": "/auth/logout/", "auth_required": true, "returns": "current token invalidated"}, {"method": "GET", "path": "/profile/", "auth_required": true, "returns": "current user + balance"}, {"method": "GET", "path": "/services/", "auth_required": true, "returns": "all active services with descriptions"}, {"method": "GET", "path": "/app/config/", "auth_required": false, "returns": "site url + latest versions/links by platform"}, {"method": "GET", "path": "/app/check-update/?platform=android&current_version=1.0.0", "auth_required": false, "returns": "update decision for platform"}, {"method": "GET", "path": "/studio/models/?category=image&recommended=1", "auth_required": true, "returns": "catalog models (up to 200)"}, {"method": "GET", "path": "/studio/models/{model_pk}/", "auth_required": true, "returns": "model detail + form fields"}, {"method": "GET", "path": "/studio/prompts/?category=image", "auth_required": true, "returns": "universal prompts for category (id, name, char_count)"}, {"method": "POST", "path": "/studio/create/", "auth_required": true, "content_type": "application/json", "body": {"model_id": "openai/gpt-image-1.5", "prompt": "\u043a\u043e\u0442 \u0432 \u043a\u043e\u0441\u043c\u043e\u0441\u0435", "params": {"aspect_ratio": "1:1"}, "universal_prompt_ids": [1, 2]}, "returns": "task (poll /studio/status/{id}/)"}, {"method": "GET", "path": "/studio/status/{task_id}/", "auth_required": true, "returns": "task status + result urls/text"}, {"method": "GET", "path": "/studio/list/?limit=20", "auth_required": true, "returns": "user studio tasks"}, {"method": "GET", "path": "/chat/rooms/", "auth_required": true, "returns": "chat rooms list"}, {"method": "POST", "path": "/chat/rooms/create/", "auth_required": true, "content_type": "application/json", "body": {"name": "\u041d\u043e\u0432\u044b\u0439 \u0447\u0430\u0442", "polza_model_id": 123}, "returns": "created room"}, {"method": "GET", "path": "/chat/messages/{room_id}/?limit=50", "auth_required": true, "returns": "messages in room"}, {"method": "POST", "path": "/chat/send/{room_id}/", "auth_required": true, "content_type": "application/json", "body": {"content": "\u041f\u0440\u0438\u0432\u0435\u0442!"}, "returns": "queued task_id"}, {"method": "GET", "path": "/chat/status/{task_id}/{room_id}/", "auth_required": true, "returns": "pending/completed with ai message"}, {"method": "GET", "path": "/openai/models", "auth_required": true, "returns": "OpenAI-shaped list of chat models"}, {"method": "POST", "path": "/openai/chat/completions", "auth_required": true, "content_type": "application/json", "body": {"model": "deepseek/deepseek-r1", "messages": [{"role": "user", "content": "\u041f\u0440\u0438\u0432\u0435\u0442"}], "stream": false}, "returns": "OpenAI chat.completion (+ usage.cost_rub)"}, {"method": "GET", "path": "/payments/methods/", "auth_required": true, "returns": "available payment methods and limits"}, {"method": "POST", "path": "/payments/create/", "auth_required": true, "content_type": "application/json", "headers": {"Idempotency-Key": "<uuid-v4 optional but recommended>"}, "body": {"amount": 500, "method": "robokassa | yookassa | tkassa"}, "returns": "payment + payment_url (generated server-side)"}, {"method": "GET", "path": "/payments/list/?limit=20", "auth_required": true, "returns": "payment history"}, {"method": "GET", "path": "/payments/status/{payment_id}/", "auth_required": true, "returns": "payment status"}], "response_contract": {"success": {"ok": true}, "error": {"ok": false, "error": {"code": "string", "message": "string"}}, "openai_compat": "\u042d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u044b /openai/* \u043e\u0442\u0434\u0430\u044e\u0442 \u0444\u043e\u0440\u043c\u0430\u0442 OpenAI (\u0431\u0435\u0437 \u043e\u0431\u0451\u0440\u0442\u043a\u0438 ok/error)."}, "recommended_client_flow": ["1) \u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0442\u043e\u043a\u0435\u043d \u0432 \u043a\u0430\u0431\u0438\u043d\u0435\u0442\u0435 \u0438\u043b\u0438 login/register; \u0445\u0440\u0430\u043d\u0438\u0442\u0435 \u0432 secure storage.", "2) \u0414\u043b\u044f \u0447\u0430\u0442\u0430 \u0432 SDK: base_url=.../api/v1/openai + Bearer token.", "3) \u0414\u043b\u044f \u043a\u0430\u0440\u0442\u0438\u043d\u043e\u043a/\u0432\u0438\u0434\u0435\u043e/\u0430\u0443\u0434\u0438\u043e: /studio/models \u2192 /studio/create \u2192 poll /studio/status.", "4) Poll status \u043a\u0430\u0436\u0434\u044b\u0435 2\u20133 \u0441 \u0434\u043e completed/failed.", "5) On 401 refresh token (\u0438\u043b\u0438 \u043d\u043e\u0432\u044b\u0439 \u0442\u043e\u043a\u0435\u043d \u0432 \u043a\u0430\u0431\u0438\u043d\u0435\u0442\u0435).", "6) \u041f\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435: /payments/methods \u2192 /payments/create."], "client_examples": [{"title": "OpenAI Python SDK (\u0447\u0430\u0442)", "code": "from openai import OpenAI\nclient = OpenAI(base_url=\"https://tigr.pro/api/v1/openai\", api_key=\"YOUR_TOKEN\")\nr = client.chat.completions.create(\n    model=\"deepseek/deepseek-r1\",\n    messages=[{\"role\": \"user\", \"content\": \"\u041f\u0440\u0438\u0432\u0435\u0442\"}],\n)\nprint(r.choices[0].message.content)"}, {"title": "\u0421\u0442\u0443\u0434\u0438\u044f: \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0437\u0430\u0434\u0430\u043d\u0438\u0435", "code": "POST /api/v1/studio/create/\nAuthorization: Bearer YOUR_TOKEN\n{\"model_id\":\"openai/gpt-image-1.5\",\"prompt\":\"\u043a\u043e\u0442 \u0432 \u043a\u043e\u0441\u043c\u043e\u0441\u0435\",\"params\":{\"aspect_ratio\":\"1:1\"}}\n\u2192 poll GET /api/v1/studio/status/{task_id}/"}, {"title": "Android (Kotlin + OkHttp)", "code": "val client = OkHttpClient()\nval req = Request.Builder()\n    .url(\"$BASE/api/v1/profile/\")\n    .header(\"Authorization\", \"Bearer $token\")\n    .get()\n    .build()\nval res = client.newCall(req).execute()\nval body = res.body?.string()"}, {"title": "Open site button + update check (\u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u043e)", "code": "1) GET /api/v1/app/config/\n2) Open docs.app.site_url by button \"\u041f\u0435\u0440\u0435\u0439\u0442\u0438 \u043d\u0430 \u0441\u0430\u0439\u0442\"\n3) GET /api/v1/app/check-update/?platform=<desktop|android|ios|mac>&current_version=<x.y.z>\n4) if update_available=true -> show update action (download_url / play_market_url)\n5) if force_update=true -> block app until update"}], "links": {"self_json": "https://tigr.pro/api/v1/docs.json", "self_html": "https://tigr.pro/api/v1/docs/", "developers": "https://tigr.pro/developers/", "cabinet_tokens": "https://tigr.pro/cabinet/"}}}