{"title":"Claude Code API Proxy","version":"4.4.0","updated":"2026-04-23","description":"OpenAI-compatible API proxy to Claude via Agent SDK + Direct Anthropic API. Persistent sessions, real-time SSE streaming, tool support, direct API mode for all 3 models (haiku/sonnet/opus). Uses Claude Max subscription with OAuth. Compatible with OpenAI SDK, Open WebUI, LiveKit, curl.","base_url":"https://claude.ai-platform.space","path_aliases":{"description":"All API endpoints work with AND without /v1/ prefix. Use whichever your client expects.","examples":[{"with_prefix":"/v1/chat/completions","without_prefix":"/chat/completions","both_work":true},{"with_prefix":"/v1/messages","without_prefix":"/messages","both_work":true},{"with_prefix":"/v1/models","without_prefix":"/models","both_work":true},{"with_prefix":"/v1/status","without_prefix":"/status","both_work":true}],"base_url_options":[{"url":"https://claude.ai-platform.space/v1","for":"Clients that add path directly (OpenClaw, some OpenAI SDK configs)"},{"url":"https://claude.ai-platform.space","for":"Clients that add /v1/ automatically (standard OpenAI SDK, LiteLLM)"}],"note":"If you get 404, check whether your client adds /v1/ prefix automatically. If yes, set base_url WITHOUT /v1. If no, set base_url WITH /v1."},"request_formats":{"description":"All endpoints auto-detect request format. Send in any format - it just works.","formats":[{"name":"OpenAI","example":"{\"model\": \"sonnet\", \"messages\": [{\"role\": \"system\", \"content\": \"You are helpful\"}, {\"role\": \"user\", \"content\": \"Hello\"}]}","for":"OpenAI SDK, Open WebUI, LiteLLM, LangChain, any OpenAI-compatible client"},{"name":"Anthropic","example":"{\"model\": \"claude-sonnet-4-6\", \"system\": \"You are helpful\", \"max_tokens\": 4096, \"messages\": [{\"role\": \"user\", \"content\": [{\"type\": \"text\", \"text\": \"Hello\"}]}]}","for":"Anthropic SDK, langchain-anthropic, Claude API clients"},{"name":"Simple text","example":"{\"prompt\": \"Hello\"} or {\"content\": \"Hello\"} or {\"query\": \"Hello\"}","for":"curl, scripts, webhooks, any simple integration"},{"name":"String messages","example":"{\"messages\": \"just send a string instead of array\"}","for":"Quick prototyping, simple scripts"}],"model_aliases":{"description":"50+ model names accepted and auto-mapped to Claude equivalents","groups":[{"name":"Short","examples":"opus, sonnet, haiku"},{"name":"Claude 4.x","examples":"claude-opus-4-7, claude-sonnet-4-6, claude-haiku-4-5 (+ legacy claude-opus-4-6)"},{"name":"Claude 3.x","examples":"claude-3-opus-20240229, claude-3-5-sonnet-20241022, claude-3-haiku-20240307"},{"name":"OpenAI","examples":"gpt-4, gpt-4o, gpt-4o-mini, gpt-3.5-turbo, gpt-4.1, o3, o3-mini"},{"name":"Google","examples":"gemini-pro, gemini-2.5-pro, gemini-2.0-flash"},{"name":"LiteLLM","examples":"anthropic/claude-sonnet-4-6, anthropic/claude-opus-4-7"}]},"auth_headers":{"description":"Both OpenAI and Anthropic auth headers accepted on ALL endpoints","accepted":["Authorization: Bearer KEY","x-api-key: KEY","?key=KEY"]}},"authentication":{"type":"API Key","methods":[{"method":"Header","format":"Authorization: Bearer YOUR_API_KEY"},{"method":"Query param","format":"?key=YOUR_API_KEY"},{"method":"Anthropic SDK","format":"x-api-key: YOUR_API_KEY"}],"note":"API keys managed via Admin Panel (/admin). Each user gets a unique sk-cc-XXXX key. Admin panel access: /admin?key=YOUR_API_KEY","internal_auth":{"description":"How the proxy authenticates with Anthropic (for reference)","method":"OAuth Bearer Token (sk-ant-oat01-*)","headers":{"Authorization":"Bearer {oauth_token}","anthropic-beta":"claude-code-20250219,oauth-2025-04-20","user-agent":"claude-cli/2.1.85 (external, cli)","x-app":"cli"},"identity_requirement":"Sonnet and Opus via OAuth require system prompt identity assertion: 'You are Claude Code, Anthropic's official CLI for Claude.' as first system block. Without this, API returns 400. Haiku works without it.","source":"GitHub Issues #35269, #40515 (discovered 06.04.2026)"}},"models":{"description":"Available Claude models","list":[{"id":"claude-opus-4-7","alias":["opus","gpt-4","gpt-4-turbo","claude-opus-4-6"],"description":"Most capable. Deep reasoning, complex architecture. 1M context.","context":1000000,"max_output":128000,"price_input":"$5/MTok","price_output":"$25/MTok","extended_thinking":true,"adaptive_thinking":true},{"id":"claude-sonnet-4-6","alias":["sonnet","gpt-4o"],"description":"Best balance of speed and quality. Default model. 1M context.","context":1000000,"max_output":64000,"price_input":"$3/MTok","price_output":"$15/MTok","extended_thinking":true,"adaptive_thinking":true},{"id":"claude-haiku-4-5","alias":["haiku","gpt-3.5-turbo","gpt-4o-mini"],"description":"Fastest. Simple tasks, quick answers. 200K context.","context":200000,"max_output":64000,"price_input":"$1/MTok","price_output":"$5/MTok","extended_thinking":true,"adaptive_thinking":false}],"note":"OpenAI model names (gpt-4, gpt-4o, gpt-3.5-turbo) are automatically mapped to Claude equivalents."},"usage_modes":{"description":"Two ways to use the API: one-shot or conversation with memory","one_shot":{"description":"Single question -> single answer. No memory between requests. Like a standard OpenAI API call.","when_to_use":"Quick questions, code generation, one-time tasks, integrations (LiveKit, Open WebUI).","example_curl":"curl -X POST https://claude.ai-platform.space/v1/chat/completions \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"model\": \"sonnet\", \"messages\": [{\"role\": \"user\", \"content\": \"Explain async/await in Python\"}]}'","example_python":"from openai import OpenAI\nclient = OpenAI(api_key=\"YOUR_API_KEY\", base_url=\"https://claude.ai-platform.space/v1\")\nresponse = client.chat.completions.create(\n    model=\"sonnet\",\n    messages=[{\"role\": \"user\", \"content\": \"Explain async/await in Python\"}]\n)\nprint(response.choices[0].message.content)"},"conversation":{"description":"Multi-turn conversation with memory. Claude remembers previous messages, files read, analysis done. Use session_id from response to continue.","when_to_use":"Debugging sessions, code reviews with follow-ups, multi-step analysis, chat interfaces.","how_it_works":["1. Send first request normally -> response includes session_id","2. Save session_id from response","3. Send next request with session_id field -> Claude has full context from previous turns","4. Repeat as needed. Session persists on server."],"example_first_request":"# Step 1: First request (creates session)\ncurl -X POST https://claude.ai-platform.space/v1/chat/completions \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"model\": \"sonnet\", \"messages\": [{\"role\": \"user\", \"content\": \"Analyze the auth module in this project\"}]}'\n\n# Response includes: \"session_id\": \"abc-123-def\"","example_continue":"# Step 2: Continue conversation (Claude remembers everything)\ncurl -X POST https://claude.ai-platform.space/v1/chat/completions \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"model\": \"sonnet\", \"session_id\": \"abc-123-def\", \"messages\": [{\"role\": \"user\", \"content\": \"Now refactor it to use JWT\"}]}'\n\n# Claude already knows the auth module from step 1","example_python":"from openai import OpenAI\nclient = OpenAI(api_key=\"YOUR_API_KEY\", base_url=\"https://claude.ai-platform.space/v1\")\n\n# First message\nr1 = client.chat.completions.create(\n    model=\"sonnet\",\n    messages=[{\"role\": \"user\", \"content\": \"Read and analyze auth.py\"}]\n)\nprint(r1.choices[0].message.content)\nsession_id = r1.session_id  # Save this!\n\n# Follow-up with context\nr2 = client.chat.completions.create(\n    model=\"sonnet\",\n    messages=[{\"role\": \"user\", \"content\": \"Now add rate limiting to it\"}],\n    extra_body={\"session_id\": session_id}  # Continue session\n)\nprint(r2.choices[0].message.content)"},"direct_api":{"description":"Direct Anthropic Messages API call. ALL 3 models supported (haiku, sonnet, opus). Zero SDK overhead. Use mode=direct or scope=light/medium.","when_to_use":"Git commit messages, translations, text summarization, copywriting, simple completions. Any task where you just need text in -> text out without file access or tools.","why":"SDK persistent sessions add ~20-40K cache tokens overhead per request ($0.25-0.70) because they load Claude Code system prompt and tool definitions. Direct API sends ONLY your prompt - zero overhead. Same Claude model, same quality, 700x cheaper for simple tasks.","how_it_works":"When mode=direct (or scope=light) is set, the proxy bypasses the SDK session pool entirely and calls Anthropic Messages API directly using OAuth Bearer token. For sonnet/opus, the proxy automatically injects the required system prompt identity assertion. No persistent session, no tools, no context accumulation.","supported_models":{"haiku":{"speed":"~900ms","status":"Works without identity assertion"},"sonnet":{"speed":"~1700ms","status":"Works WITH identity assertion (auto-injected by proxy)"},"opus":{"speed":"~2700ms","status":"Works WITH identity assertion (auto-injected by proxy)"}},"identity_fix_note":"Since 06.04.2026: sonnet and opus via OAuth require system prompt identity. The proxy handles this automatically - you don't need to do anything special. Just pass model=sonnet or model=opus with mode=direct.","example_curl_haiku":"curl -X POST https://claude.ai-platform.space/v1/chat/completions \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"model\": \"haiku\", \"mode\": \"direct\", \"messages\": [{\"role\": \"user\", \"content\": \"Translate to English: Привет мир\"}]}' ","example_curl_sonnet":"curl -X POST https://claude.ai-platform.space/v1/chat/completions \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"model\": \"sonnet\", \"mode\": \"direct\", \"messages\": [{\"role\": \"user\", \"content\": \"Explain async/await in Python\"}]}' ","example_curl_opus":"curl -X POST https://claude.ai-platform.space/v1/chat/completions \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"model\": \"opus\", \"mode\": \"direct\", \"messages\": [{\"role\": \"user\", \"content\": \"Design a microservice architecture for e-commerce\"}]}' ","example_with_system":"curl -X POST https://claude.ai-platform.space/v1/chat/completions \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"model\": \"sonnet\", \"mode\": \"direct\", \"messages\": [{\"role\": \"system\", \"content\": \"Generate a git commit message\"}, {\"role\": \"user\", \"content\": \"diff --git a/file.py ...\"}]}' ","comparison":{"sdk_session":{"cost_per_request":"$0.25-0.70","cache_tokens":"20-40K","speed":"2-30s","tools":true,"method":"Agent SDK persistent session"},"direct_api":{"cost_per_request":"depends on tokens","cache_tokens":"0","speed":"0.7-5s","tools":false,"method":"Direct Anthropic Messages API"}},"available_models":"ALL 3: haiku (default for scope=light), sonnet, opus. Pass model explicitly: model=sonnet with mode=direct.","response_field":"Response includes 'mode': 'direct_api' to confirm direct API was used."},"extended_thinking":{"description":"Claude Opus 4.7 / Sonnet 4.6 / Haiku 4.5 support extended thinking — reasoning before responding. Available in BOTH Direct API and SDK session. Two ways to enable:","method_1_effort":{"description":"Easiest: just set 'effort' field. Proxy automatically picks the right thinking config for each model.","mapping":{"opus (4.7)":"effort=medium/high/max → thinking={type:'adaptive'} + output_config.effort (Claude 4.7 decides its own budget)","sonnet (4.6)":"effort=medium → budget_tokens=4000, effort=high → 10000, effort=max → 16000","haiku (4.5)":"same as sonnet"},"example_curl":"curl -X POST https://claude.ai-platform.space/v1/chat/completions \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"model\":\"opus\",\"mode\":\"direct\",\"effort\":\"max\",\"max_tokens\":2048,\"messages\":[{\"role\":\"user\",\"content\":\"Plan a migration from monolith to microservices\"}]}'"},"method_2_raw_thinking":{"description":"Explicit: pass Anthropic-native 'thinking' field. Overrides effort-mapping.","shapes":{"adaptive":"{type: 'adaptive'} — REQUIRED for Opus 4.7 (classic 'enabled' fails with 400). Claude auto-picks budget.","enabled":"{type: 'enabled', budget_tokens: N} — for Sonnet 4.6, Haiku 4.5, Opus 4.6 (legacy). N must be < max_tokens. Budgets >~20k usually require stream=true.","disabled":"{type: 'disabled'} — force no thinking even if model defaults to it."},"example_curl":"curl -X POST https://claude.ai-platform.space/v1/chat/completions \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"model\":\"sonnet\",\"mode\":\"direct\",\"thinking\":{\"type\":\"enabled\",\"budget_tokens\":8000},\"max_tokens\":2000,\"messages\":[{\"role\":\"user\",\"content\":\"Derive a regex for matching URLs\"}]}'"},"notes":["Extended thinking only engages for Direct API (mode=direct or scope=light). SDK sessions use their own --effort flag passed to Claude Code CLI.","Proxy strips ThinkingBlocks from the response and returns only the final text in 'choices[0].message.content'.","If budget_tokens >= max_tokens, proxy auto-raises max_tokens to budget+1024 to satisfy Anthropic's requirement.","Opus 4.7 does NOT accept 'enabled' type — proxy converts effort=* to 'adaptive' automatically. Old 'enabled' requests to Opus 4.7 will get 400 from Anthropic."]}},"endpoints":[{"method":"POST","path":"/v1/chat/completions","description":"Send a message and get Claude's response. Fully OpenAI-compatible.","request_body":{"model":{"type":"string","required":false,"default":"sonnet","description":"Model to use. Accepts Claude IDs (claude-sonnet-4-6) or short names (sonnet) or OpenAI aliases (gpt-4o)."},"messages":{"type":"array","required":true,"description":"Array of message objects with role and content.","example":[{"role":"system","content":"You are a helpful assistant."},{"role":"user","content":"Hello!"}]},"stream":{"type":"boolean","required":false,"default":false,"description":"Enable real-time SSE streaming. Tokens arrive as they are generated, not after full response."},"timeout":{"type":"integer","required":false,"default":120,"description":"Request timeout in seconds. Max 300."},"effort":{"type":"string","required":false,"default":"medium","description":"Reasoning depth: 'low'/'medium'/'high'/'max'. Works in BOTH modes. For SDK session — passed to Claude Code as --effort. For Direct API — automatically maps to Anthropic extended thinking: Opus 4.7 uses {type:'adaptive', output_config.effort}, Sonnet/Haiku use {type:'enabled', budget_tokens} (medium=4k, high=10k, max=16k)."},"thinking":{"type":"object","required":false,"description":"Raw Anthropic extended thinking config (Direct API only). Overrides effort-mapping. Shapes: {type:'adaptive'} for Opus 4.7, {type:'enabled', budget_tokens:N} for Sonnet/Haiku/Opus 4.6, {type:'disabled'}. If budget_tokens >= max_tokens, max_tokens is auto-raised."},"mode":{"type":"string","required":false,"default":"session","description":"Execution mode: 'direct' = Direct Anthropic Messages API (fast, no tools, effort+thinking supported), 'session' = SDK persistent session (tools, effort, context). Also accepts 'lightweight' (alias for direct)."},"scope":{"type":"string","required":false,"description":"Preset alias: 'light' = direct+haiku, 'medium' = session+sonnet+medium, 'strong' = session+opus+high, 'max' = session+opus+max. Overrides model/effort/mode. Note: scope=max is always Opus — for 'Sonnet at max effort' use explicit {model:'sonnet', effort:'max'} instead."}},"response":{"id":"chatcmpl-xxxx","object":"chat.completion","created":1773224718,"model":"haiku","choices":[{"index":0,"message":{"role":"assistant","content":"Response text"},"finish_reason":"end_turn"}],"usage":{"prompt_tokens":10,"completion_tokens":75,"total_tokens":85,"cache_read_tokens":20548,"cache_creation_tokens":1615},"session_id":"uuid-of-session","cost_usd":0.0045,"duration_ms":1072,"duration_api_ms":1033},"examples":{"curl_basic":"curl -X POST https://claude.ai-platform.space/v1/chat/completions \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"model\": \"sonnet\", \"messages\": [{\"role\": \"user\", \"content\": \"Hello!\"}]}'","curl_stream":"curl -N -X POST https://claude.ai-platform.space/v1/chat/completions \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"model\": \"sonnet\", \"stream\": true, \"messages\": [{\"role\": \"user\", \"content\": \"Hello!\"}]}'","curl_direct":"curl -X POST https://claude.ai-platform.space/v1/chat/completions \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"model\": \"haiku\", \"mode\": \"direct\", \"messages\": [{\"role\": \"user\", \"content\": \"Say OK\"}]}'","curl_effort":"curl -X POST https://claude.ai-platform.space/v1/chat/completions \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"model\": \"sonnet\", \"effort\": \"high\", \"messages\": [{\"role\": \"user\", \"content\": \"Analyze this\"}]}'","python_openai":"from openai import OpenAI\n\nclient = OpenAI(\n    api_key=\"YOUR_API_KEY\",\n    base_url=\"https://claude.ai-platform.space/v1\"\n)\n\nresponse = client.chat.completions.create(\n    model=\"sonnet\",\n    messages=[{\"role\": \"user\", \"content\": \"Hello!\"}]\n)\nprint(response.choices[0].message.content)","python_stream":"from openai import OpenAI\n\nclient = OpenAI(\n    api_key=\"YOUR_API_KEY\",\n    base_url=\"https://claude.ai-platform.space/v1\"\n)\n\nstream = client.chat.completions.create(\n    model=\"sonnet\",\n    messages=[{\"role\": \"user\", \"content\": \"Write a poem\"}],\n    stream=True\n)\nfor chunk in stream:\n    if chunk.choices[0].delta.content:\n        print(chunk.choices[0].delta.content, end=\"\")","javascript_fetch":"const response = await fetch(\"https://claude.ai-platform.space/v1/chat/completions\", {\n  method: \"POST\",\n  headers: {\n    \"Authorization\": \"Bearer YOUR_API_KEY\",\n    \"Content-Type\": \"application/json\"\n  },\n  body: JSON.stringify({\n    model: \"sonnet\",\n    messages: [{ role: \"user\", content: \"Hello!\" }]\n  })\n});\nconst data = await response.json();\nconsole.log(data.choices[0].message.content);","livekit_agent":"# LiveKit Voice Agent integration\nfrom livekit.plugins import openai\nimport httpx\n\nllm = openai.LLM(\n    model=\"claude-sonnet-4-6\",\n    base_url=\"http://127.0.0.1:8092/v1\",\n    api_key=\"YOUR_API_KEY\",\n    timeout=httpx.Timeout(connect=15.0, read=120.0, write=15.0, pool=15.0),\n)"}},{"method":"POST","path":"/v1/messages","description":"Anthropic Messages API compatible endpoint. For langchain-anthropic, anthropic Python SDK.","request_body":null,"response":{"id":"msg_xxxx","type":"message","role":"assistant","content":[{"type":"text","text":"Response"}]},"examples":{"python_anthropic":"from anthropic import Anthropic\n\nclient = Anthropic(\n    api_key=\"YOUR_API_KEY\",\n    base_url=\"https://claude.ai-platform.space\"\n)\nmessage = client.messages.create(\n    model=\"claude-sonnet-4-6\",\n    max_tokens=4096,\n    messages=[{\"role\": \"user\", \"content\": \"Hello!\"}]\n)\nprint(message.content[0].text)"},"error_responses":{"401":{"detail":"Invalid or expired API key"},"402":{"error":{"type":"insufficient_balance","message":"Balance too low. Top up at /cabinet#billing"}},"403":{"detail":"Model not allowed for this key"},"429":{"detail":"Daily request limit exceeded"}},"billing_note":"Each request costs tokens from your balance. $5 bonus on signup. Pricing: /billing/pricing"},{"method":"GET","path":"/v1/models","description":"List available models for your API key.","request_body":null,"response":{"object":"list","data":[{"id":"claude-opus-4-7","object":"model","owned_by":"anthropic"},{"id":"claude-sonnet-4-6","object":"model","owned_by":"anthropic"},{"id":"claude-haiku-4-5","object":"model","owned_by":"anthropic"}]},"examples":{"curl":"curl https://claude.ai-platform.space/v1/models \\\n  -H \"Authorization: Bearer YOUR_API_KEY\""}},{"method":"GET","path":"/v1/status","description":"Check API status, session pool health, version.","request_body":null,"response":{"status":"running","version":"4.1.0","mode":"sdk-persistent-sessions + direct-api","default_model":"sonnet","pool":{"ready_count":3,"healthy":true}},"examples":{"curl":"curl https://claude.ai-platform.space/v1/status?key=YOUR_API_KEY"}},{"method":"GET","path":"/health","description":"Health check with session pool status. No authentication required.","request_body":null,"response":{"status":"ok","service":"claude-api-sdk-proxy","version":"4.1.0","mode":"sdk-persistent-sessions + direct-api","pool":{"pool_size":3,"ready_count":3,"healthy":true}},"examples":{"curl":"curl https://claude.ai-platform.space/health"}},{"method":"GET","path":"/rate-limits","description":"Monitor unified rate limits from OAuth subscriptions. Shows 5-hour, 7-day and overage utilization.","request_body":null,"response":{"unified_status":"normal","representative_claim":"opus","five_hour":{"status":"normal","utilization_pct":35.2,"resets_in_sec":12400},"seven_day":{"status":"normal","utilization_pct":12.8,"resets_in_sec":504000},"overage":{"status":"normal","in_use":false,"utilization_pct":0},"fallback_percentage":35.2,"last_model":"opus","last_check_ago_sec":45},"examples":{"curl":"curl https://claude.ai-platform.space/rate-limits \\\n  -H \"Authorization: Bearer YOUR_API_KEY\""}}],"auth_endpoints":{"description":"User authentication and registration. Session-token based auth.","base_path":"/auth","endpoints":[{"method":"POST","path":"/auth/register","description":"Register new user. $5 bonus on signup. Rate limit: 3 per hour.","request_body":{"email":{"type":"string","required":true,"description":"Valid email (temp-email domains blocked)"},"password":{"type":"string","required":true,"description":"Min 8 characters"},"lang":{"type":"string","required":false,"default":"en","description":"Interface language: en, uk, ru"}},"response":{"success":true,"user":{"id":1,"username":"user_abc","email":"user@example.com","role":"user"},"api_key":"sk-cc-xxxx","balance":5.0,"session_token":"tok_xxxx"}},{"method":"POST","path":"/auth/login","description":"Login with email and password. Rate limit: 5 attempts per 15 min.","request_body":{"email":{"type":"string","required":true,"description":"User email"},"password":{"type":"string","required":true,"description":"User password"}},"response":{"success":true,"user":{"id":1,"username":"user_abc","email":"user@example.com","role":"user"},"balance":12.5,"session_token":"tok_xxxx"}},{"method":"POST","path":"/auth/logout","description":"Invalidate current session token. Requires authentication.","request_body":null,"response":{"success":true}},{"method":"GET","path":"/auth/me","description":"Get current authenticated user profile.","request_body":null,"response":{"user":{"id":1,"username":"user_abc","email":"user@example.com","role":"user","balance":12.5,"bonus_claimed":true,"email_verified":true}}}]},"cabinet_endpoints":{"description":"User cabinet API - dashboard, keys, logs, balance, settings. All endpoints require session token authentication.","base_path":"/cabinet/api","endpoints":[{"method":"GET","path":"/cabinet/api/dashboard","description":"User dashboard with today's stats, lifetime totals, chart data (30 days)."},{"method":"GET","path":"/cabinet/api/keys","description":"List user's API keys (values masked). Max 10 keys per user."},{"method":"POST","path":"/cabinet/api/keys","description":"Create new API key. Body: {name}. Returns full key value (shown once)."},{"method":"DELETE","path":"/cabinet/api/keys/{key_id}","description":"Revoke/deactivate an API key."},{"method":"GET","path":"/cabinet/api/logs","description":"User's request logs. Params: model, status, limit (max 100), offset."},{"method":"GET","path":"/cabinet/api/logs/{request_id}","description":"Full details of a specific request."},{"method":"GET","path":"/cabinet/api/balance","description":"Balance and transaction history. Params: limit, offset."},{"method":"GET","path":"/cabinet/api/usage","description":"Usage stats by model and day. Params: days (default 30)."},{"method":"GET","path":"/cabinet/api/settings","description":"User profile settings: email, daily spend limit, notifications."},{"method":"PUT","path":"/cabinet/api/settings","description":"Update settings. Body: {email, daily_spend_limit, notification_settings}."},{"method":"PUT","path":"/cabinet/api/settings/password","description":"Change password. Body: {current_password, new_password}. Invalidates other sessions."},{"method":"GET","path":"/cabinet/api/pricing","description":"Pricing for all active models."}]},"billing_endpoints":{"description":"Billing and payments. Top-up balance, check payment status.","base_path":"/billing","endpoints":[{"method":"GET","path":"/billing/pricing","description":"Public pricing for all models with cache token prices. No auth required.","request_body":null,"response":{"models":[{"model":"claude-sonnet-4-6","display_name":"Sonnet","price_input_per_mtok":3.0,"price_output_per_mtok":15.0,"price_cache_read_per_mtok":0.3,"price_cache_write_per_mtok":3.75}]}},{"method":"POST","path":"/billing/topup","description":"Initiate balance top-up. Amount: $5-$1000. Returns payment order reference.","request_body":{"amount":{"type":"float","required":true,"description":"Amount in USD ($5-$1000)"}},"response":{"order_reference":"CC-xxxx","amount":10.0,"status":"pending","message":"Payment initiated"}},{"method":"POST","path":"/billing/webhook","description":"Payment provider webhook callback. Idempotent, HMAC verification.","request_body":null,"response":{"orderReference":"CC-xxxx","status":"accept"}},{"method":"GET","path":"/billing/status/{order_ref}","description":"Check payment status by order reference.","request_body":null,"response":{"status":"completed","amount_usd":10.0,"created_at":"2026-04-06T12:00:00","completed_at":"2026-04-06T12:01:00"}}]},"admin_endpoints":[{"method":"GET","path":"/admin/dashboard","description":"Dashboard metrics, charts data, top users, errors."},{"method":"GET","path":"/admin/users","description":"List all users with stats."},{"method":"POST","path":"/admin/users","description":"Create new user. Body: {username, password, email, role, max_requests_per_day, max_tokens_per_day, allowed_models, notes}. Returns: {user_id, api_key, username}"},{"method":"PUT","path":"/admin/users/{id}","description":"Update user fields."},{"method":"DELETE","path":"/admin/users/{id}","description":"Delete user and all their keys."},{"method":"GET","path":"/admin/users/{id}/keys","description":"List API keys for user."},{"method":"POST","path":"/admin/users/{id}/keys","description":"Create new API key. Body: {name, expires_at}"},{"method":"PUT","path":"/admin/keys/{id}","description":"Update key (name, is_active, expires_at)."},{"method":"DELETE","path":"/admin/keys/{id}","description":"Delete API key."},{"method":"GET","path":"/admin/logs","description":"Request logs with filters. Params: limit, offset, user_id, model, status, date_from, date_to, search."},{"method":"GET","path":"/admin/logs/{request_id}","description":"Full log detail including raw JSON."},{"method":"GET","path":"/admin/sessions","description":"List Claude sessions. Params: limit, user_id."},{"method":"GET","path":"/admin/sessions/{session_id}/messages","description":"All messages in a session with full details (prompt, response, tokens, cost)."},{"method":"GET","path":"/admin/stats/daily","description":"Daily aggregated stats. Params: days, user_id."},{"method":"GET","path":"/admin/stats/models","description":"Stats by model. Params: days."},{"method":"GET","path":"/admin/stats/users","description":"Stats by user. Params: days."},{"method":"GET","path":"/admin/stats/cache","description":"Cache hit/miss ratio. Params: days."},{"method":"GET","path":"/admin/settings","description":"Get all settings."},{"method":"PUT","path":"/admin/settings","description":"Update settings. Body: {key: value, ...}"},{"method":"GET","path":"/admin/billing/overview","description":"Billing overview: revenue, bonuses, consumed, user balances."},{"method":"POST","path":"/admin/billing/adjust","description":"Adjust user balance. Body: {user_id, amount, description}"},{"method":"GET","path":"/admin/billing/pricing","description":"Get pricing for all models."},{"method":"PUT","path":"/admin/billing/pricing/{model}","description":"Update pricing for a model."},{"method":"GET","path":"/api/docs/json","description":"This documentation in JSON format."},{"method":"GET","path":"/admin/accounts","description":"List OAuth account pool with stats and rate limit info."},{"method":"POST","path":"/admin/accounts","description":"Add OAuth account. Body: {email, credentials_file, notes}."},{"method":"PUT","path":"/admin/accounts/{id}","description":"Update account (priority, is_active, status, notes, email)."},{"method":"POST","path":"/admin/accounts/probe","description":"Probe all accounts with light haiku request to update rate limit headers."}],"telemetry_fields":{"description":"Every request logs 25+ fields for full observability","fields":[{"name":"input_tokens","description":"Input tokens sent to model"},{"name":"output_tokens","description":"Tokens generated by model"},{"name":"cache_read_input_tokens","description":"Tokens read from prompt cache (cost savings)"},{"name":"cache_creation_input_tokens","description":"Tokens written to prompt cache"},{"name":"cost_usd","description":"Estimated cost in USD"},{"name":"duration_ms","description":"Total request time"},{"name":"duration_api_ms","description":"Pure API call time"},{"name":"num_turns","description":"Number of tool-use turns"},{"name":"stop_reason","description":"Why Claude stopped (end_turn, max_tokens)"},{"name":"session_id","description":"Session ID for conversation continuity"},{"name":"stream_mode","description":"Whether request used SSE streaming"}]},"rate_limits":{"description":"Per-user configurable limits","fields":[{"name":"max_requests_per_day","default":100,"description":"Maximum API requests per day per user"},{"name":"max_tokens_per_day","default":500000,"description":"Maximum tokens per day per user (tracked)"},{"name":"allowed_models","default":"haiku,sonnet,opus","description":"Comma-separated list of allowed models. All 3 models available by default."}]},"how_it_works":{"description":"Architecture overview - two execution paths","two_paths":{"direct_api":{"when":"mode=direct or scope=light/medium","description":"Direct call to Anthropic Messages API via OAuth. ALL 3 models: haiku (~900ms), sonnet (~1700ms), opus (~2700ms). Zero SDK overhead. Proxy auto-injects identity assertion for sonnet/opus.","flow":["1. Client sends request with mode=direct (or scope=light)","2. Proxy authenticates, checks limits","3. Proxy calls Anthropic Messages API directly with OAuth Bearer + identity headers","4. For sonnet/opus: system prompt identity auto-injected","5. Response returned immediately","6. Logged to MySQL"],"speed":"0.7-2.7s (model dependent)","cost":"$0 (subscription)","supported_models":"haiku, sonnet, opus (all 3)","use_for":"Git commits, translations, summaries, copywriting, any text generation without tools"},"sdk_session":{"when":"scope=medium/strong/max or default without scope","description":"Request goes through persistent Agent SDK session. Claude has access to tools (Read, Write, Bash, Web) and conversation memory.","flow":["1. Client sends request","2. Proxy authenticates, checks limits","3. Proxy routes to pre-warmed SDK session pool","4. Claude may use tools, multi-turn reasoning","5. Response streams as SSE or returns as JSON","6. Logged to MySQL"],"speed":"2-6s","cost":"$0.01-0.70 (cache tokens from SDK system prompt)","use_for":"Code analysis, file operations, complex reasoning, chat with memory"}},"tech_stack":["FastAPI + uvicorn (Python) - API server","Anthropic Python SDK - direct API calls for lightweight requests","Claude Agent SDK (Python) - persistent sessions for full agent mode","MySQL 8.4 (PyMySQL+DBUtils) - logging, billing and user management","nginx (HestiaCP) - SSL termination and reverse proxy"],"session_pool":{"description":"12 persistent SDK sessions across 4 scopes + Direct API for all 3 models","scopes":{"light":"Direct API: haiku (~900ms), sonnet (~1700ms), opus (~2700ms) - zero SDK overhead","medium":"sonnet/medium, 2 SDK slots - balanced speed and quality with tools","strong":"opus/high, 1 SDK slot - deep analysis with tools","max":"opus/max, 1 SDK slot - maximum reasoning depth with tools"},"oauth_accounts":"Multi-account OAuth pool (4 accounts). Smart fallback: if one account hits rate limit, proxy tries next.","benefits":["Direct API for ALL 3 models: haiku/sonnet/opus with zero cache overhead","Real token-by-token SSE streaming for SDK sessions","Session context preserved between requests (optional, via session_id)","Automatic health monitoring and session recreation","Multi-account OAuth pool with smart fallback on 429","Unified rate limit monitoring via /rate-limits endpoint"],"limits":["SDK sessions: 1-2 parallel requests per scope (queued if busy)","Sessions auto-recreate every 100 requests (context window protection)","Effort is fixed per scope (medium=medium, strong=high, max=max)","OAuth unified rate limits: 5-hour and 7-day windows per subscription"]}}}