{"title":"Claude Code API Proxy","version":"5.3.0","updated":"2026-09-18","pricing_verified":"2026-09-10: все 14 моделей сверены с официальными прайсами Anthropic и OpenAI. Формула расчёта проверена независимым пересчётом по токенам за 7 дней: расхождение 0.31% (округление decimal(12,6) на мелких запросах, всегда в пользу клиента).","pricing_verified_meta":"2026-09-18: две модели Meta добавлены по официальному прайсу Meta - muse-spark-1.3 $1.25/$4.25 (чтение кеша $0.15) и muse-spark-1.3-contributor $0.10/$0.20 (чтение кеша $0.002). Запись кеша Meta не тарифицирует, в таблице стоит ноль осознанно.","pricing_verified_55":"2026-10-16: Opus 5.5 и Sonnet 5.5 считаются отдельными строками pricing по официальному прайсу Anthropic - Opus 5.5 $4/$20 (чтение кеша $0.20, запись 5m $5, 1h $8), Sonnet 5.5 $2/$10 (чтение $0.10, запись 5m $2.50, 1h $4). Ключ цены - исходное имя модели от клиента (raw_model): claude-opus-5-5 и claude-sonnet-5-5.","whats_new":{"2026-09-18 — третий провайдер: Meta Muse Spark":{"summary":"Добавлены две модели Meta: muse-spark-1.3 и muse-spark-1.3-contributor. Обе закрыты по умолчанию, открываются точечно через allowed_models. Контекст миллион токенов у обеих.","training_disclosure":"🔴 ГЛАВНОЕ. muse-spark-1.3-contributor стоит дешевле более чем в 12 раз по входу и более чем в 21 раз по выходу ($0.10/$0.20 против $1.25/$4.25) ровно потому, что Meta ОБУЧАЕТСЯ на ваших промптах и ответах. Это условие линейки contributor, а не наша политика. Нужна дешевизна - берите ее осознанно; нужна конфиденциальность - берите muse-spark-1.3, там данные для обучения не используются.","fallback_note":"🔴 При одновременной перегрузке Claude и OpenAI аварийная подмена уходит в muse-spark-1.3-contributor, то есть в линейку с обучением. Это делается ради того, чтобы запрос вообще получил ответ вместо отказа. Ответ в таком случае несет заголовки X-Fallback-Provider: meta и X-Fallback-Training: true - по второму видно, что данные ушли в обучающуюся линейку. Не хотите такого совсем - напишите нам: сейчас это звено выключается целиком для всей платформы (одна настройка сервиса), персонального выключателя на ключе пока нет.","limits":"Meta не принимает stop_sequences и top_k (400) и не поддерживает часовой срок кеша - прокси снимает эти поля сам, ошибки вы не увидите. Уровня усилия max у Meta нет, он приземляется в xhigh. Размышление включено ВСЕГДА и делит max_tokens с ответом, поэтому прокси поднимает нижнюю границу до 16000 - иначе приходит пустой ответ при полном счете токенов (ночь 19.09.2026: 169 из 169 запросов с max_tokens=8000 пришли пустыми). При 503 от Meta прокси сам делает один повтор через 3 сек; если не помогло, приходит 429 с Retry-After: 20.","streaming":"Стрим настоящий, но с ДОЛГОЙ ПАУЗОЙ В НАЧАЛЕ. Замер через прокси 18.09.2026: первая дельта приходит через 7-22 секунды, дальше текст идет нормальным потоком (замер tests/meta/probe_stream.py: на ответе в 10279 символов 954 события дельты, средняя пауза между ними 0.039 сек). Прокси каждые 15 секунд шлет служебное событие, чтобы клиент с коротким таймаутом не оборвался на этой паузе: на /v1/messages это event: ping, на /v1/chat/completions - строка-комментарий. Если ваш клиент показывает пользователю первый байт - заложите ожидание не меньше 30 секунд.","cache":"Кеш префикса работает сам и на обеих линейках, управлять им не нужно и нечем. Канонический замер tests/meta/probe_capabilities.py 18.09.2026 на префиксе ~10800 токенов: первый запрос вход 10825 и ноль кеша, повтор вход 102 при чтении кеша 10723. ВАЖНО: попадание не гарантировано на каждом повторе - третий такой же запрос снова ушел мимо кеша. Рассчитывайте на кеш как на экономию, а не как на правило."},"2026-09-09 — GPT-6 Astra + штатное поле reasoning_effort":{"summary":"Добавлена gpt-6-astra (самая сильная модель OpenAI). Прокси начал читать reasoning_effort - штатное имя поля в OpenAI API, которое до этого игнорировалось.","reasoning_effort":"ГЛАВНОЕ ДЛЯ КЛИЕНТОВ НА openai-python: поле reasoning_effort теперь работает. Раньше оно молча игнорировалось, и запрос шёл на дефолте канала. Порядок чтения: output_config.effort (контракт Anthropic) -> reasoning_effort (контракт OpenAI) -> effort (наше короткое имя). Значения: low / medium / high / xhigh / max.","effort_none_minimal":"none и minimal принимаются всегда, ошибки клиент не получит. Куда они приземляются: у семьи gpt-5.6 и gpt-5.5 уровень none ШТАТНЫЙ и уходит как есть (minimal → low); на gpt-6-astra оба → low, модель их отвергает с 400; на моделях Claude оба → low, потому что своих таких уровней у Anthropic нет.","astra_limits":"gpt-6-astra: контекст 872000, выход до 128000, $10/$50 за 1M. Ставьте max_tokens от 2000 - модель сначала рассуждает, и рассуждение делит бюджет с ответом.","removed_models":"gpt-5.4 (08.09) и gpt-5.4-mini (09.09) исчезли у провайдера. Запрос на них возвращает 400 с НАШЕЙ причиной и именем живой замены, а не сырой ответ провайдера. Замены: gpt-5.6-terra и gpt-5.6-luna.","context_correction":"Контекст семьи 5.6 был занижен втрое в прежней документации (272000). Фактический потолок 872000, подтверждён запросом с 793356 токенами входа."},"2026-08-22 сверка цен и описание поведения прокси":{"summary":"Документация дополнена тем, что появилось после 25.07: модель Fable 5, эмбеддинги, генерация картинок и раздел proxy_behaviour - что прокси делает сам (склейка обрезанных ответов, фильтр пустых пингов, отсечка нераздаваемых моделей, потолок размышления, часовой кеш).","pricing":"Цены сверены с официальными источниками. Совпадают точь-в-точь: opus $5/$25, haiku $1/$5, fable $10/$50, gpt-5.6-terra, gpt-5.6-luna, gpt-5.5, оба эмбеддинга, картинки, распознавание речи, голос. Множители кеша Anthropic (read 0.1x, запись 5m 1.25x, запись 1h 2.0x от входа) соблюдены у всех четырёх моделей Claude.","our_own_tariff":"Два тарифа выше официальных ОСОЗНАННО - это наша цена за пул подписок, отказоустойчивость и автоматический fallback между провайдерами: sonnet $3/$15 (у Anthropic $2/$10, решение 22.08 - осознанная наценка) и gpt-5.6-sol $5/$30 (у OpenAI акция $4/$20 минимум до 21.11.2026). Строка opus $5/$25 - наш тариф для короткого имени opus и старых снепшотов (включая claude-opus-5); запросы с явным именем claude-opus-5-5 считаются по официальной строке $4/$20 с 16.10.2026. Мы отдаём СВОЙ тариф и нигде не обещали транслировать чужой прайс.","limits_correction":"Исправлен дефолт max_requests_per_day: в документации стояло 100, фактически лимит снят глобально 16.06.2026 - сейчас 0 (безлимит) у 51 из 56 ключей."},"2026-07-25 — Claude Opus 5 / Sonnet 5":{"summary":"Прокси переведён на claude-opus-5 и claude-sonnet-5. Цены НЕ изменились: opus $5/$25, sonnet $3/$15. Это drop-in upgrade — менять код клиента не нужно.","backward_compatibility":"Старые имена моделей продолжают работать и автоматически апгрейдятся: любое имя, содержащее 'opus' -> claude-opus-5, 'sonnet' -> claude-sonnet-5, 'haiku' -> claude-haiku-5-5. Это касается и snapshot-имён (claude-opus-4-8), и OpenAI-алиасов (gpt-4o).","breaking_changes_upstream":["Thinking на Opus 5 ВКЛЮЧЁН ПО УМОЛЧАНИЮ: запрос без поля thinking всё равно думает (на 4.7/4.8 было наоборот). max_tokens капает thinking + видимый ответ ВМЕСТЕ.","budget_tokens удалён на Opus 5 и Sonnet 5 (Anthropic возвращает 400). Используйте thinking={type:'adaptive'} + effort. Прокси конвертирует legacy budget_tokens автоматически.","temperature / top_p / top_k отвергаются на opus и sonnet (400). Прокси выбрасывает их silently — клиентам менять код не нужно.","thinking={type:'disabled'} допустим только при effort <= high. С xhigh/max Anthropic возвращает 400 — прокси снимает disabled автоматически."],"proxy_improvements":["Пол max_tokens=16000 для opus: раньше на дефолтных 4096 ответ обрезался, т.к. thinking съедал бюджет.","max_output поднят до 128000 для opus и sonnet (было 32000/64000).","effort xhigh и max пробрасываются как есть, больше не понижаются до high.","Порог prompt caching снижен: opus 512 токенов (Anthropic снизил минимум), haiku скорректирован под русский текст."],"measured_notes":{"chars_per_token":"русский текст ~2.3 симв/токен, английский ~4.55. Учитывайте при расчёте порогов кеша: 10008 симв русского = 4185 токенов.","prompt_cache_minimums":"opus 512 ток, sonnet 1024 ток, haiku 4096 ток. Промпт ниже минимума молча НЕ кешируется (cache_creation=0 без ошибки)."}}},"description":"OpenAI-compatible API proxy to Claude via Direct Anthropic API. Real-time SSE streaming, tool support, server-side tools (web_search, web_fetch, code_execution), Vision (image_url + base64), Sonnet 5 default. Uses Claude Max subscription with OAuth. Compatible with OpenAI SDK, Open WebUI, LiveKit, langchain, anthropic SDK, Cline, Cursor. v4.7.0 (01.06.2026): /v1/messages non-stream switched to direct Anthropic API (legacy SDK pool retired, fixes Unknown slot_key 500 error).","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-5\", \"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 5 / 4.x","examples":"claude-opus-5, claude-sonnet-5, claude-haiku-5-5 (legacy принимаются и авто-апгрейдятся: claude-opus-4-8, claude-opus-4-7, claude-opus-4-6, claude-sonnet-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-5, anthropic/claude-opus-5"}]},"auth_headers":{"description":"Both OpenAI and Anthropic auth headers accepted on ALL endpoints","accepted":["Authorization: Bearer KEY","x-api-key: KEY","?key=KEY"]},"encoding_tolerance":{"description":"Body decoding fallback chain. Прокси принимает request body даже если клиент шлёт его в legacy encoding (Windows-based интеграции, старые CRM-системы). Битые UTF-8 байты заменяются на U+FFFD вместо отказа с 400.","fallback_order":["UTF-8 (strict)","windows-1251 (cp1251)","latin-1","UTF-8 with replace errors"],"introduced":"28.05.2026 (фикс инцидента '0xcf at position 56' — клиент шёл cp1251)","applies_to":["/v1/chat/completions","/v1/messages","/v1/messages/count_tokens"],"note":"Если в body есть кириллица — рекомендуется всё же слать в UTF-8. Fallback — safety net для legacy."}},"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 models. Three providers behind one API: Anthropic (Claude), OpenAI (ChatGPT subscription via Codex) and Meta (Muse Code subscription). Model name decides the provider.","providers":{"anthropic":"claude-* and legacy aliases gpt-4 / gpt-4o / o3 (kept for backward compatibility - they resolve to Claude, NOT to OpenAI)","openai":"exact names gpt-6-astra / gpt-5.6-sol / gpt-5.6-terra / gpt-5.6-luna / gpt-5.5","meta":"exact names muse-spark-1.3 / muse-spark-1.3-contributor. Both closed by default, granted per key via allowed_models. 🔴 The -contributor line is cheap BECAUSE Meta trains on your prompts and completions."},"fallback":{"what":"When every Claude account is above the load threshold, the request is served by OpenAI instead of failing. If OpenAI is exhausted too, Meta is the third link.","mapping":"opus to gpt-5.6-sol, sonnet to gpt-5.6-terra, haiku to gpt-5.6-luna. The whole 5.6 family accepts up to 872K input tokens (measured 08.09.2026: a request with 793356 real input tokens went through), so long context needs no separate model any more.","meta_link":"🔴 Third link, used only when Claude AND OpenAI are both unavailable: any model goes to muse-spark-1.3-contributor, which is the cheapest CHAT model in our price list (only the embedding models cost less, and they are not chat models). It is cheap because META TRAINS ON THE PROMPTS AND COMPLETIONS it receives. The substitution is made by us, not by you, so the response is marked with X-Fallback-Training: true on top of the usual fallback headers. Ask us and we switch this link off - today that is a service-wide setting, not a per-key one, so it goes off for everyone.","transparency":"Response carries the REAL model name plus headers X-Fallback-Provider / X-Fallback-From / X-Fallback-To, and X-Fallback-Training: true whenever the answering model trains on the data. Billing follows the model that actually answered.","note":"Decision is made before the first byte: SSE sends the model name in the very first event and it cannot change mid-stream."},"list":[{"id":"claude-fable-5","alias":["fable"],"description":"Anthropic's most capable model. ДОСТУП ЗАКРЫТ: наша OAuth-подписка Max его не отдаёт - Anthropic возвращает 429 на всех аккаунтах пула, даже когда недельное окно квоты Fable свободно на 94%. Проверено 21.08.2026 тремя путями: через прокси, прямым HTTP и SDK-клиентом. Прокси отвечает честной ошибкой с причиной вместо молчаливой подмены на другую модель. Код раздачи готов - заработает без правок, если доступ появится.","context":1000000,"max_output":128000,"price_input":"$10/MTok","price_output":"$50/MTok","price_cache_read":"$1/MTok","price_cache_write_5m":"$12.50/MTok","price_cache_write_1h":"$20/MTok","extended_thinking":true,"adaptive_thinking":true,"thinking_default":"ON - как у Opus 5","effort_levels":["low","medium","high","xhigh","max"],"sampling_params":"temperature/top_p/top_k REJECTED (400) - proxy drops them silently","max_tokens_floor":"16000 - как у opus, thinking делит бюджет с ответом","tokenizer_note":"Claude 4.7 и новее используют новый токенизатор: примерно на 30% больше токенов на тот же текст (официальная сноска Anthropic)","access":"closed - по умолчанию не входит в allowed_models; открывается точечно, но фактически недоступен по подписке"},{"id":"claude-opus-5-5","alias":["opus","claude-opus-5","gpt-4","gpt-4-turbo","claude-opus-4-8","claude-opus-4-7","claude-opus-4-6"],"description":"Most capable. Deep reasoning, agentic coding, long-horizon work. Upgraded 24.09.2026 from Opus 5 to Opus 5.5 (drop-in: any name containing opus, including claude-opus-5, now runs on Opus 5.5). 1M context (default and max). Default effort on Opus 5.5 is medium (was high on Opus 5), pass effort explicitly if you relied on the default.","context":1000000,"max_output":128000,"max_output_proxy_cap":"21000 tokens for non-streaming direct mode (use stream=true for full 128K output)","max_tokens_floor":"16000 — proxy raises any lower value for opus, because thinking is ON BY DEFAULT on Opus 5 and shares the budget with the visible answer (added 25.07.2026)","price_input":"$4/MTok","price_output":"$20/MTok","price_cache_read":"$0.20/MTok","price_cache_write_5m":"$5/MTok","price_cache_write_1h":"$8/MTok","prompt_cache_min":"512 tokens (lowest of all models; was 1024 on Opus 4.8)","extended_thinking":true,"adaptive_thinking":true,"thinking_default":"ALWAYS ON on Opus 5.5 - cannot be disabled. thinking={type:disabled} and {type:enabled,budget_tokens} return 400 at Anthropic; the proxy removes them and the request runs adaptive","effort_levels":["low","medium","high","xhigh","max"],"thinking_shape":"{type: 'adaptive'} — Opus 5 picks its own budget. Proxy passes output_config.effort as-is; all 5 levels supported natively since 25.07.2026 (xhigh/max are no longer downgraded to high).","sampling_params":"temperature/top_p/top_k are REJECTED by Anthropic (400) — proxy drops them silently","constraint":"tool_choice {type:any} / {type:tool} return 400 on Opus 5.5 (only auto and none are supported) - the proxy lowers them to auto, so the model may answer in text instead of calling the tool. response_format json_schema keeps working. Assistant prefill (last message from assistant) is not supported on Opus 5.5."},{"id":"claude-sonnet-5","alias":["sonnet","gpt-4o","claude-sonnet-5"],"description":"Best balance of speed and quality — near-Opus quality on coding and agentic work. Default model. Upgraded 25.07.2026 from Sonnet 4.6 at the SAME price. 1M context.","context":1000000,"max_output":128000,"max_output_proxy_cap":"21000 tokens for non-streaming direct mode (use stream=true for full 128K output)","price_input":"$3/MTok","price_output":"$15/MTok","price_cache_read":"$0.30/MTok","price_cache_write_5m":"$3.75/MTok","price_cache_write_1h":"$6/MTok","prompt_cache_min":"1024 tokens","extended_thinking":true,"adaptive_thinking":true,"thinking_default":"adaptive when the thinking field is omitted","effort_levels":["low","medium","high","xhigh","max"],"thinking_shape":"{type: 'adaptive'} — budget_tokens was removed in Sonnet 5 (returns 400); proxy converts legacy budget_tokens automatically.","sampling_params":"temperature/top_p/top_k are REJECTED by Anthropic (400) — proxy drops them silently (fixed 25.07.2026)"},{"id":"claude-sonnet-5-5","alias":[],"description":"Best balance of speed and quality. Current Sonnet since 02.10.2026 (any name containing sonnet now runs on Sonnet 5.5). 1M context.","context":1000000,"max_output":128000,"max_output_proxy_cap":"21000 tokens for non-streaming direct mode (use stream=true for full output)","price_input":"$2/MTok","price_output":"$10/MTok","price_cache_read":"$0.10/MTok","price_cache_write_5m":"$2.50/MTok","price_cache_write_1h":"$4/MTok","prompt_cache_min":"1024 tokens","extended_thinking":true,"adaptive_thinking":true,"thinking_default":"adaptive when the thinking field is omitted","effort_levels":["low","medium","high","xhigh","max"],"sampling_params":"temperature/top_p/top_k are REJECTED by Anthropic (400) — proxy drops them silently"},{"id":"claude-haiku-5-5","alias":["haiku","gpt-3.5-turbo","gpt-4o-mini"],"description":"Fastest. Simple tasks, quick answers. 1M context. Current Haiku since 10.10.2026 (claude-haiku-4-5 and other haiku names resolve to it). ВНИМАНИЕ: на haiku действует потолок усилий medium (см. proxy_behaviour.effort_caps) — запрос с high/xhigh/max будет понижен, ошибки не будет.","context":1000000,"max_output":128000,"max_output_proxy_cap":"21000 tokens for non-streaming direct mode (use stream=true for full output)","price_input":"$1/MTok","price_output":"$5/MTok","price_cache_read":"$0.10/MTok","price_cache_write_5m":"$1.25/MTok","price_cache_write_1h":"$2/MTok","prompt_cache_min":"512 tokens (Haiku 5.5, since 10.10.2026)","extended_thinking":true,"adaptive_thinking":false,"effort_levels":["low","medium","high","xhigh","max"],"thinking_shape":"{type: 'enabled', budget_tokens: N} — effort=medium->4000, high->10000, xhigh->13000, max->16000.","sampling_params":"temperature/top_p/top_k return 400 on Haiku 5.5; proxy silently drops them"},{"id":"gpt-6-astra","alias":[],"provider":"openai","description":"OpenAI's most capable model, for the hardest end-to-end work: computer use, browsing, software engineering, science. Added 08.09.2026.","context":872000,"max_output":128000,"price_input":"$10/MTok","price_output":"$50/MTok","price_cache_read":"$1/MTok","price_cache_write":"$12.50/MTok","effort_levels":["low","medium","high","xhigh","max"],"sampling_params":"temperature/top_p REJECTED (400) - proxy drops them","notes":"Unlike the 5.6 family it REJECTS effort 'none' and 'minimal' (400); the proxy raises such a request to 'low' instead of failing. Knowledge cutoff 30.04.2026.","access":"closed by default - granted per key via allowed_models, because it burns the shared subscription window fastest"},{"id":"gpt-5.6-sol","alias":[],"provider":"openai","max_output":128000,"description":"OpenAI flagship for hard tasks. Frontier agentic coding model.","context":872000,"price_input":"$5/MTok","price_output":"$30/MTok","price_cache_read":"$0.50/MTok","price_cache_write":"not billed","effort_levels":["none","low","medium","high","xhigh","max"],"sampling_params":"temperature/top_p REJECTED (400) - proxy drops them","notes":"Fast mode (service_tier=priority) doubles the price - proxy does not enable it."},{"id":"gpt-5.6-terra","alias":[],"provider":"openai","max_output":128000,"description":"OpenAI balanced model for everyday work. Fallback target for sonnet.","context":872000,"price_input":"$2/MTok","price_output":"$12/MTok","price_cache_read":"$0.20/MTok","price_cache_write":"not billed","effort_levels":["none","low","medium","high","xhigh","max"]},{"id":"gpt-5.6-luna","alias":[],"provider":"openai","max_output":128000,"description":"OpenAI fast and cheap. Fallback target for haiku. 25x cheaper than Sol on output.","context":872000,"price_input":"$0.20/MTok","price_output":"$1.20/MTok","price_cache_read":"$0.02/MTok","price_cache_write":"not billed","effort_levels":["none","low","medium","high","xhigh","max"]},{"id":"gpt-5.5","alias":[],"provider":"openai","max_output":128000,"description":"Previous OpenAI flagship. Same price as Sol - prefer Sol or Terra.","context":272000,"price_input":"$5/MTok","price_output":"$30/MTok","price_cache_read":"$0.50/MTok","effort_levels":["none","low","medium","high","xhigh"],"notes":"No 'max' effort - proxy lowers it to xhigh instead of returning 400."},{"id":"gpt-5.4","alias":[],"provider":"openai","status":"REMOVED","description":"GONE from the subscription catalog since early September 2026 - any request returns 400 'not supported when using Codex with a ChatGPT account' (verified 08.09.2026 both in the catalog and with a live request). Removed from /v1/models so nobody plans around a model that no longer answers. Use gpt-5.6-terra instead - the proxy answers with that replacement name instead of passing the provider's raw 400. Long context moved to the 5.6 family, which accepts the same volume (872000).","context":0,"price_input":"$2.50/MTok","price_output":"$15/MTok"},{"id":"gpt-5.4-mini","alias":[],"provider":"openai","status":"REMOVED","description":"GONE from the subscription catalog since 09.09.2026 - any request returns 400 'not supported when using Codex with a ChatGPT account'. Verified three ways: our catalog watcher alerted at 05:43, the live catalog no longer lists it, and a direct request returns the 400 (control: gpt-5.6-luna returned 200 in the same run). Use gpt-5.6-luna instead - same role, cheaper. The proxy answers with that replacement name instead of passing the provider's raw 400.","context":0,"price_input":"$0.75/MTok","price_output":"$4.50/MTok"},{"id":"muse-spark-1.3","alias":[],"provider":"meta","description":"Meta Muse Spark, обычная линейка. Данные клиента НЕ используются для обучения Meta. Контекст миллион токенов. Проверено живыми запросами через прокси 18.09.2026: текст, вызов инструментов (модель вернула tool_use с разобранными аргументами), размышление, картинки на вход (четыре картинки разных цветов названы верно, среди них два оттенка оливкового, то есть три независимых цвета; при контрольном запросе без картинки модель отвечает 'Неизвестно') и PDF (метка внутри файла прочитана). Картинку присылайте размером хотя бы в десятки пикселей: на 1x1 модель отвечает наугад. Картинку и PDF присылайте вложением base64: по ссылке их скачивает только путь OpenAI, на Meta ссылка уходит провайдеру как есть.","context":1048576,"max_output":128000,"price_input":"$1.25/MTok","price_output":"$4.25/MTok","price_cache_read":"$0.15/MTok","price_cache_write":"not billed","effort_levels":["low","medium","high","xhigh","max"],"max_tokens_floor":"16000 (с 19.09.2026, было 4096) - размышление у Meta включено ВСЕГДА и делит бюджет с ответом; при более тесном лимите приходит пустой ответ при полном счете output_tokens. Ночь 19.09.2026: все 169 запросов с max_tokens=8000 пришли пустыми, поэтому пол поднят до уровня Opus","training":false,"access":"closed by default - granted per key via allowed_models","notes":"Прокси сам снимает поля, которые Meta отвергает с 400: stop_sequences, top_k, часовой срок кеша. Уровня max у Meta нет, он приземляется в xhigh. Кеш префикса включается сам, управлять им нечем; попадание не гарантировано на каждом повторе (канонический замер tests/meta/probe_capabilities.py 18.09.2026, префикс ~10800 токенов: 10825 / 102 при чтении 10723 / 102 при 10723 / снова 10825). Стрим настоящий, но первая дельта приходит через 7-22 секунды (замеры через прокси 18.09.2026), дальше текст идет потоком; прокси каждые 15 секунд держит соединение служебным событием (event: ping на /v1/messages, строка-комментарий на /v1/chat/completions)."},{"id":"muse-spark-1.3-contributor","alias":[],"provider":"meta","description":"🔴 ТА ЖЕ МОДЕЛЬ, НО META ОБУЧАЕТСЯ НА ВАШИХ ДАННЫХ. Промпты и ответы уходят в обучение Meta - это условие линейки contributor, и именно за это она дешевле обычной более чем в 12 раз по входу и более чем в 21 раз по выходу. Самая дешевая ЧАТ-модель в нашем прайсе: дешевле стоят только эмбеддинги, а они не для диалога. Не отправляйте сюда ничего, что не готовы отдать Meta.","context":1048576,"max_output":128000,"price_input":"$0.10/MTok","price_output":"$0.20/MTok","price_cache_read":"$0.002/MTok","price_cache_write":"not billed","effort_levels":["low","medium","high","xhigh"],"max_tokens_floor":"16000 - как у обычной линейки (с 19.09.2026)","training":true,"training_warning":"Meta trains on your prompts and completions. This is what makes the model cheap.","access":"closed by default - granted per key via allowed_models","notes":"Возможности и ограничения те же, что у muse-spark-1.3. Кеш префикса работает и здесь, замерено на САМОЙ этой линейке (канонический прогон tests/meta/probe_capabilities.py 18.09.2026, префикс ~10800 токенов): 10824 / 101 при чтении 10723 / 101 при 10723 / 101 при 10723. На обычной линейке в том же прогоне четвертый запрос ушел мимо кеша - попадание не гарантировано на каждом повторе. Эта же модель используется как третье звено аварийной подмены при одновременной перегрузке Claude и OpenAI - тогда ответ помечен заголовком X-Fallback-Training: true."},{"id":"text-embedding-3-small","alias":[],"provider":"openai","kind":"embeddings","description":"Эмбеддинги для поиска по смыслу. Endpoint /v1/embeddings, НЕ /v1/chat/completions (запрос в чат отклоняется с 400 и подсказкой). Открыта ВСЕМ клиентам: идёт на api.openai.com со своим лимитом 5000 запросов/мин, недельное окно подписки не тратит.","dimensions":1536,"max_input":"8191 токенов","price_input":"$0.02/MTok","price_output":"не тарифицируется","note":"Запрос меньше ~50 токенов записывается как $0.000000 - предел точности хранения decimal(12,6), округление всегда в пользу клиента. Батчи и дешевле, и точнее считаются."},{"id":"text-embedding-3-large","alias":[],"provider":"openai","kind":"embeddings","description":"Эмбеддинги повышенной точности. Тот же endpoint /v1/embeddings.","dimensions":3072,"max_input":"8191 токенов","price_input":"$0.13/MTok","price_output":"не тарифицируется"},{"id":"gpt-image-2","alias":[],"provider":"openai","kind":"images","description":"Генерация изображений. Endpoint /v1/images/generations. Доступ точечный: картинки реально жгут недельное окно подписки.","price_per_image_square":"low $0.006 / medium $0.053 / high $0.211","price_per_image_non_square":"low $0.005 / medium $0.041 / high $0.165","max_images_per_request":4,"pre_debit_hold":"$0.85 (худший случай 4 x $0.211)","note":"ЦЕНА НЕ ПО ТОКЕНАМ. Замер 03.08.2026: PNG на 732674 байт пришел при output_tokens=47 - картинки в usage нет вообще, стоимость начисляется надбавкой. Модель отдает свое разрешение (просили 1024x1024, пришло 1254x1254). Без параметра size он уходит клиенту как есть, с size - приводится кропом по центру. background=transparent дает 400; параметр model в теле эндпоинт не читает вовсе. Промпт по умолчанию переписывается по cookbook - управляется полем prompt_mode (rewrite | enhance | off), результат виден в prompt_applied."}],"note":"OpenAI model names auto-mapped to Claude equivalents. Model id with date suffix (claude-haiku-4-5-20251001, resolved to claude-haiku-5-5) also accepted. ЛЮБОЕ имя, содержащее opus/sonnet/haiku, резолвится в актуальный snapshot этой семьи — старые клиенты работают без правок и автоматически получают Opus 5 / Sonnet 5 (обновлено 25.07.2026).","effort_to_thinking_mapping":{"opus (Opus 5)":"любой уровень выше low → thinking={type: 'adaptive'}; глубину выбирает модель, output_config.effort идёт отдельно. Уровни xhigh и max больше НЕ понижаются до high (это было верно для снятого Opus 4.7).","sonnet (Sonnet 5) / haiku (5.5)":"budget_tokens для type=enabled: medium → 4000, high → 10000, xhigh → 13000, max → 16000","effort=low":"размышление выключено у всех моделей","effort=none / minimal":"у моделей Anthropic таких уровней нет — прокси приводит их к low (иначе включилось бы размышление на 8000 токенов, то есть ДОРОЖЕ medium). У семьи gpt-5.6 и gpt-5.5 уровень none штатный и передаётся как есть."}},"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":"⚠️ NOT IMPLEMENTED YET (planned). session_id is returned in response and accepted in subsequent requests, but the proxy does NOT currently resume the SDK session — every call starts fresh. Send conversation history yourself via messages[] array (standard OpenAI behavior). True server-side resume is on the roadmap.","when_to_use":"For now: include full message history in each request (standard OpenAI flow). Future: persistent server-side memory across requests.","status":"planned — session_id resume not active as of 17.05.2026","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 5 / Sonnet 5 / Haiku 5.5 support extended thinking — reasoning before responding. On Opus 5 thinking is ON BY DEFAULT (omitting the field runs adaptive) and shares max_tokens with the visible answer. 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 (5)":"effort=medium/high/xhigh/max → thinking={type:'adaptive'} + output_config.effort, проброс as-is (Opus 5 сам выбирает бюджет). Все 5 уровней поддерживаются. ВАЖНО: thinking включён ПО УМОЛЧАНИЮ — запрос без поля thinking всё равно думает.","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/4.8 (classic 'enabled' fails with 400). Claude auto-picks budget.","enabled":"{type: 'enabled', budget_tokens: N} — LEGACY, for Haiku 5.5 and older models (accepted on subscription 10.10.2026). On Opus 5 / Sonnet 5 budget_tokens returns 400; use {type: 'adaptive'} + output_config.effort instead (proxy converts legacy budget_tokens automatically). N must be < max_tokens.","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/4.8 does NOT accept 'enabled' type — proxy converts effort=* to 'adaptive' automatically. Old 'enabled' requests will get 400 from Anthropic.","Opus 5 / Sonnet 5 support all 5 effort levels natively (low/medium/high/xhigh/max). Proxy passes them through unchanged since 25.07.2026."]}},"endpoints":[{"method":"POST","path":"/v1/chat/completions","description":"Send a message and get Claude's response. Fully OpenAI-compatible. Supports text, vision (multimodal), tools/function calling, structured output (json_schema), streaming, extended thinking, prompt caching.","request_body":{"model":{"type":"string","required":false,"default":"sonnet","description":"Model to use. Accepts Claude IDs (claude-sonnet-5), short names (sonnet), or OpenAI aliases (gpt-4o, gpt-4o-mini)."},"messages":{"type":"array | string","required":true,"description":"Array of {role, content} objects. content can be string OR array of blocks (text/image). role values: 'system', 'user', 'assistant', 'tool'. Also accepts plain string (shortcut).","example":[{"role":"system","content":"You are a helpful assistant."},{"role":"user","content":"Hello!"}]},"documents_note":{"type":"info","required":false,"description":"PDF works on ALL THREE providers (Anthropic, OpenAI, Meta). Two block formats are accepted: Anthropic native {\"type\":\"document\",\"source\":{\"type\":\"base64\",\"media_type\":\"application/pdf\",\"data\":\"...\"}} and OpenAI standard {\"type\":\"file\",\"file\":{\"filename\":\"doc.pdf\",\"file_data\":\"data:application/pdf;base64,...\"}}. The OpenAI form used to be silently dropped - the model replied 'please send the document' while the PDF was attached (fixed 03.08.2026). Plain base64 without the data: prefix and https links are also accepted."},"vision_note":{"type":"info","required":false,"description":"Images work on all three providers (Anthropic, OpenAI, Meta). Send them as base64 data URLs or as https links - the proxy handles both. Links are downloaded on our side ONLY on the OpenAI path, because Codex times out fetching them itself; on the Anthropic and Meta paths the link is passed through as is and the provider fetches it (fixed 03.08.2026: half of one client's requests were failing with 'Unable to download content from the provided URL'). Download limits: 12s timeout, 20 MB per image; if a link cannot be fetched it is passed through unchanged."},"system":{"type":"string | array","required":false,"description":"Anthropic top-level system prompt. Alternative to messages[role=system]. Accepts string OR array of blocks [{type:'text', text:'...', cache_control:{...}}]. Used by Anthropic SDK clients."},"stream":{"type":"boolean","required":false,"default":false,"description":"Enable real-time SSE streaming. Tokens arrive as they are generated. Tool calls also stream incrementally (tool_use_start / input_delta / tool_use_stop)."},"max_tokens":{"type":"integer","required":false,"default":4096,"description":"Max output tokens. PASSTHROUGH: клиентский max_tokens пробрасывается в Anthropic (fix 01.06.2026 — раньше терялся в парсинге и любой ответ обрезался на 4096). Caps по модели + режиму: non-stream = 21000 (SDK 10-min timeout limit). Stream: opus/sonnet/haiku = 128000 (per-model Anthropic limits, обновлено 25.07.2026). Для opus действует ПОЛ 16000 — меньшие значения поднимаются, т.к. thinking включён по умолчанию и делит бюджет с ответом. Если передать больше — proxy clamp'нет до cap. Используй stream=true для длинных ответов. Aliased as max_completion_tokens (OpenAI). Для extended thinking: если budget_tokens >= max_tokens, proxy auto-raises max_tokens до budget+1024."},"max_completion_tokens":{"type":"integer","required":false,"description":"Alias of max_tokens (OpenAI o-series naming). Used identically."},"temperature":{"type":"float","required":false,"description":"Sampling temperature 0.0-1.0. Lower = more deterministic, higher = more creative. Passed through to Anthropic. (Active since 17.05.2026 — earlier versions silently ignored this field.)"},"top_k":{"type":"integer","required":false,"description":"Top-K sampling (Anthropic-only param). Sample only from top K tokens at each step. (Active since 01.06.2026.) ⚠️ Opus 4.7/4.8 silently игнорирует этот параметр — Anthropic вернёт 400 если передать. Для Sonnet/Haiku работает."},"top_p":{"type":"float","required":false,"description":"Top-P (nucleus) sampling 0.0-1.0. Sample from smallest set of tokens whose cumulative probability >= top_p. (Active since 01.06.2026.) ⚠️ Opus 4.7/4.8 silently игнорирует — Anthropic вернёт 400. Для Sonnet/Haiku работает. НЕ используй одновременно с temperature."},"stop_sequences":{"type":"array","required":false,"description":"До 4 строк при встрече которых модель остановит генерацию. Также принимаются alias 'stop' (OpenAI naming). Stop sequences не возвращаются в ответе. (Active since 01.06.2026.)"},"stop":{"type":"string | array","required":false,"description":"OpenAI alias для stop_sequences. Принимается string или array of strings. Конвертируется в Anthropic stop_sequences."},"service_tier":{"type":"string","required":false,"description":"Anthropic service tier: 'auto' (default — Anthropic выбирает) или 'standard_only'. (Active since 01.06.2026.) Работает ТОЛЬКО для non-stream. Stream запросы всегда идут на standard. На OAuth-подписке max — оба варианта эквивалентны."},"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', 'xhigh', 'max'. Opus 5 и Sonnet 5 поддерживают все 5 уровней нативно (с 25.07.2026 xhigh/max больше НЕ понижаются до high). Anthropic рекомендует xhigh для coding/agentic задач. Works in BOTH modes. For SDK session → --effort flag to Claude Code. For Direct API → maps to Anthropic extended thinking (see effort_to_thinking_mapping in models)."},"thinking":{"type":"object","required":false,"description":"Raw Anthropic extended thinking config (Direct API only). Overrides effort-mapping. Shapes: {type:'adaptive'} for Opus 4.7/4.8 (REQUIRED — classic 'enabled' fails with 400), {type:'enabled', budget_tokens:N} for Sonnet/Haiku/Opus 4.6, {type:'disabled'}."},"mode":{"type":"string","required":false,"default":"session","description":"Execution mode: 'direct' = Direct Anthropic Messages API (fast, supports vision/tools/thinking), 'session' = SDK persistent session (full Claude Code agent with file tools, web search, bash). Aliases: 'lightweight' (= direct), 'stream' (= direct + force streaming). Auto-forced to direct when tools, response_format, or multimodal content is present."},"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."},"tools":{"type":"array","required":false,"description":"Function calling. Accepts BOTH OpenAI format [{type:'function', function:{name, description, parameters}}] AND Anthropic format [{name, description, input_schema}]. Also passes Anthropic server tools (web_search_*, bash_*, code_execution_*, text_editor_*) without conversion. OpenAI server tools [{type:'web_search'}] and [{type:'image_generation'}] work on gpt-5.* models (fixed 03.08.2026 - they used to be silently dropped, so the model answered from memory instead of searching). On Claude models these two are dropped on purpose, since Anthropic expects its own format and would return 400. Presence of tools forces mode=direct."},"tool_choice":{"type":"string | object","required":false,"description":"How model should pick tools. Values: 'auto' (default), 'none', 'required' (must call any tool), 'any' (Anthropic synonym for required), OR {type:'function', function:{name:'X'}} to force specific tool. Converted to Anthropic {type:'auto'|'any'|'tool', name:?}."},"response_format":{"type":"object","required":false,"description":"Structured output. {type:'json_object'} — appends JSON instruction to system + strips ```json``` wrapper from response. {type:'json_schema', json_schema:{name:'X', schema:{...}, description?:'...'}} — internally creates a forced tool call (Anthropic tool_use) and returns the JSON in choices[0].message.content. Used by LangChain with_structured_output, Pydantic-AI, Graphiti."},"cache_control":{"type":"object","required":false,"description":"Per-message or per-block Anthropic prompt cache marker. Shape: {type:'ephemeral', ttl?:'5m'|'1h'}. Can be placed on message-level (msg.cache_control) or on individual content blocks. See full prompt_caching section."},"disable_auto_cache":{"type":"boolean","required":false,"default":false,"description":"Disable proxy's automatic system_prompt caching. Equivalent to sending header 'X-No-Auto-Cache: 1'. Use when you don't want any cache_control added automatically (e.g. for testing exact cache behavior)."},"metadata":{"type":"object","required":false,"description":"Anthropic metadata object + proxy-specific extension fields. Recognized subfields: metadata.user_id (≤256 chars, opaque end-user identifier for Anthropic abuse-detection — НЕ email/PII), metadata.prompt_type (string label for аналитики — появляется в /v1/usage?group_by=prompt_type). Also accepts top-level prompt_type field as shortcut for metadata.prompt_type."},"session_id":{"type":"string","required":false,"description":"⚠️ PLANNED feature. Currently returned in response but NOT yet used to resume SDK sessions. Include full message history yourself for now."}},"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-5\",\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)"},"response_headers":{"X-Request-ID":"req-XXXXXXXXXXXX (unique id, always returned — also reflected in 500 traceback log for cross-service debugging). Clients may send their own X-Request-ID to override.","Content-Type":"application/json (non-stream) OR text/event-stream (stream=true)"},"error_responses":{"400":{"error":{"type":"invalid_request_error","message":"<reason from Anthropic>","request_id":"req-..."},"_when":"malformed body, unsupported field combinations, Anthropic 400 propagated."},"401":{"detail":"Invalid or expired API key","_when":"missing/invalid Bearer key, x-api-key, or ?key="},"402":{"error":{"type":"insufficient_balance","message":"Balance too low. Top up at /cabinet#billing","balance":-0.34,"credit_limit":1.0,"tier":"new","payments_count":0},"_when":"balance + credit_limit < estimated cost. credit_limit depends on credit tier (new=$1, active=$10, loyal=$20)."},"403":{"detail":"Model not allowed for this key","_when":"key's allowed_models field doesn't include requested model"},"429":{"error":"rate_limit_error","rate_limit":{"unified_status":"warning","utilization_7d_pct":95.2,"fallback_percentage":95.2},"_when":"Daily limit (max_requests_per_day) OR OAuth pool unified rate limit (5h/7d windows)"},"500":{"error":{"type":"internal_server_error","message":"...","request_id":"req-..."},"_when":"Unhandled exception. Use X-Request-ID to correlate with /var/log/nginx/...5xx.log and server_500.log. Added 15.05.2026."},"503":{"detail":"Service is in maintenance mode","_when":"admin enabled maintenance flag"},"504":{"detail":"Gateway Timeout","_when":"Anthropic API upstream timeout (rare, retried automatically)"}},"billing_note":"Each request costs tokens from your balance. +$5 bonus on your first top-up. Credit tier extends overdraft limit ($0/$10/$20). Pricing: /billing/pricing"},{"method":"POST","path":"/v1/messages","description":"Anthropic Messages API compatible endpoint. Native /v1/messages format for langchain-anthropic, anthropic Python SDK, Cline, Cursor, Claude Desktop connectors.","auth_note":"Accepts Authorization: Bearer and x-api-key. NOTE: ?key= query param is NOT supported on this endpoint (only on /v1/chat/completions). Use header.","request_body":{"model":{"type":"string","required":true,"description":"Claude model id or alias (claude-sonnet-5, sonnet, opus, haiku)."},"messages":{"type":"array","required":true,"description":"Anthropic format: [{role, content}]. content can be string OR array of blocks ({type:'text'|'image'|'tool_use'|'tool_result'})."},"system":{"type":"string | array","required":false,"description":"System prompt. String or array of {type:'text', text, cache_control?}. Multi-block supported with caching."},"max_tokens":{"type":"integer","required":true,"description":"Max output tokens. Per Anthropic spec — required для этого endpoint. PASSTHROUGH (fix 01.06.2026): клиентский max_tokens пробрасывается. Caps: non-stream = 21000 (SDK 10-мин timeout), stream opus/sonnet = 128000, stream haiku = 128000. Для opus пол 16000 (thinking по умолчанию). Превышение → proxy clamp до cap."},"stream":{"type":"boolean","required":false,"default":false,"description":"SSE in Anthropic format: message_start / content_block_start / content_block_delta / content_block_stop / message_delta / message_stop / ping events (keepalive every 15s)."},"temperature":{"type":"float","required":false,"description":"0.0-1.0 sampling temperature. (Active since 17.05.2026 fix.)"},"top_k":{"type":"integer","required":false,"description":"Anthropic Top-K sampling. (Active since 01.06.2026.) ⚠️ Opus 4.7/4.8 silently игнорирует — Anthropic вернёт 400."},"top_p":{"type":"float","required":false,"description":"Anthropic Top-P (nucleus) sampling 0.0-1.0. (Active since 01.06.2026.) ⚠️ Opus 4.7/4.8 silently игнорирует. НЕ используй одновременно с temperature."},"stop_sequences":{"type":"array","required":false,"description":"До 4 строк. При встрече модель останавливается. Не возвращаются в ответе. (Active since 01.06.2026.)"},"service_tier":{"type":"string","required":false,"description":"'auto' (default) или 'standard_only'. (Active since 01.06.2026.) Только для non-stream. На OAuth max-подписке оба варианта эквивалентны."},"tools":{"type":"array","required":false,"description":"Anthropic native tools format: [{name, description, input_schema}]. Also accepts OpenAI tools — auto-converted."},"tool_choice":{"type":"object","required":false,"description":"{type:'auto'|'any'|'tool'|'none', name?:'X'}"},"effort":{"type":"string","required":false,"description":"Proxy extension: 'low'/'medium'/'high'/'xhigh'/'max'. Auto-maps to thinking config."},"thinking":{"type":"object","required":false,"description":"Anthropic extended thinking. {type:'adaptive'} (Opus 4.7/4.8), {type:'enabled', budget_tokens:N} (Sonnet/Haiku/Opus 4.6)."},"metadata":{"type":"object","required":false,"description":"Anthropic metadata + proxy fields. Recognized subfields: metadata.user_id (≤256 chars opaque end-user id для Anthropic abuse-detection), metadata.prompt_type (analytics label)."}},"response":{"id":"msg_xxxx","type":"message","role":"assistant","model":"claude-sonnet-5","content":[{"type":"text","text":"Response"}],"stop_reason":"end_turn","usage":{"input_tokens":12,"output_tokens":45,"cache_creation_input_tokens":0,"cache_read_input_tokens":0}},"examples":{"python_anthropic":"from anthropic import Anthropic\n\nclient = Anthropic(\n    api_key=\"YOUR_API_KEY\",  # sk-cc-...\n    base_url=\"https://claude.ai-platform.space\"\n)\nmessage = client.messages.create(\n    model=\"claude-sonnet-5\",\n    max_tokens=4096,\n    messages=[{\"role\": \"user\", \"content\": \"Hello!\"}]\n)\nprint(message.content[0].text)","python_stream":"from anthropic import Anthropic\nclient = Anthropic(api_key=\"YOUR_API_KEY\", base_url=\"https://claude.ai-platform.space\")\nwith client.messages.stream(\n    model=\"sonnet\", max_tokens=1024,\n    messages=[{\"role\": \"user\", \"content\": \"Tell me a joke\"}]\n) as stream:\n    for text in stream.text_stream:\n        print(text, end=\"\", flush=True)","curl_basic":"curl -X POST https://claude.ai-platform.space/v1/messages \\\n  -H \"x-api-key: YOUR_API_KEY\" \\\n  -H \"anthropic-version: 2023-06-01\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"model\":\"claude-sonnet-5\",\"max_tokens\":1024,\"messages\":[{\"role\":\"user\",\"content\":\"Hello!\"}]}'"},"error_responses":{"401":{"detail":"Invalid or expired API key"},"402":{"error":{"type":"insufficient_balance","message":"Balance too low. Top up at /cabinet#billing"},"_note":"Balance check added 17.05.2026 — earlier versions skipped this on /v1/messages."},"403":{"detail":"Model not allowed for this key"},"429":{"detail":"Daily request limit exceeded"}},"billing_note":"Each request costs tokens from your balance. Same billing as /v1/chat/completions."},{"method":"POST","path":"/v1/messages/count_tokens","description":"Anthropic Messages Token Counting API. Возвращает точное число input_tokens для конкретного payload БЕЗ генерации ответа. Полезно для LangChain/LlamaIndex/Pydantic-AI — оценка стоимости до отправки, проверка лимита контекста, бюджетирование. БЕСПЛАТНО (не списывает с баланса). Идентичный shape запроса/ответа с api.anthropic.com.","auth_note":"Accepts Authorization: Bearer и x-api-key. Header anthropic-version: 2023-06-01 рекомендуется (не обязателен).","request_body":{"model":{"type":"string","required":true,"description":"Claude model id или alias (claude-sonnet-5, sonnet, opus, haiku). Считает токены по tokenizer'у конкретной модели."},"messages":{"type":"array","required":true,"description":"Anthropic format: [{role, content}]. content может быть string ИЛИ array of blocks (text/image/tool_use/tool_result)."},"system":{"type":"string | array","required":false,"description":"System prompt. String или array of {type:'text', text, cache_control?}."},"tools":{"type":"array","required":false,"description":"Если есть — tools schema тоже учитывается в подсчёте (tools кушают input_tokens)."},"tool_choice":{"type":"object","required":false,"description":"Tool choice (учитывается)."}},"response":{"input_tokens":12345},"examples":{"curl_basic":"curl -X POST https://claude.ai-platform.space/v1/messages/count_tokens \\\n  -H \"x-api-key: YOUR_API_KEY\" \\\n  -H \"anthropic-version: 2023-06-01\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"model\":\"claude-sonnet-5\",\"messages\":[{\"role\":\"user\",\"content\":\"Hello, world!\"}]}'","python_anthropic":"from anthropic import Anthropic\n\nclient = Anthropic(api_key=\"sk-cc-YOUR_KEY\", base_url=\"https://claude.ai-platform.space\")\nresult = client.messages.count_tokens(\n    model=\"claude-sonnet-5\",\n    messages=[{\"role\": \"user\", \"content\": \"How many tokens is this?\"}],\n)\nprint(result.input_tokens)","langchain":"# LangChain использует count_tokens внутри для get_num_tokens_from_messages()\nfrom langchain_anthropic import ChatAnthropic\n\nllm = ChatAnthropic(\n    model=\"claude-sonnet-5\",\n    anthropic_api_url=\"https://claude.ai-platform.space\",\n    anthropic_api_key=\"sk-cc-YOUR_KEY\",\n)\nn_tokens = llm.get_num_tokens_from_messages([HumanMessage(\"Hello\")])"},"response_headers":{"X-Request-ID":"req-XXX","Content-Type":"application/json"},"error_responses":{"400":{"error":{"type":"invalid_request_error","message":"<reason>"},"_when":"невалидный shape запроса, неподдерживаемая модель"},"401":{"detail":"Invalid or expired API key"}},"billing_note":"БЕСПЛАТНО — token counting не списывает с баланса. Anthropic считает токены своим tokenizer'ом без вызова модели."},{"method":"POST","path":"/v1/images/generations","description":"Generate images (gpt-image-2 via the OpenAI subscription pool). OpenAI-compatible: the official openai-python client works unchanged. This is NOT available on the Claude pool - Anthropic has no image generation at all.","request_body":{"prompt":{"type":"string","required":true,"description":"What to draw."},"n":{"type":"integer","required":false,"default":1,"description":"How many images, 1-4. The tool draws one image per call, so n=4 means four sequential generations. Capped at 4 to protect the shared weekly subscription quota."},"size":{"type":"string","required":false,"default":null,"description":"Any WxH up to 4096, e.g. 1024x1024 | 1024x1536 | 1536x1024 | auto. OMIT IT and you get the model's native resolution untouched - usually the best choice. Pass it and the proxy fits the result to your exact size by CENTER-CROPPING (like CSS object-fit: cover): geometry is preserved, edges are trimmed. It never stretches. Note the upstream model ignores this parameter entirely and picks its own framing from the wording of the prompt, so ask for the aspect ratio in words too - or leave prompt_mode on and the proxy adds those words for you. The raw model resolution comes back in data[].model_size."},"quality":{"type":"string","required":false,"default":"medium","description":"low | medium | high. Drives the price directly - see billing_note."},"output_format":{"type":"string","required":false,"default":"png","description":"png | jpeg | webp."},"background":{"type":"string","required":false,"default":"opaque","description":"Only 'opaque' is supported. 'transparent' returns 400 from the upstream API, so the proxy silently falls back to opaque instead of failing your request."},"prompt_mode":{"type":"string","required":false,"default":"rewrite","description":"How the proxy treats your prompt before sending it upstream. 'rewrite' (default) - a Sonnet pass rewrites it following the official OpenAI prompting cookbook: scene, subject, materials, lighting, composition, exclusions. 'enhance' - only fills in what is missing, your own wording stays recognisable. 'off' - untouched. Aliases accepted: full/replace/true -> rewrite, improve/auto -> enhance, none/no/raw/false -> off. An unknown value returns 400 rather than silently defaulting. The rewrite costs you nothing extra and adds about 2-4 seconds. Whatever happens is fully visible in the response: prompt_original, prompt_applied, prompt_changes, prompt_hints. Pass 'off' or 'enhance' when your prompt is an exact spec (literal on-image text, precise object list)."},"images":{"type":"array","required":false,"description":"Up to 4 input images as base64 or data: URLs - this turns the request into an EDIT. Also accepts the singular 'image' field for OpenAI edits compatibility. A truncated or corrupt base64 is rejected with a clear 400 naming the reason, instead of a raw upstream error."},"action":{"type":"string","required":false,"description":"generate | edit | auto. Set automatically to 'edit' when images are present, so you rarely need it."},"mask":{"type":"string","required":false,"description":"PNG with an alpha channel as base64 or data: URL - transparent pixels mark the area the model may change, everything else stays. Requires at least one input image."},"output_compression":{"type":"integer","required":false,"description":"0-100, jpeg and webp only (png is lossless - passing it with png returns 400). webp at 50 gives roughly 26 KB against 1.26 MB for the same png."}},"response":{"created":1785700000,"data":[{"b64_json":"<base64 png>","revised_prompt":"what the upstream model rewrote your prompt into","model_size":"1672x941","size":null}],"model":"gpt-image-2","quality":"low","action":"generate","prompt_mode":"rewrite","prompt_original":"what you sent","prompt_applied":"what was actually sent upstream","prompt_changes":["prompt rewritten following the cookbook structure"],"prompt_hints":["advice we did not apply, e.g. there is on-image text and quality=low is tuned for speed - compare with medium or high"],"model_notes":[],"errors":[],"cost_usd":0.006644,"usage":{"input_tokens":2329,"output_tokens":67,"images":1},"duration_ms":15241},"access_note":"Requires access to the OpenAI pool: at least one gpt-5.* model must be enabled for your key (admins are exempt). This one really does share the weekly subscription quota with the gpt chat models - it runs through the same subscription backend, unlike embeddings and speech-to-text - so it stays gated.","gotchas_note":"1) data[].b64_json is roughly 930 KB of text - write it to a file, do not print it. 2) model_notes is non-empty when the model drew something other than what you asked and explained why in words - always check it, the HTTP status stays 200. 3) errors can be non-empty on a 200 when n>1 and only some images came out. 4) A refusal from the content filter arrives as text from the model, not as a moderation_blocked code - do not retry the same prompt, change it. 5) 402 means your balance is below the $0.85 reserve, 403 means your key has no access to the OpenAI pool.","billing_note":"Priced per image using the official OpenAI table, PLUS the carrier model tokens. Square 1024x1024: low $0.006, medium $0.053, high $0.211. Non-square (1024x1536 / 1536x1024): low $0.005, medium $0.041, high $0.165. The image itself never appears in usage (measured: a 732 KB PNG came back with 47 output tokens), so it is billed as a separate surcharge. A reserve of $0.85 is held before generation and the unused part is refunded immediately after."},{"method":"POST","path":"/v1/audio/transcriptions","description":"Speech-to-text via the OpenAI subscription pool. OpenAI-compatible multipart/form-data, so the official openai-python client works unchanged. Not available on the Claude pool - Anthropic has no speech recognition.","request_body":{"file":{"type":"file","required":true,"description":"Audio file (multipart/form-data). Max 25 MB. mp3/mp4/mpeg/mpga/m4a/wav/webm."},"model":{"type":"string","required":false,"default":"gpt-transcribe","description":"gpt-transcribe (best quality, released 28.07.2026) | gpt-4o-transcribe | gpt-4o-mini-transcribe (cheapest). whisper-1 is NOT available on this subscription - the proxy returns a clear 400 explaining why instead of a raw 401."},"language":{"type":"string","required":false,"description":"ISO-639-1 hint, e.g. 'ru'. Improves accuracy and latency."},"prompt":{"type":"string","required":false,"description":"Context hint - useful for names and domain terms."},"response_format":{"type":"string","required":false,"default":"json","description":"json | text | srt | vtt."}},"response":{"text":"Проверка распознавания речи...","model":"gpt-transcribe","seconds":13.56,"cost_usd":0.001017,"duration_ms":3565},"access_note":"Open to every active key - no extra permission needed (opened 03.08.2026). Speech-to-text does NOT run through the subscription backend that serves the gpt chat models: it goes to api.openai.com, which has its own rate-limit bucket. Measured: 100 requests did not move the weekly subscription window at all (7% -> 7%), and the responses carry their own x-ratelimit-* headers with no x-codex-* among them. You pay per minute from your balance; no scarce shared resource is consumed.","billing_note":"Billed per minute of audio at the official OpenAI rate: gpt-transcribe $0.0045/min, gpt-4o-transcribe $0.006/min, gpt-4o-mini-transcribe $0.003/min. Duration is measured on our side with ffprobe, identical for every model - the provider itself reports seconds for gpt-transcribe but tokens for gpt-4o-transcribe. Minimum billable length is 1 second. A reserve is held before the request and the unused part is refunded immediately.","performance_note":"Measured 03.08.2026 on 13.5s of Russian speech: gpt-transcribe 1.5s, gpt-4o-transcribe 1.1s, gpt-4o-mini-transcribe 0.9s. Quality is comparable across all of them; the reason to use this endpoint is latency, not accuracy."},{"method":"POST","path":"/v1/embeddings","description":"Text embeddings via the OpenAI subscription pool. OpenAI-compatible, so the official client works unchanged.","request_body":{"input":{"type":"string | array","required":true,"description":"Text or array of texts. Up to 2048 items per request, 8191 tokens each."},"model":{"type":"string","required":false,"default":"text-embedding-3-small","description":"text-embedding-3-small (1536 dims, $0.02/MTok) | text-embedding-3-large (3072 dims, $0.13/MTok). text-embedding-ada-002 is NOT available on this subscription - scope is granted per model, and the proxy returns a clear 400 instead of a raw 401."},"dimensions":{"type":"integer","required":false,"description":"Reduce output dimensions (supported by the 3-* models)."},"encoding_format":{"type":"string","required":false,"description":"float (default) or base64."}},"response":{"object":"list","data":[{"object":"embedding","index":0,"embedding":["...1536 floats..."]}],"model":"text-embedding-3-small","usage":{"prompt_tokens":22,"total_tokens":22},"duration_ms":841},"access_note":"Open to every active key - no extra permission needed (opened 03.08.2026). Same reason as speech-to-text: embeddings go to api.openai.com with its own rate-limit bucket and leave the weekly subscription window untouched.","billing_note":"Billed per input token from the pricing table - no surcharge, unlike images and audio. NOTE: cost is stored with 6 decimal places, so a request below ~50 tokens on 3-small rounds down to $0.000000 (about 7 tokens on 3-large). Rounding always favours the client. Batch your texts in one request - it is both cheaper per call and more precise for billing.","quality_note":"Measured 03.08.2026 against the free local multilingual-e5-large running on the same VPS, using Russian domain texts (4 queries, 4 candidate documents each): all three models picked the correct document 4/4, but the margin between the correct and the best wrong document was +0.057 locally versus +0.246 (3-small) and +0.252 (3-large). The margin is what protects you on noisy data. The local model also truncates input at 512 tokens against 8191 here."},{"method":"WSS","path":"/v1/realtime","description":"Realtime voice conversation - audio in and out over a single WebSocket. Not available on the Claude pool at all. The proxy passes the Realtime API protocol through untouched: connect and speak exactly as you would to OpenAI directly.","request_body":{"key":{"type":"query param","required":true,"description":"Your API key. Passed as ?key=... because browser WebSocket cannot set headers; Authorization: Bearer also works for server-side clients."},"model":{"type":"query param","required":false,"default":"gpt-realtime-2.1-mini","description":"gpt-realtime-2.1 | gpt-realtime-2.1-mini | gpt-realtime."}},"response":{"protocol":"Standard OpenAI Realtime API events: session.created, session.update, conversation.item.create, response.create, response.output_audio.delta, response.output_audio_transcript.delta, response.done.","errors":"Rejections arrive as {\"type\":\"error\",\"error\":{\"type\":...,\"message\":...}} right after the handshake, then the socket closes. An invalid key is rejected before the handshake with a plain 403."},"limits_note":"Concurrent sessions: 8 for the whole service, 2 per client. A session is closed after 15 minutes, or after 2 minutes of silence. Check current occupancy with GET /v1/realtime/sessions.","access_note":"Requires access to the OpenAI pool: at least one gpt-5.* model must be enabled for your key (admins are exempt). Unlike embeddings and speech-to-text, this one stays gated - not because of the subscription quota (voice runs on api.openai.com, its own bucket) but because a voice session holds a connection open for minutes inside the same process that carries all production traffic, and only 8 can run at once.","billing_note":"Billed from the usage reported in response.done, not by wall time. Official per-1M-token rates: gpt-realtime-2.1 audio in $32 / cached $0.40 / audio out $64, text $4/$24. gpt-realtime-2.1-mini audio in $10 / cached $0.30 / audio out $20, text $0.60/$2.40. gpt-realtime same audio as 2.1, text $4/$16. Voice is expensive: one minute of synthesized speech is roughly 600 audio tokens. Cached audio tokens are subtracted from the input count so they are never billed twice."},{"method":"GET","path":"/v1/realtime/sessions","description":"How many realtime voice sessions are open right now (total, limit, and per-user breakdown).","request_body":null,"response":{"total":0,"limit":8,"by_user":{}}},{"method":"GET","path":"/v1/models","description":"List available models for your API key.","request_body":null,"response":{"object":"list","data":[{"id":"claude-opus-5-5","object":"model","owned_by":"anthropic"},{"id":"claude-opus-5","object":"model","owned_by":"anthropic"},{"id":"claude-sonnet-5","object":"model","owned_by":"anthropic"},{"id":"claude-opus-4-8","object":"model","owned_by":"anthropic"},{"id":"claude-opus-4-7","object":"model","owned_by":"anthropic"},{"id":"claude-sonnet-4-6","object":"model","owned_by":"anthropic"},{"id":"claude-haiku-5-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, version, OAuth account pool health.","request_body":null,"response":{"status":"running","version":"4.7.0","mode":"direct-api","default_model":"sonnet","pool":{"ready_count":0,"healthy":true}},"examples":{"curl":"curl https://claude.ai-platform.space/v1/status?key=YOUR_API_KEY"}},{"method":"GET","path":"/health","description":"Health check. Returns 200 OK if the proxy is up. No authentication required.","request_body":null,"response":{"status":"ok","service":"claude-api-sdk-proxy","version":"4.7.0","mode":"direct-api","pool":{"pool_size":0,"ready_count":0,"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\""}},{"method":"GET","path":"/v1/usage","description":"Per-client usage statistics with flexible grouping. Returns aggregated tokens/cost/requests for the authenticated user.","request_body":{"from":{"type":"string (query)","required":false,"description":"Start date YYYY-MM-DD. Default: 7 days ago."},"to":{"type":"string (query)","required":false,"description":"End date YYYY-MM-DD. Default: today."},"group_by":{"type":"string (query)","required":false,"default":"date,model","description":"Comma-separated dimensions: 'date', 'model', 'prompt_type'. E.g. group_by=date,model returns per-day per-model breakdown. Allowed values: date, model, prompt_type."}},"response":{"period":{"from":"2026-04-17","to":"2026-05-17"},"total_requests":1247,"total_input_tokens":482553,"total_output_tokens":95210,"total_cache_read_tokens":312000,"total_cache_creation_tokens":18420,"total_cost_usd":4.82,"by_date":[{"date":"2026-05-17","requests":42,"cost_usd":0.18}],"by_model":[{"model":"sonnet","requests":900,"cost_usd":3.6}],"by_prompt_type":[{"prompt_type":"agent_chat","requests":500,"cost_usd":2.1}]},"examples":{"curl_today":"curl \"https://claude.ai-platform.space/v1/usage?from=2026-05-17&to=2026-05-17&group_by=model\" \\\n  -H \"Authorization: Bearer YOUR_API_KEY\"","curl_7d_by_prompt_type":"curl \"https://claude.ai-platform.space/v1/usage?from=2026-05-10&to=2026-05-17&group_by=date,prompt_type\" \\\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 the first top-up. 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,"credit_limit":10.0,"tier_name":"active","bonus_claimed":true,"email_verified":true}}},{"method":"POST","path":"/auth/forgot-password","description":"Request password reset email. Always returns success to prevent email enumeration. Rate limit applies.","request_body":{"email":{"type":"string","required":true}},"response":{"success":true,"message":"If the email exists, a reset link was sent"}},{"method":"POST","path":"/auth/reset-password","description":"Apply password reset using token from email.","request_body":{"token":{"type":"string","required":true,"description":"Reset token from email link"},"new_password":{"type":"string","required":true,"description":"Min 8 characters"}},"response":{"success":true}},{"method":"POST","path":"/auth/resend-verify","description":"Resend email verification message. Rate limited.","request_body":null,"response":{"success":true}},{"method":"GET","path":"/auth/verify-email","description":"Apply email verification token (link from email). Query: ?token=...","request_body":null,"response":{"success":true,"message":"Email verified"}},{"method":"GET","path":"/auth/unsubscribe","description":"Unsubscribe from notification emails via signed link. Query: ?token=...","request_body":null,"response":{"success":true,"category":"marketing"}}]},"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/payments","description":"Payment history (separate from balance transactions). Params: limit, offset, status."},{"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, credit tier info."},{"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-5","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"}},{"method":"POST","path":"/billing/card/verify","description":"Initiate card binding for recurring charges (WayForPay 3DS flow). Body: {amount?:1.0}. Returns redirect URL."},{"method":"GET","path":"/billing/cards","description":"List saved cards. Returns masked PAN + default flag + expiry."},{"method":"POST","path":"/billing/cards/{id}/default","description":"Set card as default for charges/autotopup."},{"method":"DELETE","path":"/billing/cards/{id}","description":"Remove saved card from WayForPay vault."},{"method":"POST","path":"/billing/charge","description":"Charge saved default card. Body: {amount}. Used by autotopup cron and manual top-up via stored card."},{"method":"POST","path":"/billing/autotopup","description":"Enable/disable auto top-up. Body: {enabled, threshold_usd, amount_usd}. When balance < threshold, default card is charged."},{"method":"GET","path":"/billing/wfp-balance","description":"WayForPay merchant balance (admin view via user endpoint)."},{"method":"GET","path":"/billing/wfp-transactions","description":"WayForPay transaction log filtered by user. Params: limit, offset."},{"method":"GET","path":"/billing/subscription-recommendations","description":"Suggested subscription plans based on user's last 30d spend."},{"method":"GET","path":"/billing/subscriptions","description":"List user's active subscriptions."},{"method":"POST","path":"/billing/subscribe","description":"Create new subscription. Body: {plan_id, payment_method?}. Uses default card."},{"method":"GET","path":"/billing/subscriptions/{id}","description":"Subscription details + upcoming payment date."},{"method":"POST","path":"/billing/subscriptions/{id}/pause","description":"Pause subscription. Resume preserves remaining days."},{"method":"POST","path":"/billing/subscriptions/{id}/resume","description":"Resume paused subscription."},{"method":"POST","path":"/billing/subscriptions/{id}/cancel","description":"Cancel subscription. Active until end of paid period."},{"method":"POST","path":"/billing/subscriptions/{id}/change","description":"Change subscription amount/plan (WFP CHANGE flow). Body: {new_amount}."},{"method":"POST","path":"/billing/subscriptions/{id}/sync","description":"Force sync subscription state with WayForPay (use after webhook lag)."}]},"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, rate limits, and blocked_reason/last_error_text for blocked accounts."},{"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; updates rate limit headers and returns blocked_reason/last_error_text/checked_at. Takes ~1s per account."},{"method":"POST","path":"/admin/accounts/set-active/{id}","description":"Set active account in THIS process pool only. Note: admin runs in claude-web (8093) while traffic is served by claude-api-sdk (8092), so this does not redirect live requests."},{"method":"POST","path":"/admin/billing/refund/{payment_id}","description":"Refund a payment via WayForPay/Lava. Body: {amount?, reason?}."},{"method":"GET","path":"/admin/billing/payments","description":"Admin payments list with filters. Params: status, user_id, date_from, date_to, limit, offset."},{"method":"GET","path":"/admin/billing/statements","description":"Financial statements by month. Params: year, month."},{"method":"GET","path":"/admin/billing/statements/csv","description":"Export statements as CSV."},{"method":"GET","path":"/admin/email/templates","description":"List email templates."},{"method":"PUT","path":"/admin/email/templates/{id}","description":"Update email template body/subject."},{"method":"GET","path":"/admin/email/log","description":"Email send log with status (sent/bounced/failed)."},{"method":"POST","path":"/admin/email/send","description":"Send transactional email. Body: {user_id, template_id, vars}."},{"method":"POST","path":"/admin/email/broadcast","description":"Broadcast to user segment. Body: {segment, template_id, vars}."},{"method":"GET","path":"/admin/email/stats","description":"Email delivery stats: sent, bounced, open rate."},{"method":"GET","path":"/admin/cache-report","description":"Prompt cache statistics dashboard. Params: period (24h|7d|30d|since-fix), since=YYYY-MM-DD. Reflects auto-cache effectiveness per user/model."},{"method":"GET","path":"/admin/usage-today","description":"Real-time usage stats for today (all users, by model)."},{"method":"GET","path":"/admin/subscriptions","description":"Admin subscriptions list. Params: status, user_id."},{"method":"POST","path":"/admin/subscriptions/{id}/sync","description":"Force WFP sync for a subscription."},{"method":"POST","path":"/admin/subscriptions/{id}/cancel","description":"Admin cancel subscription."},{"method":"POST","path":"/admin/subscriptions/{id}/change","description":"Admin change subscription amount."},{"method":"GET","path":"/admin/subscriptions/{id}/payments","description":"Subscription payments history."},{"method":"POST","path":"/admin/oauth/init","description":"OAuth provisioning: initiate flow (returns Anthropic OAuth URL + state)."},{"method":"POST","path":"/admin/oauth/exchange","description":"OAuth provisioning: exchange code for tokens (callback handler)."},{"method":"POST","path":"/admin/oauth/provision","description":"OAuth provisioning: finalize, add account to pool."},{"method":"GET","path":"/admin/oauth/status","description":"OAuth provisioning current state (in-progress flows)."},{"method":"POST","path":"/admin/oauth/cancel","description":"Cancel current OAuth provisioning flow."},{"method":"POST","path":"/admin/oauth/resume","description":"Resume interrupted provisioning."},{"method":"POST","path":"/admin/oauth/invites/create","description":"Create OAuth invite token (self-service onboarding for OAuth account owner). Body: {note, expires_in_hours}."},{"method":"GET","path":"/admin/oauth/invites","description":"List active invites."},{"method":"POST","path":"/admin/oauth/invites/revoke","description":"Revoke an invite. Body: {token}."},{"method":"POST","path":"/public/oauth/init","description":"PUBLIC invite-token endpoint. Initiate OAuth flow for invited user (no admin auth, only invite token)."},{"method":"POST","path":"/public/oauth/exchange","description":"PUBLIC: exchange code (callback for invitee)."},{"method":"POST","path":"/public/oauth/provision","description":"PUBLIC: finalize OAuth provisioning via invite."},{"method":"GET","path":"/public/oauth/status","description":"PUBLIC: invite flow state."}],"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"}]},"proxy_behaviour":{"meta_sanitizer":{"what":"🔴 На моделях muse-* прокси МОЛЧА снимает поля, которые Meta отвергает с 400. Вы не получите ошибку, но и эффекта от этих полей не будет.","removed":"stop_sequences, top_k, thinking с типом disabled, бета-заголовки Anthropic и опознавательный префикс Claude Code. cache_control НЕ снимается с 21.09.2026: ephemeral/5m пропускаются (Meta принимает и обещает больше попаданий), ttl 1h понижается до 5m (часового Meta не держит, был бы 400).","effort":"Уровень усилия приводится к шкале Meta: low / medium / high / xhigh, плюс max ТОЛЬКО на muse-spark-1.3 (тариф standard, замер 19.09.2026: 200; на contributor max дает 400, поэтому там прокси понижает его до xhigh). none и minimal поднимаются до low, потому что Meta размышляет всегда. Замер через прокси 18.09.2026 на одной задаче: выход рос 528 / 877 / 938 / 1481 токена на low / medium / high / xhigh, то есть уровень реально влияет.","max_tokens_floor":"max_tokens поднимается минимум до 16000 (с 19.09.2026, было 4096). Причина: размышление у Meta включено всегда и делит бюджет с ответом - на тесном лимите весь бюджет уходит в размышление, и приходит ПУСТОЙ ответ при полном счете выходных токенов. То есть вы заплатили бы за пустой пузырь.","model_name":"Имя модели подставляется жестко. Имена claude-* Meta не знает и отвечает 404."},"description":"Что прокси делает САМ, без участия клиента. Знать полезно: это меняет то, что вы получаете в ответе и за что платите.","auto_continue_truncated":{"what":"Ответ, упёршийся в max_tokens (stop_reason=max_tokens), прокси дозапрашивает и склеивает - клиент получает ЦЕЛЫЙ ответ, а не обрезок.","why":"Обрезанный ответ обычно бесполезен, но оплачен полностью. У одного клиента 1839 ответов подряд обрывались ровно на 4500 токенах - около $185 за 5 дней в мусор.","limits":"до 3 дозапросов (максимум 4x исходного max_tokens); только чистый текст без вызова инструментов; не срабатывает при max_tokens < 200 - короткий лимит считаем осознанным выбором клиента","visibility":"finish_reason меняется с length на stop. Отдельного заголовка нет.","scope":"только non-stream. В stream не применяется.","measured":"50 успешных склеек за 7 дней, ошибок 0"},"health_ping_filter":{"what":"Пустой пинг (промпт вида hi / ping / test, без system, max_tokens <= 64) прокси отвечает локально словом ok и НЕ ходит в Anthropic.","why":"Один клиент слал 11009 таких пингов в неделю = 8.1% всего трафика платформы, и каждый жёг квоту OAuth-подписки.","billing":"$0, в логах prompt_type=health_ping, account_id пустой","marker":"в ответе поле health_ping: true","important":"Отсечки по имени модели стоят ВЫШЕ этого фильтра (исправлено 20.08.2026): запрос к нераздаваемой модели получит честную ошибку, а не заглушку с чужим именем модели."},"unsupported_model_rejection":{"what":"Имя модели, которое прокси не обслуживает, отклоняется с 400 и объяснением - вместо тихой подмены на дефолтную.","cases":["text-embedding-3-* в /v1/chat/completions -> 400 с указанием использовать /v1/embeddings","claude-mythos-5 -> 400, модель ограниченной доступности (Project Glasswing), пул её не обслуживает","claude-fable-5 -> 400 с причиной: подписка не отдаёт модель (см. её карточку в models)"],"why":"resolve_model_alias схлопывает любое незнакомое имя в дефолтную модель. Без отсечки клиент просил одну модель, получал HTTP 200 и ответ ДРУГОЙ модели, не зная об этом.","note":"Проверяется ИСХОДНОЕ имя из запроса, до нормализации."},"effort_caps":{"what":"Потолок уровня размышления по модели, действует на ВСЕХ включая администратора.","current":"sonnet: не выше high (xhigh/max опускаются; low/medium проходят как есть). haiku: не выше medium. opus: потолок high (возвращен 11.09.2026 решением владельца, был снят 10.08.2026) - xhigh и max опускаются в high. Для НЕ-админов сверх этого действует общий ролевой потолок high на ЛЮБОЙ модели, включая muse-*: xhigh и max молча становятся high.","why":"Временная мера экономии квоты: два из трёх Claude-аккаунтов были выбраны на 100%, за сутки 283 отказа клиентам. Замер показал, что xhigh это 17% запросов, но 40% входных токенов и 37% денег.","status":"ВРЕМЕННО. Снимается при возврате ёмкости пула.","visibility":"Отдельной ошибки нет - запрос выполняется на сниженном уровне."},"cache_ttl_1h":{"what":"Только Claude: кеш промптов без указания срока прокси помечает часовым (ttl=1h). OpenAI GPT-5.6+ использует отдельный срок 30 минут.","why":"Anthropic 06.03.2026 сменил срок по умолчанию с часа на 5 минут. Замер за неделю: 98-100% всех записей кеша были короткими. Пауза программиста больше пяти минут - и весь контекст пишется заново по ставке 1.25x от входа; за час это до 12 перезаписей вместо одной по 2.0x.","safety":"Правятся либо ВСЕ блоки запроса, либо ни одного. Если клиент указал срок сам и он не часовой - прокси не трогает ничего. Смешение сроков в одном запросе невозможно по построению (Anthropic требует строгий порядок 1h раньше 5m и иначе отвечает 400)."}},"rate_limits":{"meta_note":{"what":"Лимиты Meta идут по тарифу и на команду, не на ключ (документация pricing-rate-limits): contributor 100 запросов/мин и 3 млн токенов/мин, standard 3000 запросов/мин и 4 млн токенов/мин. Прокси держит один общий потолок канала по меньшему тарифу и сам держит темп (80 в минуту, 20 одновременных) и ставит лишние запросы в очередь - это видно как рост длительности, а не как ошибка. При исчерпании прокси отдает 429 с заголовком Retry-After.","transient_503":"Когда Meta отвечает 503 (временная перегрузка на ее стороне), прокси делает один повтор через 3 сек на том же аккаунте. Если 503 повторился, вы получаете 429 с Retry-After: 20 и текстом про перегрузку; это НЕ исчерпание канала, повторяйте через 20 сек. Настоящее исчерпание приходит с другим текстом и Retry-After от окна подписки (до 900 сек). Различайте по значению Retry-After, а не по тексту.","no_silent_switch":"Запрос НЕ переливается молча в другую линейку Meta: обычная muse-spark-1.3 дороже contributor в 12 раз, и такая подмена означала бы рост цены без вашего ведома. Лучше честный 429.","access":"Обе модели muse-* закрыты по умолчанию и выдаются точечно через allowed_models. Каскадного понижения внутри Meta НЕТ: обычная линейка и contributor отличаются не ценой, а тем, обучается ли Meta на ваших данных, поэтому молча переводить между ними запрещено. Нет права - будет 403, а не тихая подмена."},"description":"Per-user configurable limits + автоматический failover между OAuth-аккаунтами при 429/401","fields":[{"name":"max_requests_per_day","default":0,"description":"Лимит запросов в сутки. 0 или отрицательное = БЕЗЛИМИТ (снят глобально 16.06.2026, сейчас 0 у 51 из 56 ключей). Токенный лимит max_tokens_per_day при этом продолжает действовать."},{"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."}],"pool_failover":{"description":"Transparent multi-account failover. Прокси держит пул из 4+ OAuth-аккаунтов (Claude Max subscriptions). При rate limit или auth failure на текущем аккаунте — автоматически переключается на следующий по приоритету и повторяет запрос. Клиент НЕ видит 429/401 если в пуле есть свободный аккаунт.","endpoints_covered":["/v1/chat/completions (stream + non-stream)","/v1/messages (stream + non-stream)"],"triggers":["429 Rate Limit от Anthropic (5h или 7d окно исчерпано на конкретном аккаунте)","401 Authentication Error (OAuth токен истёк — обычно auto-refresh ловит до этого)"],"max_retries":"5 попыток на запрос. Каждая retry идёт на ДРУГОЙ аккаунт (трекинг через _tried_accounts set, без повторов).","rotation_strategy":"try_next_account: sort by priority ASC + id, skip overloaded (≥95% utilization), берёт первый available. Sticky: после успешного switch следующий запрос идёт на тот же аккаунт пока не упрётся.","stream_behavior":"Для stream запросов: если 429/401 пришёл ДО первого SSE event'а — retry прозрачен (новый стрим из start). Если посередине стрима — retry невозможен (часть данных уже отдана клиенту), будет yield error event.","transparency":"Клиент видит увеличенный latency (~0.5-2s на retry) вместо ошибки. Если ВСЕ 4 аккаунта в 429 одновременно — клиент получает finальный 429 с unified_status / utilization_7d_pct в теле.","history":"Stream retry активирован 01.06.2026. До этого только non-stream имел retry — stream возвращал 429 мгновенно даже если 3 других аккаунта свободны.","monitoring":"GET /rate-limits показывает текущий active аккаунт + utilization. GET /admin/accounts — полная картина пула с per-account метриками."}},"vision":{"meta_note":{"what":"Картинки и PDF на вход работают на muse-*. Проверено через прокси 18.09.2026: три независимых цвета одноцветных PNG названы верно, при контрольном запросе БЕЗ картинки модель отвечает 'Неизвестно' (значит не угадывает); уникальная метка внутри собранного на месте PDF возвращена дословно.","send_as_base64":"🔴 Присылайте вложением base64. Скачивание картинок по ссылке прокси делает ТОЛЬКО на пути OpenAI; на пути Meta ссылка уходит провайдеру как есть.","size":"Картинка должна быть хотя бы в десятки пикселей: на 1x1 модель отвечает наугад (в замере называла цвет, которого не было)."},"description":"Vision (multimodal) — отправь картинку вместе с текстом и Claude её опишет/проанализирует. Прокси принимает ВСЕ известные форматы блоков от любых клиентов (OpenAI Chat, OpenAI Responses API, Anthropic native, LangChain, LibreChat, n8n) и нормализует в Anthropic native перед отправкой. Universal-конвертер на стороне прокси (без правок на стороне клиента).","supported_input_formats":{"description":"16+ принимаемых вариаций блоков картинок — все автоматически нормализуются","variants":[{"name":"OpenAI Chat Completions standard","example":{"type":"image_url","image_url":{"url":"data:image/png;base64,..."}}},{"name":"OpenAI Chat Completions с публичным URL","example":{"type":"image_url","image_url":{"url":"https://example.com/cat.jpg"}}},{"name":"OpenAI с detail (игнорится)","example":{"type":"image_url","image_url":{"url":"https://...","detail":"high"}}},{"name":"image_url как строка (legacy/сокращение)","example":{"type":"image_url","image_url":"data:image/jpeg;base64,..."}},{"name":"Плоский url на уровне блока","example":{"type":"image_url","url":"https://example.com/x.png"}},{"name":"OpenAI Responses API input_image","example":{"type":"input_image","image_url":{"url":"data:image/webp;base64,..."}}},{"name":"OpenAI Responses API + строка","example":{"type":"input_image","image_url":"data:image/png;base64,..."}},{"name":"OpenAI Responses API + плоский url","example":{"type":"input_image","url":"https://..."}},{"name":"Плоский Anthropic-like","example":{"type":"image","url":"https://..."}},{"name":"Микс: image + image_url","example":{"type":"image","image_url":"https://..."}},{"name":"Anthropic native base64 (canonical)","example":{"type":"image","source":{"type":"base64","media_type":"image/png","data":"..."}}},{"name":"Anthropic native URL (canonical)","example":{"type":"image","source":{"type":"url","url":"https://..."}}},{"name":"data URL без ;base64 (urlencoded)","example":{"type":"image_url","image_url":{"url":"data:image/svg+xml,%3Csvg/%3E"}}},{"name":"data URL с доп. параметрами (charset etc.)","example":{"type":"image_url","image_url":{"url":"data:image/png;charset=utf-8;base64,..."}}},{"name":"Голый base64 с media_type подсказкой","example":{"type":"image_url","image_url":{"url":"iVBORw0KGgo...","media_type":"image/png"}}},{"name":"Голый base64 без подсказки (детект magic bytes)","example":{"type":"image_url","image_url":"iVBORw0KGgo..."}},{"name":"image/jpg алиас → image/jpeg","example":{"type":"image_url","image_url":{"url":"data:image/jpg;base64,..."}}}]},"supported_text_formats":{"description":"Text-блоки тоже нормализуются: 'input_text' и 'output_text' (OpenAI Responses API) → 'text' (Anthropic).","variants":[{"type":"text","note":"Anthropic / OpenAI Chat Completions standard"},{"type":"input_text","note":"OpenAI Responses API → нормализуется в text"},{"type":"output_text","note":"OpenAI Responses API (assistant) → нормализуется в text"}]},"supported_media_types":{"description":"Anthropic Claude API нативно принимает 4 формата изображений: image/jpeg, image/png, image/gif, image/webp. Прокси расширяет список через автоконверсию на нашей стороне.","native":[{"media_type":"image/jpeg","aliases":["image/jpg","image/pjpeg"],"max_size":"5MB (base64) / 5MB (url)"},{"media_type":"image/png","aliases":["image/x-png"],"max_size":"5MB"},{"media_type":"image/gif","aliases":[],"max_size":"5MB"},{"media_type":"image/webp","aliases":[],"max_size":"5MB"}],"auto_converted_by_proxy":[{"media_type":"image/svg+xml","converts_to":"image/png","tool":"rsvg-convert (librsvg)","note":"SVG автоматически растеризуется в PNG на стороне прокси перед отправкой в Anthropic. Прозрачно для клиента."}],"not_supported":[{"media_type":"image/bmp","reason":"Anthropic не принимает; конверсия в PNG возможна, но пока не реализована"},{"media_type":"image/tiff","reason":"Anthropic не принимает; конверсия в PNG возможна, но пока не реализована"},{"media_type":"image/heic","reason":"Anthropic не принимает; iOS-only формат"}],"official_anthropic_docs":"https://docs.claude.com/en/docs/build-with-claude/vision"},"size_and_resolution_limits":{"max_file_size":"5 MB на изображение (base64 ИЛИ url) — лимит Anthropic API","max_dimension":"8000×8000 пикселей — для не-batch запросов; для batch 2000×2000","max_megapixels":"Recommended: 1.15 megapixels (1568×1568) для оптимального качества; больше — auto-resize","max_images_per_request":"100 изображений на запрос (per Anthropic Vision docs)","tokens_per_image":"Approx (width×height) / 750. Image 1000×1000 ≈ 1334 tokens. Учитывается в input_tokens биллинга."},"examples":{"curl_data_url":"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 '{\n    \"model\": \"haiku\",\n    \"mode\": \"direct\",\n    \"max_tokens\": 100,\n    \"messages\": [{\n      \"role\": \"user\",\n      \"content\": [\n        {\"type\": \"text\", \"text\": \"What do you see?\"},\n        {\"type\": \"image_url\", \"image_url\": {\"url\": \"data:image/png;base64,iVBORw0KGgo...\"}}\n      ]\n    }]\n  }'","curl_http_url":"curl -X POST https://claude.ai-platform.space/v1/chat/completions \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  -d '{\n    \"model\": \"sonnet\",\n    \"mode\": \"direct\",\n    \"messages\": [{\n      \"role\": \"user\",\n      \"content\": [\n        {\"type\": \"text\", \"text\": \"Describe in 5 words\"},\n        {\"type\": \"image_url\", \"image_url\": {\"url\": \"https://images.unsplash.com/photo-1574158622682-e40e69881006?w=400\"}}\n      ]\n    }]\n  }'","curl_svg_auto_convert":"curl -X POST https://claude.ai-platform.space/v1/chat/completions \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  -d '{\n    \"model\": \"haiku\",\n    \"mode\": \"direct\",\n    \"messages\": [{\n      \"role\": \"user\",\n      \"content\": [\n        {\"type\": \"text\", \"text\": \"What color?\"},\n        {\"type\": \"image_url\", \"image_url\": {\"url\": \"data:image/svg+xml;base64,PHN2Zy4uLg==\"}}\n      ]\n    }]\n  }'  # SVG автоконвертируется в PNG прокси","python_openai_sdk":"from openai import OpenAI\nimport base64\n\nclient = OpenAI(\n    api_key=\"YOUR_API_KEY\",\n    base_url=\"https://claude.ai-platform.space/v1\"\n)\n\nwith open('image.png', 'rb') as f:\n    img_b64 = base64.b64encode(f.read()).decode()\n\nresponse = client.chat.completions.create(\n    model=\"sonnet\",\n    extra_body={\"mode\": \"direct\"},\n    messages=[{\n        \"role\": \"user\",\n        \"content\": [\n            {\"type\": \"text\", \"text\": \"Describe this image\"},\n            {\"type\": \"image_url\", \"image_url\": {\"url\": f\"data:image/png;base64,{img_b64}\"}}\n        ]\n    }]\n)\nprint(response.choices[0].message.content)","langchain":"from langchain_openai import ChatOpenAI\nfrom langchain_core.messages import HumanMessage\n\nllm = ChatOpenAI(\n    base_url=\"https://claude.ai-platform.space/v1\",\n    api_key=\"YOUR_API_KEY\",\n    model=\"claude-sonnet-5\",\n    extra_body={\"mode\": \"direct\"},\n)\n\nmsg = HumanMessage(content=[\n    {\"type\": \"text\", \"text\": \"What is in this image?\"},\n    {\"type\": \"image_url\", \"image_url\": {\"url\": \"https://example.com/x.png\"}},\n])\nresponse = llm.invoke([msg])\nprint(response.content)"},"tips":["Используй mode=direct для vision — быстрее и дешевле чем SDK session.","5 MB лимит = размер base64-данных. Если файл больше — сначала уменьши/сожми.","HTTP URL вариант: Anthropic сам качает картинку (не наш прокси). Для приватных URL используй base64.","image/svg+xml автоматически растеризуется в PNG (rsvg-convert на VPS). Прозрачно для клиента.","Все 3 модели поддерживают vision: haiku ($0.0001/картинка), sonnet ($0.0003), opus ($0.0015) — типичные значения для 100×100 px.","Идемпотентность: если шлёшь Anthropic native формат — прокси его НЕ трогает (zero overhead).","Идентичный текст-блок: 'input_text' (OpenAI Responses API) автоматически конвертится в 'text' — клиенту не нужно знать про различия SDK."]},"orchestration_claude_plus_muse":{"description":"Как использовать связку «Claude Code архитектор, Muse исполнитель» через ОДИН наш ключ. Все три провайдера живут за одним адресом и одним ключом: имя модели решает, куда уйдет запрос. Значит агент может planning делать на opus, а массовую работу отдавать в muse, не меняя ни базовый адрес, ни ключ.","why_this_split":"Muse дешевле: muse-spark-1.3-contributor стоит $0.10/$0.20 за 1M против $5/$25 у opus, то есть в 50 раз дешевле по входу и в 125 по выходу. При этом контекст у Muse миллион токенов и вызов инструментов работает, поэтому он годится на роль исполнителя, которому дают уже разобранную задачу. 🔴 У contributor есть цена помимо денег: Meta обучается на промптах и ответах.","roles":{"architect":"opus или sonnet. Разбор задачи, план, ревью результата, решения о развилках. Дорого за токен, но токенов мало.","executor":"muse-spark-1.3 (без обучения) или muse-spark-1.3-contributor (с обучением, в 12 раз дешевле). Массовая механическая работа по готовому плану: обход файлов, генерация однотипного кода, извлечение данных.","reviewer":"отдельный запрос к sonnet или opus по результату исполнителя. Проверяющий НЕ должен быть той же моделью и тем же диалогом, что исполнитель - иначе он защищает собственную работу."},"effort":{"what":"max существует только на muse-spark-1.3 (standard): проходит как max. На muse-spark-1.3-contributor уровня max нет (400), прокси понижает его до xhigh, ошибки не будет. Исправлено 19.09.2026, раньше здесь стояло «max у Meta нет» - это проверялось только на contributor.","role_cap":"🔴 ЧИТАТЬ ДО ТОГО, КАК СТРОИТЬ ЦИКЛ: обычному ключу (роль user) потолок усилия high на ЛЮБОЙ модели, включая muse-*. Запрос с xhigh или max МОЛЧА опускается в high, ошибки не будет; в логе прокси это видно строкой 'effort cap: requested=xhigh -> high'. Выше high получает только админ. Ставьте high и не рассчитывайте на xhigh, пока вам не подняли потолок.","measured":"Замер через прокси 18.09.2026 АДМИНСКИМ ключом (ролевой потолок на него не действует): выходных токенов 528 / 877 / 938 / 1481 на low / medium / high / xhigh. Уровень влияет на глубину, но обычному ключу доступны только первые три.","how":"Передавайте output_config.effort (контракт Anthropic), либо reasoning_effort (контракт OpenAI), либо короткое effort. Читаются все три, приоритет в этом порядке."},"cache_strategy":{"what":"Кешом у Meta управлять нечем, он включается сам. Выигрывает тот, кто строит запрос правильно.","rule":"Держите ПОБАЙТНО неизменное начало запроса: сначала общий контекст задачи и справочники, потом переменная часть. Меняете что-то в начале - кеш сбрасывается весь.","measured":"На префиксе ~10800 токенов повтор давал вход 102 вместо 10825 при чтении кеша 10723. Экономия реальная, но попадание не гарантировано на каждом запросе.","anti_pattern":"Не кладите в начало запроса метку времени, счетчик шага или идентификатор задачи - это ломает кеш на каждом вызове."},"agent_loop":{"description":"Минимальный цикл агента на Muse. Проверено живым прогоном 18.09.2026: три шага, list_files -> read_file -> верный ответ.","example_python":"import json, os, time, urllib.error, urllib.request\n\nKEY = os.environ['CLAUDE_PROXY_KEY']  # ключ платформы, в код не зашивать\nBASE = 'https://claude.ai-platform.space/v1/messages'\nH = {'Content-Type': 'application/json', 'x-api-key': KEY, 'anthropic-version': '2023-06-01'}\n\nTOOLS = [{'name': 'read_file', 'description': 'Прочитать файл',\n          'input_schema': {'type': 'object', 'properties': {'name': {'type': 'string'}},\n                           'required': ['name']}}]\n\ndef my_tool(name, input_dict):\n    \"\"\"ВАША функция: исполняет инструмент и возвращает результат СТРОКОЙ.\n\n    ВНИМАНИЕ: это заглушка. Путь приходит ОТ МОДЕЛИ, и здесь он читается как есть -\n    в своей реализации ограничьте доступ рабочим каталогом, иначе модель сможет\n    попросить любой файл на машине.\n    \"\"\"\n    if name == 'read_file':\n        return open(input_dict['name'], encoding='utf-8').read()[:4000]\n    return f'неизвестный инструмент: {name}'\n\ndef run_agent(task, max_steps=8):\n    msgs = [{'role': 'user', 'content': task}]\n    for _ in range(max_steps):\n        body = {'model': 'muse-spark-1.3', 'max_tokens': 8000, 'messages': msgs,\n                'tools': TOOLS, 'output_config': {'effort': 'high'}}  # high = потолок обычного ключа\n        req = urllib.request.Request(BASE, data=json.dumps(body).encode(), headers=H)\n        try:\n            r = json.load(urllib.request.urlopen(req, timeout=300))\n        except urllib.error.HTTPError as e:\n            if e.code == 429:  # канал занят, паузу называет сам прокси\n                time.sleep(int(e.headers.get('Retry-After') or 30))\n                continue\n            raise\n        content = r.get('content') or []\n        calls = [b for b in content if b.get('type') == 'tool_use']\n        if not calls:\n            return ''.join(b.get('text', '') for b in content if b.get('type') == 'text')\n        msgs.append({'role': 'assistant', 'content': content})\n        msgs.append({'role': 'user', 'content': [\n            {'type': 'tool_result', 'tool_use_id': c['id'], 'content': str(my_tool(c['name'], c['input']))}\n            for c in calls]})\n    raise RuntimeError('лимит шагов исчерпан')\n\n\nif __name__ == '__main__':\n    print(run_agent('Прочитай файл config.json и скажи, сколько воркеров указано. Ответь числом.'))\n","notes":"Цикл ведет ВАША сторона: прокси не хранит состояние диалога и не выполняет инструменты за вас. Историю передавайте целиком каждый раз - на этом и работает кеш. my_tool в примере это заглушка: замените ее своей реализацией, она обязана возвращать результат СТРОКОЙ. Пример самодостаточен: копируется и запускается как есть (нужен ключ в переменной окружения CLAUDE_PROXY_KEY и файл config.json рядом). Заглушка my_tool читает путь, пришедший ОТ МОДЕЛИ, без ограничений - в своей реализации ограничьте каталог."},"cost_control":{"hold":"Перед запросом замораживается оценка: $0.15 на muse-spark-1.3 и $0.012 на contributor. Излишек возвращается сразу после ответа, по факту израсходованного.","billing":"Платите по фактически ответившей модели. Если сработала аварийная подмена, цена будет от той модели, которая реально ответила.","limits":"Дневные лимиты в деньгах и токенах считаются по всем провайдерам вместе. Кеш-чтение входит в токенный лимит с весом 0.1, а не полным объемом."},"pitfalls":["Таймаут первого байта в стриме: на muse-* первая дельта идет 7-22 секунды, не ставьте ожидание меньше 30 секунд.","Claude Code на muse-*: подключайте через ANTHROPIC_AUTH_TOKEN (Bearer), не ANTHROPIC_API_KEY - при живом логине claude.ai второй вариант шлет OAuth-токен и получает 401 (документация Meta coding-agents.md, проверено 20.09.2026). Стрим с tools на muse-* с 20.09.2026 отдает input_json_delta с полным JSON одной дельтой; до этого аргументы терялись (дефект прокси, исправлен).","Имена инструментов у Meta: ^[a-zA-Z0-9_.-]+$ и не больше одной точки, иначе 400. strict: true включает проверку схемы (additionalProperties: false, все свойства в required).","tool_choice у Meta работает только auto и none (живой ответ 19.09.2026: «only auto is supported... none, required, and named function choices are not currently supported»; документация Meta обещает any, но он тоже дает 400). Прокси приводит {type: tool, name} и {type: any} к auto: принуждение к вызову инструмента теряется, ответ приходит вместо 400. Если вам нужен гарантированный вызов инструмента, проверяйте stop_reason=tool_use сами и повторяйте. Для web_search параметры allowed_domains, blocked_domains и max_uses снимаются (400 у Meta). thinking {type: enabled, budget_tokens} приводится к adaptive: Meta бюджет не читает, глубину задает output_config.effort.","Длинный НЕ-стримовый запрос на muse-* может получить 504 от самой Meta (документированный таймаут не-стрима, совет Meta: используйте stream=true). Прокси такой запрос не повторяет: повтор уперся бы в тот же лимит. Ответы длиннее нескольких тысяч токенов запрашивайте стримом.","max_tokens меньше 16000 на muse-* поднимается прокси: при тесном лимите весь бюджет уходит в размышление и приходит пустой ответ.","stop_sequences и top_k на muse-* снимаются молча - не стройте на них логику остановки, останавливайте цикл на своей стороне.","Картинки и PDF на muse-* присылайте вложением base64: ссылки скачиваются только на пути OpenAI.","Проверяющий агент должен быть отдельным запросом к другой модели, иначе он подтверждает собственную работу."]},"prompt_caching":{"openai_note":{"ttl_seconds":1800,"models":"GPT-5.6 и GPT-6, включая GPT-6.1 Sol. На старые модели этот срок не распространяется.","what":"Минимум 30 минут после последней записи или повторного использования префикса. Попадание в кеш обновляет срок; хранение дольше возможно, но не гарантируется. Это не часовой кеш Claude.","transport":"Канал Codex использует срок провайдера по умолчанию. Anthropic cache_control.ttl=1h не задает срок OpenAI.","response":"usage.cache_ttl_seconds=1800 в итоговом ответе и финальном событии стрима /v1/messages и /v1/chat/completions. Поле описывает срок, а не подтверждает попадание: смотрите cache_read_input_tokens.","client_timer":"Точный срок передается как cache_ttl_seconds вместе с cache_provider и cache_ttl_kind. Локальная доработка таймера Claude Code читает эти поля и показывает окно OpenAI 30 минут. Клиенты без этой доработки продолжают читать только совместимые корзины 5m/1h.","source":"https://developers.openai.com/api/docs/guides/prompt-caching#cache-lifetime"},"meta_note":{"retention":"В текущем канале /v1/messages принимается запрос ttl=5m. Это не гарантированный момент удаления: чтение Muse наблюдалось после паузы более 13 минут. Поэтому usage.cache_provider=meta, cache_ttl_kind=unknown и cache_ttl_seconds=0: интерфейс показывает неизвестный срок и отдельно факт чтения, а не ложное истечение через 5 минут. Responses API Meta позволяет запросить хранение до 24 часов, но этот канал прокси его пока не использует.","what":"На моделях muse-* кеш префиксный и включается сам, но брейкпоинты РАБОТАЮТ: cache_control ephemeral/5m Meta принимает (схема Messages API: «to improve cache hit rates»). Прокси с 21.09.2026 пропускает их, а ttl 1h понижает до 5m (часовой Meta отвергает с 400). Слать можно и нужно.","measured":"Замер через прокси 18.09.2026, четыре одинаковых запроса на префиксе ~10800 токенов. muse-spark-1.3: вход 10825 / 102 при чтении кеша 10723 / 102 при 10723 / снова 10825. muse-spark-1.3-contributor: 10824 / 101 при 10723 / 101 / 101. Замер 21.09.2026 после даунгрейда (contributor, префикс ~8000): повтор с брейкпоинтами дал вход 135 при чтении 7921, тот же повтор БЕЗ брейкпоинтов - вход 7 при чтении 8049. Тот же опыт на префиксе ~1200: оба раза чтение 0 - у кеша есть минимальный размер префикса (между 1200 и 8000 токенов, точная граница не мерялась).","how_to_hit":"Попадание дает ПОБАЙТНО одинаковое начало запроса. Держите стабильный префикс (системная часть, справочники, контекст задачи) в начале и меняйте только хвост. Любая правка в начале сбрасывает кеш целиком. На практике попадания идут в режиме «все или ничего»: совпал префикс с начала - читается почти весь, разъехался в первых блоках (system, tools) - чтение ровно 0.","not_a_rule":"Попадание НЕ гарантировано на каждом повторе: в замере на обычной линейке четвертый запрос ушел мимо кеша при неизменном префиксе. Считайте кеш экономией, а не правилом - на нем нельзя строить расчет стоимости.","price":"Чтение кеша $0.15/MTok на muse-spark-1.3 и $0.002/MTok на contributor. Запись кеша Meta не тарифицирует вообще."},"description":"Anthropic prompt caching support — reuse a stable prefix (system prompt, tools, RAG context) at 10% of normal input cost. Available in mode=direct only.","how_to_use":"Add cache_control to the system message (or any text block in Anthropic-style content array). Two TTL options: '5m' (default, 1.25× write cost) and '1h' (extended cache, 2× write cost).","example":{"request":{"model":"haiku","mode":"direct","max_tokens":100,"messages":[{"role":"system","content":"...your large stable system prompt (>=4500 chars for sonnet, >=10000 for haiku, >=2200 for opus)...","cache_control":{"type":"ephemeral","ttl":"1h"}},{"role":"user","content":"Your dynamic question"}]},"response_first_call":{"usage":{"prompt_tokens":9,"completion_tokens":30,"cache_creation_input_tokens":6166,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":6166}},"cost_usd":0.009889},"response_repeat_call":{"usage":{"prompt_tokens":9,"completion_tokens":30,"cache_creation_input_tokens":0,"cache_read_input_tokens":6166,"cache_creation":{}},"cost_usd":0.000572,"note":"94% cheaper than first call thanks to cache hit"}},"ttl_options":[{"value":"5m","default_when":"ttl omitted","write_multiplier":"1.25× base input price","use_for":"bursty workloads, conversations within minutes"},{"value":"1h","default_when":"explicit","write_multiplier":"2× base input price","use_for":"long pauses (3-6h), patient flows, batch processing","beta_header":"extended-cache-ttl-2025-04-11 (auto-applied by proxy)"}],"minimum_size":[{"model":"sonnet","min_tokens":1024,"approx_chars":4500,"note":"Anthropic published threshold"},{"model":"haiku","min_tokens":512,"approx_chars":1200,"note":"Below this, Anthropic returns cache_creation=0 silently"},{"model":"opus","min_tokens":512,"approx_chars":2200,"note":"Opus 5 lowered the cache minimum to 512 tokens"}],"pricing":[{"model":"haiku","display":"Haiku 5.5","input_per_mtok":1.0,"cache_read_per_mtok":0.1,"cache_write_5m_per_mtok":1.25,"cache_write_1h_per_mtok":2.0,"output_per_mtok":5.0},{"model":"sonnet","display":"Sonnet 5","input_per_mtok":3.0,"cache_read_per_mtok":0.3,"cache_write_5m_per_mtok":3.75,"cache_write_1h_per_mtok":6.0,"output_per_mtok":15.0},{"model":"opus","display":"Opus 5","input_per_mtok":5.0,"cache_read_per_mtok":0.5,"cache_write_5m_per_mtok":6.25,"cache_write_1h_per_mtok":10.0,"output_per_mtok":25.0},{"model":"claude-opus-5-5","display":"Opus 5.5","input_per_mtok":4.0,"cache_read_per_mtok":0.2,"cache_write_5m_per_mtok":5.0,"cache_write_1h_per_mtok":8.0,"output_per_mtok":20.0},{"model":"claude-sonnet-5-5","display":"Sonnet 5.5","input_per_mtok":2.0,"cache_read_per_mtok":0.1,"cache_write_5m_per_mtok":2.5,"cache_write_1h_per_mtok":4.0,"output_per_mtok":10.0}],"auto_caching":"If you don't pass cache_control, the proxy auto-marks system_prompt as ephemeral with ttl='1h' (CHANGED 18.05.2026) when system_prompt char length exceeds the proxy threshold: sonnet ≥ 4500 chars, haiku ≥ 1200 chars, opus ≥ 2200 chars. Reason: Anthropic silently dropped default TTL from 1h to 5min on 06.03.2026 — explicit ttl='1h' restores prior behavior. Below threshold, the proxy does NOT add cache_control (Anthropic would silently return cache_creation=0).","proxy_thresholds":{"sonnet":"4500 chars (~1024 tokens — matches Anthropic published minimum)","haiku":"1200 chars (~512 tokens)","opus":"2200 chars (~512 tokens)","note":"These are PROXY thresholds (CACHE_MIN_CHARS in session_pool.py). Anthropic minimums differ per model: Opus 5 = 512 tokens, Sonnet 5 = 1024, Haiku 5.5 = 512. Char thresholds assume ~2.3 chars/token for Russian text."},"disable_auto_caching":{"description":"Three ways to disable proxy's automatic system_prompt cache_control:","methods":["1. Request body field: {'disable_auto_cache': true}","2. HTTP header: X-No-Auto-Cache: 1","3. Send your own cache_control on the system message — proxy then respects yours (does not double-add)"],"when_to_disable":"Testing exact cache behavior; intentionally avoiding cache writes; A/B benchmarking; prompts that change every request anyway."},"session_mode_note":"Legacy mode=session (CLI subprocess pool) is deprecated. All /v1/messages and /v1/chat/completions traffic now goes through direct Anthropic API. cache_control is fully honored.","tips":["Keep dynamic content (timestamps, user IDs) AFTER cache_control breakpoint — anything before invalidates the cache.","Watch usage.cache_creation.ephemeral_1h_input_tokens to confirm 1h cache is active.","Cache key is per OAuth account in our pool; warming up is fast since the pool clusters requests by user.","5min TTL resets every read — high-traffic prompts stay warm indefinitely.","Use disable_auto_cache=true if you want raw input billing (e.g. for cost comparison benchmarking)."]},"tools_and_function_calling":{"meta_note":{"what":"Вызов инструментов на muse-* работает, формат тот же. Проверено через прокси 18.09.2026 живой МНОГОШАГОВОЙ цепочкой: модель вызвала list_files с аргументом {'path': '/app'}, получила результат, затем сама вызвала read_file, получила результат и дала верный финальный ответ. Три шага, stop_reason шел tool_use -> tool_use -> end_turn.","how":"Инструменты передаются как обычно (принимается и формат OpenAI, и формат Anthropic). Результат возвращается блоком tool_result с тем же tool_use_id, как у Claude - отдельного диалекта у Meta нет.","orchestration":"Этого достаточно, чтобы Muse работал исполнителем внутри агентного цикла: цикл ведет ваша сторона, Muse отвечает, какой инструмент вызвать и с какими аргументами.","web_search":"Веб-поиск у Meta РАБОТАЕТ через наш прокси, проверено 18.09.2026. Передайте инструмент {'type': 'web_search'} - он доходит до Meta как есть (отсечка серверных инструментов OpenAI стоит только на пути Claude). Доказательство не по словам модели, а по счетчику: на короткий вопрос вход составил 7427 токенов вместо нескольких десятков, то есть результаты поиска реально подставлены в контекст; модель назвала курс валюты с точным временем котировки и домен источника. Контрольный запрос БЕЗ инструмента на тот же вопрос отвечает, что доступа к поиску в реальном времени нет. ВНИМАНИЕ: отдельных блоков server_tool_use в ответе нет, поле usage.server_tool_use приходит пустым - факт поиска виден только по росту входных токенов.","caveat":"Форму Anthropic {'type': 'web_search_20260209'} Meta НЕ принимает: 400 'tool type web_search_20260209 is not supported'. Используйте форму OpenAI."},"description":"Function calling / tool use. The proxy accepts BOTH OpenAI tools format and Anthropic native tools format on /v1/chat/completions and /v1/messages. Auto-converts as needed. Since 01.06.2026 all non-stream /v1/messages requests use the same direct Anthropic API path as streaming and tools — no SDK pool roundtrip.","openai_format":{"description":"Standard OpenAI tools array used by langchain.tools, OpenAI SDK, LiteLLM, Pydantic-AI.","example":{"tools":[{"type":"function","function":{"name":"get_weather","description":"Get current weather for a city","parameters":{"type":"object","properties":{"city":{"type":"string"}},"required":["city"]}}}],"tool_choice":"auto"}},"anthropic_format":{"description":"Anthropic native tools — used by anthropic Python SDK.","example":{"tools":[{"name":"get_weather","description":"Get current weather for a city","input_schema":{"type":"object","properties":{"city":{"type":"string"}},"required":["city"]}}]}},"tool_choice_values":{"auto":"Default — model decides whether to call tools or respond directly","none":"Force model to respond without using any tool","required / any":"Force model to call at least one tool (any of them)","{type:'function', function:{name:'X'}}":"OpenAI: force specific tool — converted to Anthropic {type:'tool', name:'X'}","{type:'tool', name:'X'}":"Anthropic native: same as above"},"server_tools":{"description":"Native Anthropic server-side tools — passed through without conversion. Useful for agents that need built-in capabilities.","supported":["web_search_*","bash_*","code_execution_*","text_editor_*"],"note":"These run on Anthropic's infrastructure, not on our proxy. Subject to Anthropic Tool Use beta headers."},"structured_output":{"description":"Two response_format shapes for forcing JSON output:","json_object":{"request":{"response_format":{"type":"json_object"}},"behavior":"Proxy appends 'Respond ONLY with valid JSON' to system + strips ```json...``` markdown wrappers from response. No schema validation."},"json_schema":{"request":{"response_format":{"type":"json_schema","json_schema":{"name":"user_profile","description":"User profile data","schema":{"type":"object","properties":{"name":{"type":"string"},"age":{"type":"integer"}},"required":["name","age"]}}}},"behavior":"Proxy creates a synthetic forced tool_use (Anthropic tool_choice={type:'tool', name:'user_profile'}). Tool_use.input is then returned as JSON string in choices[0].message.content. Used by LangChain with_structured_output, Pydantic-AI, Graphiti, Instructor."}},"tool_history_in_messages":{"description":"Multi-turn tool use — include prior assistant tool_calls and role=tool results in messages array.","openai_shape":[{"role":"user","content":"Weather in Kyiv?"},{"role":"assistant","content":null,"tool_calls":[{"id":"call_1","type":"function","function":{"name":"get_weather","arguments":"{\"city\":\"Kyiv\"}"}}]},{"role":"tool","tool_call_id":"call_1","content":"{\"temp\":18}"},{"role":"user","content":"Convert to F"}],"anthropic_shape":[{"role":"user","content":"Weather in Kyiv?"},{"role":"assistant","content":[{"type":"tool_use","id":"toolu_1","name":"get_weather","input":{"city":"Kyiv"}}]},{"role":"user","content":[{"type":"tool_result","tool_use_id":"toolu_1","content":"{\"temp\":18}"}]}],"note":"Both shapes accepted. Proxy converts OpenAI → Anthropic via convert_openai_messages_to_anthropic()."},"tool_calls_streaming":{"description":"stream=true with tools: tool_calls arrive incrementally.","openai_events":["data: {... delta: {tool_calls: [{index:0, id:'call_1', function:{name:'get_weather'}}]}}","data: {... delta: {tool_calls: [{index:0, function:{arguments:'{\"city\":'}}]}}","data: {... delta: {tool_calls: [{index:0, function:{arguments:'\"Kyiv\"}'}}]}}","data: {... finish_reason: 'tool_calls'}","data: [DONE]"],"note":"OpenAI index ↔ Anthropic content block index mapping preserved. Multiple parallel tool calls supported."},"example_curl_basic_tools":"curl -X POST https://claude.ai-platform.space/v1/chat/completions \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" -H \"Content-Type: application/json\" \\\n  -d '{\n    \"model\":\"sonnet\",\n    \"messages\":[{\"role\":\"user\",\"content\":\"What is the weather in Kyiv?\"}],\n    \"tools\":[{\n      \"type\":\"function\",\n      \"function\":{\n        \"name\":\"get_weather\",\n        \"description\":\"Get weather for a city\",\n        \"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"]}\n      }\n    }],\n    \"tool_choice\":\"auto\"\n  }' ","example_langchain_structured":"from langchain_openai import ChatOpenAI\nfrom pydantic import BaseModel\n\nclass User(BaseModel):\n    name: str\n    age: int\n\nllm = ChatOpenAI(\n    base_url=\"https://claude.ai-platform.space/v1\",\n    api_key=\"YOUR_API_KEY\",\n    model=\"claude-sonnet-5\",\n)\nstructured = llm.with_structured_output(User)\nresult = structured.invoke(\"John Doe is 32 years old\")\nprint(result)  # User(name='John Doe', age=32)","tips":["Tools always use direct Anthropic API path (SDK pool is deprecated for /v1/messages and /v1/chat/completions).","Empty arguments string ('{}') is valid for OpenAI — proxy converts to empty Anthropic input{}.","Streaming tool_calls: aggregate by index, not by id (id is sent once at start).","If you need both tools AND extended thinking — use Sonnet/Haiku with thinking={type:'enabled', budget_tokens:N}. Opus 4.7/4.8 adaptive thinking + tools works too.","response_format=json_schema is the most reliable way to get structured JSON — no markdown wrapper to strip."]},"server_side_tools":{"description":"Anthropic-executed tools: model decides when to call, Anthropic runs them server-side, returns results. NO client implementation needed — unlike classic function calling. Supported via Bearer OAuth subscription (Claude Max). Added 01.06.2026.","available_tools":{"web_search":{"tool_type":"web_search_20260209 (recommended, with dynamic filtering) OR web_search_20250305 (legacy, no filtering)","description":"Model searches the web during generation and returns answers with citations.","client_side_implementation":"NONE — pass tools=[{type: 'web_search_20260209', name: 'web_search', max_uses?: 5, allowed_domains?, blocked_domains?, user_location?}].","price":"$10 / 1000 searches + standard tokens for retrieved content. Failed searches NOT billed.","models_supported":["claude-opus-5-5","claude-sonnet-5-5","claude-haiku-5-5"],"response_blocks":["server_tool_use (model's search query)","web_search_tool_result (results array)","text (with citations)"],"multi_turn":"Re-send encrypted_content/encrypted_index back in subsequent messages for citations to keep working."},"web_fetch":{"tool_type":"web_fetch_20260209 (recommended) OR web_fetch_20250910 (legacy)","description":"Model fetches full content from a specific URL (HTML, PDF). For PDFs auto-extract base64.","client_side_implementation":"NONE — pass tools=[{type: 'web_fetch_20260209', name: 'web_fetch', max_uses?: 5, allowed_domains?, blocked_domains?, citations?: {enabled: true}, max_content_tokens?: 100000}].","price":"FREE (no extra charges, only token cost of fetched content).","models_supported":["claude-opus-5-5","claude-sonnet-5-5","claude-haiku-5-5"],"url_validation":"Can ONLY fetch URLs that already appeared in conversation context (user messages, prior tool results). No arbitrary URLs."},"code_execution":{"tool_type":"code_execution_20250825 (Bash + file ops) OR code_execution_20260120 (latest, REPL state, Opus 4.5+/Sonnet 4.5+ only)","description":"Model writes Python/Bash code and executes in Anthropic sandbox container (200MB RAM, files, matplotlib graphs).","client_side_implementation":"NONE — pass tools=[{type: 'code_execution_20250825', name: 'code_execution'}]. Requires anthropic-beta: code-execution-2025-08-25 (already in proxy default headers since 01.06.2026).","price":"FREE when used together with web_search/web_fetch. Otherwise $0.05/h per container (min 5 minutes), 1550 free hours/month per org.","models_supported":["claude-opus-5-5","claude-sonnet-5-5","claude-haiku-5-5"],"response_block_types":["server_tool_use (action: bash_code_execution or text_editor_code_execution)","bash_code_execution_tool_result (with stdout, stderr, return_code)","text_editor_code_execution_tool_result (file ops)"],"rate_limits_note":"OAuth subscription may hit too_many_requests on code_execution faster than API-key tier. Proxy returns the error in result.content.error_code."}},"response_format_openai":{"description":"/v1/chat/completions returns server tools via extension fields (OpenAI standard doesn't define them):","fields":{"server_tool_uses":"list of {id, name, input, result: {type, content, is_error?, error_code?}}","citations":"list of {type: 'web_search_result_location'|'char_location', url?, title?, cited_text?, encrypted_index?, ...}","usage.server_tool_use":"{web_search_requests: N, web_fetch_requests: N, code_execution_requests: N}","cost_usd":"includes $0.01 × web_search_requests (web_fetch/code_exec free or token-only)"}},"response_format_anthropic":{"description":"/v1/messages returns full Anthropic native blocks in content[]:","blocks":["text (with optional citations array)","server_tool_use","web_search_tool_result","web_fetch_tool_result","bash_code_execution_tool_result","text_editor_code_execution_tool_result"]},"streaming_sse_events":{"description":"Streaming SSE flow for /v1/chat/completions when server tools fire:","sequence":["data: {delta: {role: 'assistant', content: ''}} — init","data: {delta: {server_tool_use: {index, id, name, status: 'start'}}} — tool block started","data: {delta: {server_tool_use: {index, status: 'stop', input: {query}}}} — full input ready","data: {delta: {server_tool_result: {tool_use_id, type: 'web_search_tool_result', content: [...]}}} — results back","data: {delta: {citation: {url, title, cited_text, ...}}} — model cites a source","data: {delta: {content: 'text chunk'}} — actual model response","data: {delta: {}, finish_reason: 'stop'} — end","data: [DONE]"]},"curl_examples":{"web_search_haiku":"curl https://claude.ai-platform.space/v1/chat/completions \\\n  -H 'Authorization: Bearer YOUR_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"model\": \"claude-haiku-5-5\",\n    \"mode\": \"direct\",\n    \"max_tokens\": 512,\n    \"messages\": [{\"role\":\"user\",\"content\":\"What time is it in Tokyo?\"}],\n    \"tools\": [{\"type\": \"web_search_20250305\", \"name\": \"web_search\", \"max_uses\": 1}]\n  }'","web_fetch_sonnet":"curl https://claude.ai-platform.space/v1/messages \\\n  -H 'x-api-key: YOUR_KEY' \\\n  -H 'anthropic-version: 2023-06-01' \\\n  -d '{\n    \"model\": \"claude-sonnet-5\",\n    \"max_tokens\": 256,\n    \"messages\": [{\"role\":\"user\",\"content\":\"Fetch https://example.com and summarize\"}],\n    \"tools\": [{\"type\": \"web_fetch_20250910\", \"name\": \"web_fetch\", \"max_uses\": 1}]\n  }'"},"billing_logic":"Per-request: input_tokens × model_input_price + output_tokens × model_output_price + $0.01 × web_search_requests. web_fetch and code_execution don't add direct charges (already covered by tokens).","notes":["OAuth subscription verified working with web_search/web_fetch/code_execution (tested 01.06.2026).","Server tools can be combined with custom function calling — both work in same request.","Multi-turn: re-send encrypted_content and encrypted_index from prior responses to keep citations valid.","Errors come back in *_tool_result.content.error_code (too_many_requests, max_uses_exceeded, etc.) — HTTP status stays 200."]},"streaming":{"meta_note":{"what":"Стрим на muse-* настоящий, события стандартные: message_start, content_block_start, content_block_delta, content_block_stop, message_delta, message_stop.","long_first_byte":"🔴 ГЛАВНОЕ ОТЛИЧИЕ: первая дельта приходит через 7-22 секунды, дальше текст идет нормальным потоком. Замер tests/meta/probe_stream.py на VPS 18.09.2026: длинный ответ на /v1/messages - 954 дельты на 10279 символов, первая на 16.33 сек, всего 53.33 сек, средняя пауза между дельтами 0.039 сек; короткий ответ - 3 дельты, первая на 7.67 сек из 7.80 сек полного времени (то есть на коротких ответах почти все время это ожидание, и они выглядят как одна пачка); /v1/chat/completions - 822 дельты, первая на 22.21 сек.","keepalive":"Формат служебного события РАЗНЫЙ на двух путях, проверено замером 18.09.2026: на /v1/messages приходит event: ping с телом {'type':'ping'} (в прогоне 2 события за 20 секунд ожидания), на /v1/chat/completions - строка-комментарий ': keepalive' (1 событие). Интервал 15 секунд. Готовые SSE-библиотеки обрабатывают оба формата сами; если разбираете поток руками - игнорируйте события ping И строки, начинающиеся с двоеточия.","advice":"Не ставьте клиентский таймаут ожидания первого байта меньше 30 секунд на моделях muse-*: в замере худший случай дал 22.21 секунды на /v1/chat/completions, поэтому порог 20 секунд оборвал бы ровно этот путь."},"description":"Real-time SSE streaming for both /v1/chat/completions (OpenAI format) and /v1/messages (Anthropic format). Since 06.05.2026 all streaming requests go through native Anthropic SDK (client.messages.stream). Since 01.06.2026 non-streaming /v1/messages also goes through direct Anthropic API — the legacy SDK pool path is fully retired.","openai_format":{"description":"Standard OpenAI Chat Completions SSE — text deltas.","event_sequence":["data: {chatcmpl-..., delta: {role:'assistant', content:''}}  # first chunk = role marker","data: {chatcmpl-..., delta: {content:'Hello'}}","data: {chatcmpl-..., delta: {content:' world'}}","data: {chatcmpl-..., delta: {}, finish_reason: 'stop'}","data: [DONE]"],"tool_calls_in_stream":"When tools fire, deltas include {tool_calls:[{index:0, id?, function:{name?, arguments:'partial json'}}]}. Accumulate arguments by index.","example_curl":"curl -N -X POST https://claude.ai-platform.space/v1/chat/completions \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  -d '{\"model\":\"sonnet\",\"stream\":true,\"messages\":[{\"role\":\"user\",\"content\":\"Count to 5\"}]}'"},"anthropic_format":{"description":"Native Anthropic SSE for /v1/messages.","event_sequence":["event: message_start  →  {message: {id, role, content:[], model, ...}}","event: content_block_start  →  {index:0, content_block: {type:'text', text:''}}","event: content_block_delta  →  {index:0, delta: {type:'text_delta', text:'Hello'}}","event: content_block_delta  →  {index:0, delta: {type:'text_delta', text:' world'}}","event: content_block_stop  →  {index:0}","event: message_delta  →  {delta: {stop_reason:'end_turn'}, usage:{output_tokens:42}}","event: message_stop","event: ping  →  (keepalive every 15s while generating)"],"tool_use_blocks":"Tool calls stream as content_block_start (type:'tool_use', id, name), then content_block_delta (type:'input_json_delta', partial_json:'...'), then content_block_stop.","example_python_sdk":"from anthropic import Anthropic\nclient = Anthropic(api_key=\"YOUR_API_KEY\", base_url=\"https://claude.ai-platform.space\")\nwith client.messages.stream(model=\"sonnet\", max_tokens=512,\n    messages=[{\"role\":\"user\",\"content\":\"Tell a story\"}]) as s:\n    for txt in s.text_stream:\n        print(txt, end=\"\", flush=True)"},"implementation_notes":["ALL streaming requests → native Anthropic SDK path (session_pool.direct_api_stream). Non-stream /v1/messages → session_pool.direct_api_call. SDK pool path is retired (01.06.2026).","Keepalive ping every 15 seconds for /v1/messages prevents nginx 504 on long thinking.","Cache tokens and cost are computed AFTER stream ends from final usage. Reflected in /v1/usage and request_logs.","If first yield in stream generator throws (e.g. auth check passes but Anthropic rejects) — proxy emits a single SSE error event + [DONE] (see STREAM_PRE_YIELD_FAIL in server_500.log)."]},"headers":{"description":"HTTP request/response headers supported by the proxy.","request_headers":[{"name":"Authorization","value":"Bearer sk-cc-...","required":"one of three auth methods","description":"Standard OpenAI auth. Works on ALL endpoints."},{"name":"x-api-key","value":"sk-cc-...","required":"one of three auth methods","description":"Anthropic SDK auth. Works on ALL endpoints."},{"name":"?key= (query)","value":"sk-cc-...","required":"one of three auth methods","description":"Query param fallback. Works on /v1/chat/completions, /v1/status, /v1/models. NOT supported on /v1/messages — use header."},{"name":"Content-Type","value":"application/json","required":"for POST","description":"Standard."},{"name":"anthropic-version","value":"2023-06-01","required":"for /v1/messages (some SDKs)","description":"Native Anthropic header. Most SDKs send automatically."},{"name":"X-Request-ID","value":"any string","required":false,"description":"If sent, proxy uses your id for correlation logs + reflects it in response header. Otherwise auto-generated (req-<12hex>). Added 16.05.2026."},{"name":"X-No-Auto-Cache","value":"1","required":false,"description":"Disable proxy's automatic system_prompt cache_control. Equivalent to body field disable_auto_cache:true."},{"name":"X-Prompt-Type","value":"any string label","required":false,"description":"Analytics label for this request. Appears in /v1/usage?group_by=prompt_type. Examples: 'agent_chat', 'summarize', 'code_review'."}],"response_headers":[{"name":"X-Request-ID","description":"Always returned (echoed or generated). Use this to correlate with logs/server_500.log and nginx 5xx.log when reporting issues."},{"name":"Content-Type","description":"application/json (non-stream), text/event-stream (stream=true), text/plain (some health responses)."},{"name":"Access-Control-Allow-Origin","description":"CORS — claude.ai-platform.space + localhost:8092 only."}],"debugging_tip":"When reporting a 500 error to support, include the X-Request-ID from response headers. Engineers can grep server_500.log for the full traceback in seconds."},"client_integrations":{"description":"Drop-in replacement instructions for popular Claude clients. All clients work by pointing them at https://claude.ai-platform.space instead of api.anthropic.com, using your sk-cc-... API key.","claude_code_cli":{"name":"Claude Code CLI (Anthropic official `claude` command)","tested_version":"2.1.154","status":"Fully working: text, tool use (Read/Write/Edit/Bash), streaming, extended thinking, multi-turn","setup_macos_linux":{"description":"Export TWO env vars before running `claude`. Both are required — Claude Code 2.1.x falls back to OAuth flow if only ANTHROPIC_API_KEY is set.","commands":["export ANTHROPIC_BASE_URL=https://claude.ai-platform.space","export ANTHROPIC_API_KEY=sk-cc-YOUR_KEY","export ANTHROPIC_AUTH_TOKEN=sk-cc-YOUR_KEY","claude --print 'Hello, world'"],"persist_in_shell":"Add the 3 export lines to ~/.zshrc or ~/.bashrc to persist across sessions."},"setup_windows_powershell":{"commands":["$env:ANTHROPIC_BASE_URL = 'https://claude.ai-platform.space'","$env:ANTHROPIC_API_KEY = 'sk-cc-YOUR_KEY'","$env:ANTHROPIC_AUTH_TOKEN = 'sk-cc-YOUR_KEY'","claude --print 'Hello, world'"]},"common_issues":[{"symptom":"Failed to authenticate. API Error: 401 Invalid or expired API key","cause":"Only ANTHROPIC_API_KEY is set; Claude Code attempts internal OAuth refresh and gets 401.","fix":"Also set ANTHROPIC_AUTH_TOKEN to the SAME value (sk-cc-...). Both env vars are required."},{"symptom":"Hangs after first response, no follow-up tool calls","cause":"Multi-turn requests stuck on auth (same as above).","fix":"Set ANTHROPIC_AUTH_TOKEN."}]},"cursor_ide":{"name":"Cursor IDE","tested_version":"0.45.x","status":"Working in chat mode. Agent/Composer features remain on Cursor's backend (cannot be redirected).","setup":{"description":"Settings → Models → API Keys section. Enable 'Override OpenAI API Base URL' AND select Claude model.","steps":["1. Open Cursor → Settings (⌘,) → Models","2. Scroll to 'Anthropic API Key' (NOT OpenAI section — Cursor sends Anthropic-native payload to /v1/messages)","3. Enter your sk-cc-... key as the Anthropic API Key","4. Toggle 'Override Anthropic Base URL' ON","5. Set base URL: https://claude.ai-platform.space","6. Pick a Claude model (Sonnet 5 recommended for code, Opus 5 for hard tasks)","7. Verify with a test chat: 'Hi'"]},"limitations":["Cursor Agent/Composer always use Cursor's own backend regardless of base URL — only chat is proxied","Tab autocomplete uses Cursor's own model, not proxy","Tool definitions must match Anthropic-native format (proxy auto-converts OpenAI format)"]},"langchain_python":{"name":"langchain-anthropic (Python)","setup_code":"from langchain_anthropic import ChatAnthropic\nllm = ChatAnthropic(\n    model='claude-sonnet-5',\n    api_key='sk-cc-YOUR_KEY',\n    anthropic_api_url='https://claude.ai-platform.space',\n)\nresult = llm.invoke('Hello!')\nprint(result.content)","notes":"Full support: streaming, tool calling, structured output, multimodal (base64 images)."},"anthropic_sdk_python":{"name":"Official Anthropic Python SDK","setup_code":"from anthropic import Anthropic\nclient = Anthropic(\n    api_key='sk-cc-YOUR_KEY',\n    base_url='https://claude.ai-platform.space',\n)\nresponse = client.messages.create(\n    model='claude-sonnet-5',\n    max_tokens=1024,\n    messages=[{'role': 'user', 'content': 'Hello!'}]\n)\nprint(response.content[0].text)"},"openai_sdk_compat":{"name":"OpenAI SDK (compatibility mode)","description":"Works via /v1/chat/completions. Auto-converts OpenAI → Anthropic and back.","setup_code":"from openai import OpenAI\nclient = OpenAI(\n    api_key='sk-cc-YOUR_KEY',\n    base_url='https://claude.ai-platform.space/v1',\n)\nresp = client.chat.completions.create(\n    model='sonnet',  # short alias OK\n    messages=[{'role': 'user', 'content': 'Hi'}]\n)\nprint(resp.choices[0].message.content)"},"cline_continue":{"name":"Cline / Continue.dev / VS Code extensions","description":"Use 'Anthropic' provider, set Anthropic API Key = sk-cc-..., set Base URL = https://claude.ai-platform.space","tested":"Cline 3.x verified working with /v1/messages streaming + tool use"},"what_works":["Text generation (haiku, sonnet, opus)","Streaming SSE (real-time deltas)","Tool use / function calling (Anthropic native + OpenAI tools format)","Multi-turn conversation with tool results","Vision (image_url + base64 in content blocks)","Extended thinking (Sonnet/Haiku enabled, Opus 4.7/4.8 adaptive)","Prompt caching (cache_control with 5min and 1h TTL)","Server-side tools: web_search, web_fetch, code_execution","All anthropic-beta flags forwarded (interleaved-thinking, prompt-caching-scope, etc.)"],"what_does_not_work":["/v1/files (Files API) — returns 501. Anthropic OAuth Max subscription has no access. Use base64 attachments in content blocks instead.","/v1/messages/batches (Batches API) — returns 501. OAuth token lacks user:batch scope.","Cursor Composer/Agent features (use Cursor's own backend, not proxied)","Claude Code's `--resume` of conversations stored on Anthropic side (we don't proxy conversation storage endpoints)"]},"credit_tiers":{"description":"Overdraft / credit limit system. New users can go slightly negative without payment friction — the lower the trust, the smaller the overdraft. Tier upgrades happen automatically based on successful payment count.","tiers":[{"name":"new","credit_limit_usd":0.0,"criteria":"0 successful payments","use_case":"No overdraft until the first payment. The first top-up gets a +$5 bonus."},{"name":"active","credit_limit_usd":10.0,"criteria":"1+ successful payment","use_case":"User has proven willingness to pay. Allows larger spikes without interruption — top-up has time to land."},{"name":"loyal","credit_limit_usd":20.0,"criteria":"2+ successful payments","use_case":"Returning paying customer. Most of agent-style workloads (multi-step research) fit within this buffer."}],"how_it_works":["1. Each request: proxy estimates cost (input_tokens × price + safety margin).","2. If balance + credit_limit < estimated_cost → 402 insufficient_balance.","3. After completion, real cost is debited. Balance may go negative up to -credit_limit.","4. Auto-topup (if enabled in cabinet) charges the saved card when balance < threshold.","5. Tier recomputed on each successful payment via WayForPay/Lava webhook."],"response_field_in_error":{"402":{"error":{"type":"insufficient_balance","message":"...","balance":-0.45,"credit_limit":1.0,"tier":"new","payments_count":0}}},"see_also":["GET /auth/me — returns user's tier_name, credit_limit, balance","POST /billing/topup — increase balance + advance tier"]},"errors":{"description":"Unified error response shapes across all endpoints.","formats":{"standard":{"error":{"type":"<error_type>","message":"<human-readable>","request_id":"req-..."}},"fastapi_legacy":{"detail":"<message>"},"rate_limit":{"error":"rate_limit_error","rate_limit":{"unified_status":"warning|critical","utilization_5h_pct":0,"utilization_7d_pct":95.2}},"balance":{"error":{"type":"insufficient_balance","message":"...","balance":0.0,"credit_limit":1.0,"tier":"new","payments_count":0}}},"common_codes":{"400":"invalid_request_error — malformed body, unsupported field combo, Anthropic 400 propagated","401":"Invalid or expired API key","402":"insufficient_balance — see credit_tiers section","403":"Model not allowed for this key (check allowed_models in /admin/users)","429":"Rate limit — either daily user limit or OAuth pool unified limit (see /rate-limits)","500":"Unhandled exception — X-Request-ID in headers for debugging (added 15.05.2026)","502":"Bad Gateway — only on nginx layer (upstream Python down). Watcher alerts to TG.","503":"Service in maintenance mode","504":"Gateway timeout — SDK session execute() exceeded timeout"},"correlation":"All 500-level responses include X-Request-ID header. Engineering team can grep /var/log/nginx/domains/claude.ai-platform.space.5xx.log and /var/www/claude-api/logs/server_500.log for full traceback in seconds. When reporting bugs — always include X-Request-ID.","monitoring":"claude_5xx_watcher cron */2 min triggers TG alert in 'Claude Тех' chat when ≥3 5xx errors hit within 5 minutes. Dedup 15 min by status-signature. Watch logs proactively — don't wait for client complaints."},"performance":{"description":"Proxy latency profile after optimizations deployed 18.05.2026. TTFB (Time To First Byte) is the dominant metric for voice/realtime — measured from client send to first SSE chunk received. Use mode=direct + stream=true for minimum TTFB.","ttfb_benchmarks_haiku":{"description":"Real measurements after deploy 18.05.2026 (haiku model, ~70 chars system prompt)","non_stream":{"ttlb_avg_5req":"~1.10s (range 0.97-1.33s)","before_optimization":"~3.0s","improvement":"2.7x faster"},"stream_cold":{"ttfb":"~0.65s (first request after pool gone cold)","before_optimization":"~3.0s","improvement":"4.6x faster","when":"After >30s idle (TCP keepalive expires)"},"stream_warm":{"ttfb":"~0.17s (requests 2+)","before_optimization":"~3.0s","improvement":"17x faster","when":"Within 30s of previous request","use_for":"Voice agents, realtime chat, calls — keep connection warm"}},"what_was_optimized":["Singleton httpx.AsyncClient with keepalive_expiry=30s (vs default 5s) — TLS+TCP reused between requests, no handshake on warm pool","asyncio.gather for parallel SQL: maintenance_check + authenticate_api_key in phase 1, check_rate_limit + get_user_credit_info in phase 2","Fire-and-forget log_api_request via asyncio.create_task — client gets response immediately, MySQL INSERT happens in background (semaphore 50 for DoS protection)","In-memory pricing cache TTL 60s — no MySQL SELECT for each calculate_cost","Explicit cache_control ttl='1h' in auto-mode (Anthropic dropped default from 1h to 5min on 06.03.2026)","All sync PyMySQL operations wrapped in asyncio.to_thread — no event loop blocking"],"tips_for_minimum_latency":["Use mode=direct + stream=true for voice/realtime — TTFB ~170ms warm","Keep a long-lived connection: same client SDK instance, don't recreate per call (otherwise TLS handshake adds ~150-200ms)","For repeated system prompts: use cache_control with ttl='1h' — 85% cost reduction + faster response on cache hit","Choose haiku for shortest TTFB (~600ms upstream) vs sonnet (~1200ms) vs opus (~2700ms)","Send Authorization: Bearer header (not query param) — query parsing is slightly slower"],"where_the_remaining_time_goes":{"anthropic_inference":"60-65% (1000-1200ms upstream — outside our control, model-dependent)","network_rtt":"5-10% (Kyiv → US anycast Anthropic ~80-110ms one-way)","tls_handshake":"0% on warm pool, ~150-200ms on cold (mitigated by keepalive 30s)","proxy_overhead":"5-10% (auth, billing, normalization — async parallel where possible)","mysql_writes":"0% on response path (moved to background via fire-and-forget)"},"future_deferred":["Background keepalive ping every 30-60s to guarantee warm pool","Auto-fallback to Haiku 5.5 for short contexts in voice scenarios","LiveKit Anthropic plugin for direct client→Anthropic bypass (eliminates proxy for voice)","VPS in US-East would save ~80-100ms RTT, but breaks 60+ other services on same machine — not pursued"]},"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"]}}}