Подключитесь за минуту.
Nox говорит на языке OpenAI API. Меняете адрес и ключ — и любой код, SDK или инструмент начинает работать со всеми моделями каталога.Nox speaks the OpenAI API. Change the address and the key, and any code, SDK or tool works with every model in the catalog.
- протоколprotocol
- OpenAI Chat Completions
- авторизацияauth
Bearer sk-nox-…- стримингstreaming
- Server-Sent Events
Ваш ключ в примерахYour key in examples
Подставим сохранённый ключ во все примеры кода — его можно копировать и запускать сразу.We will put your saved key into every code sample so you can copy and run it right away.
Быстрый стартQuickstart
Nox совместим с OpenAI API. Подойдёт официальный SDK, любая библиотека или инструмент, где можно указать base_url. Три шага — и первый ответ модели у вас в терминале.Nox is compatible with the OpenAI API. Use the official SDK or any library or tool that lets you set a base_url. Three steps to your first model reply.
- Получите ключ. Кнопка «Получить API-ключ» — без регистрации и почты. Ключ показывается один раз, сохраните его.Get a key. Click “Get API key” — no sign-up, no email. The key is shown once, so save it.
- Укажите адрес API —
https://noxai.vip/v1— и ключ в настройках клиента.Set the API address —https://noxai.vip/v1— and your key in the client settings. - Отправьте запрос к любой модели из каталога.Send a request to any model from the catalog.
Установка SDKInstall the SDK
pip install openainpm install openaiПервый запросFirst request
from openai import OpenAI
client = OpenAI(
base_url="https://noxai.vip/v1",
api_key="sk-nox-...",
)
resp = client.chat.completions.create(
model="__MODEL__",
messages=[{"role": "user", "content": "__ASK__"}],
)
print(resp.choices[0].message.content)import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://noxai.vip/v1",
apiKey: "sk-nox-...",
});
const resp = await client.chat.completions.create({
model: "__MODEL__",
messages: [{ role: "user", content: "__ASK__" }],
});
console.log(resp.choices[0].message.content);curl https://noxai.vip/v1/chat/completions \
-H "Authorization: Bearer sk-nox-..." \
-H "Content-Type: application/json" \
-d '{
"model": "__MODEL__",
"messages": [{"role": "user", "content": "__ASK__"}]
}'Через переменные окруженияUsing environment variables
Официальные SDK читают адрес и ключ из окружения — тогда код вообще не нужно менять: OpenAI() без аргументов будет ходить в Nox.The official SDKs read the address and key from the environment, so your code does not change at all: OpenAI() with no arguments will talk to Nox.
OPENAI_BASE_URL=https://noxai.vip/v1
OPENAI_API_KEY=sk-nox-...АвторизацияAuthentication
Каждый запрос к API должен содержать ключ в заголовке Authorization:Every API request must carry your key in the Authorization header:
Authorization: Bearer sk-nox-...Для клиентов, которые не умеют менять этот заголовок, ключ также принимается в x-api-key или api-key. Ключ имеет вид sk-nox- и 40 символов после префикса.For clients that cannot set that header, the key is also accepted in x-api-key or api-key. Keys look like sk-nox- followed by 40 characters.
| ОтветResponse | КодCode | ПричинаReason |
|---|---|---|
401 | missing_api_key | Ключ не переданNo key provided |
401 | invalid_api_key | Ключ не найден или отозванKey not found or revoked |
403 | key_blocked | Ключ заблокирован за нарушение правилKey blocked for breaking the rules |
МоделиModels
Список доступных моделей отдаёт стандартный эндпоинт. Ключ для него необязателен. В поле model запросов передавайте id модели.The standard endpoint returns the list of available models. A key is optional here. Pass the model id in the model field of your requests.
https://noxai.vip/v1/modelsfor m in client.models.list():
print(m.id)const list = await client.models.list();
for (const m of list.data) console.log(m.id);curl https://noxai.vip/v1/modelsПомимо стандартных полей, Nox возвращает название, размер контекста и возможности модели:Besides the standard fields, Nox returns the model name, context size and capabilities:
{
"object": "list",
"data": [
{
"id": "gpt-4o-mini",
"object": "model",
"created": 1735689600,
"owned_by": "openai",
"name": "GPT-4o mini",
"context_length": 128000,
"max_output_tokens": 16384,
"capabilities": ["vision", "tools", "json"]
}
]
}Описания, лимиты и статус каждой модели — на странице Модели. Одну модель можно запросить по адресу GET /v1/models/{id}.Descriptions, limits and status for every model are on the Models page. A single model is available at GET /v1/models/{id}.
Chat CompletionsChat Completions
Основной эндпоинт: принимает историю диалога и возвращает ответ модели. Формат полностью совпадает с OpenAI.The main endpoint: takes a conversation history and returns the model reply. The format is identical to OpenAI.
https://noxai.vip/v1/chat/completionsПараметрыParameters
| ПараметрParameter | ТипType | ОписаниеDescription |
|---|---|---|
model | string | Обязательный. ID модели из каталога.Required. Model ID from the catalog. |
messages | array | Обязательный. Сообщения диалога: {"role", "content"}, роли system, user, assistant, tool.Required. Conversation messages: {"role", "content"} with roles system, user, assistant, tool. |
stream | boolean | Потоковый ответ через SSE. По умолчанию false. См. Стриминг.Stream the reply over SSE. Defaults to false. See Streaming. |
max_tokens | integer | Максимальная длина ответа. Значение выше лимита ключа или модели будет уменьшено, а если параметр не указан — подставится максимум. Также поддерживается max_completion_tokens.Maximum reply length. Values above the key or model limit are lowered; if omitted, the maximum is used. max_completion_tokens is also supported. |
temperature | number | Случайность ответа, обычно от 0 до 2.Randomness of the reply, usually 0 to 2. |
top_p | number | Nucleus sampling — альтернатива temperature.Nucleus sampling — an alternative to temperature. |
stop | string | array | Последовательности, на которых генерация остановится.Sequences where generation stops. |
tools | array | Описания функций, которые может вызвать модель. См. Tools и JSON.Functions the model may call. See Tools & JSON. |
tool_choice | string | object | auto, none, required или конкретная функция.auto, none, required or a specific function. |
response_format | object | {"type": "json_object"} или json_schema для структурированного ответа.{"type": "json_object"} or json_schema for structured output. |
stream_options | object | {"include_usage": true} — расход токенов в последнем чанке стрима.{"include_usage": true} — token usage in the last stream chunk. |
seedpresence_penaltyfrequency_penaltyuser | — | Передаются модели как есть.Passed to the model as is. |
Диалог и системный промптConversation and system prompt
resp = client.chat.completions.create(
model="__MODEL__",
temperature=0.7,
messages=[
{"role": "system", "content": "__SYS__"},
{"role": "user", "content": "__HI__"},
{"role": "assistant", "content": "..."},
{"role": "user", "content": "__ASK__"},
],
)
print(resp.choices[0].message.content)
print(resp.usage.total_tokens)const resp = await client.chat.completions.create({
model: "__MODEL__",
temperature: 0.7,
messages: [
{ role: "system", content: "__SYS__" },
{ role: "user", content: "__HI__" },
{ role: "assistant", content: "..." },
{ role: "user", content: "__ASK__" },
],
});
console.log(resp.choices[0].message.content);
console.log(resp.usage.total_tokens);curl https://noxai.vip/v1/chat/completions \
-H "Authorization: Bearer sk-nox-..." \
-H "Content-Type: application/json" \
-d '{
"model": "__MODEL__",
"temperature": 0.7,
"messages": [
{"role": "system", "content": "__SYS__"},
{"role": "user", "content": "__ASK__"}
]
}'ОтветResponse
{
"id": "chatcmpl-9f1c7d2a",
"object": "chat.completion",
"created": 1735689600,
"model": "__MODEL__",
"choices": [
{
"index": 0,
"message": { "role": "assistant", "content": "..." },
"finish_reason": "stop"
}
],
"usage": { "prompt_tokens": 24, "completion_tokens": 58, "total_tokens": 82 }
}СтримингStreaming
С "stream": true ответ приходит по частям в формате Server-Sent Events: каждая строка data: содержит чанк с фрагментом текста в choices[0].delta.content, а поток завершается строкой data: [DONE].With "stream": true the reply arrives in parts as Server-Sent Events: each data: line carries a chunk with a text fragment in choices[0].delta.content, and the stream ends with data: [DONE].
stream = client.chat.completions.create(
model="__MODEL__",
messages=[{"role": "user", "content": "__POEM__"}],
stream=True,
)
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)const stream = await client.chat.completions.create({
model: "__MODEL__",
messages: [{ role: "user", content: "__POEM__" }],
stream: true,
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
}curl -N https://noxai.vip/v1/chat/completions \
-H "Authorization: Bearer sk-nox-..." \
-H "Content-Type: application/json" \
-d '{
"model": "__MODEL__",
"stream": true,
"messages": [{"role": "user", "content": "__POEM__"}]
}'Формат потокаStream format
data: {"id":"chatcmpl-9f1c","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"role":"assistant","content":""}}]}
data: {"id":"chatcmpl-9f1c","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":"..."}}]}
data: {"id":"chatcmpl-9f1c","object":"chat.completion.chunk","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}
data: [DONE]Чтобы получить расход токенов, передайте "stream_options": {"include_usage": true} — последний чанк перед [DONE] будет содержать поле usage и пустой массив choices.To get token usage, pass "stream_options": {"include_usage": true} — the last chunk before [DONE] will contain usage and an empty choices array.
Tools и JSONTools & JSON
Модели с меткой «инструменты» умеют вызывать функции: вы описываете их в tools, модель возвращает tool_calls с аргументами, вы выполняете функцию и отправляете результат сообщением с ролью tool.Models tagged “tools” can call functions: you describe them in tools, the model returns tool_calls with arguments, you run the function and send the result back as a tool message.
import json
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "__WDESC__",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
},
},
}]
messages = [{"role": "user", "content": "__WEATHER__"}]
resp = client.chat.completions.create(model="__MODEL__", messages=messages, tools=tools)
msg = resp.choices[0].message
if msg.tool_calls:
messages.append(msg)
for call in msg.tool_calls:
args = json.loads(call.function.arguments)
result = {"city": args["city"], "temp": 21, "sky": "clear"}
messages.append({"role": "tool", "tool_call_id": call.id, "content": json.dumps(result)})
resp = client.chat.completions.create(model="__MODEL__", messages=messages, tools=tools)
print(resp.choices[0].message.content)const tools = [{
type: "function",
function: {
name: "get_weather",
description: "__WDESC__",
parameters: {
type: "object",
properties: { city: { type: "string" } },
required: ["city"],
},
},
}];
const messages = [{ role: "user", content: "__WEATHER__" }];
let resp = await client.chat.completions.create({ model: "__MODEL__", messages, tools });
const msg = resp.choices[0].message;
if (msg.tool_calls) {
messages.push(msg);
for (const call of msg.tool_calls) {
const args = JSON.parse(call.function.arguments);
const result = { city: args.city, temp: 21, sky: "clear" };
messages.push({ role: "tool", tool_call_id: call.id, content: JSON.stringify(result) });
}
resp = await client.chat.completions.create({ model: "__MODEL__", messages, tools });
}
console.log(resp.choices[0].message.content);Структурированный ответStructured output
Режим JSON гарантирует, что ответ будет валидным JSON. Обязательно попросите об этом и в тексте промпта. Для строгой схемы используйте {"type": "json_schema", ...}, если модель её поддерживает.JSON mode guarantees the reply is valid JSON. Ask for it in the prompt as well. For a strict schema use {"type": "json_schema", ...} if the model supports it.
resp = client.chat.completions.create(
model="__MODEL__",
response_format={"type": "json_object"},
messages=[{"role": "user", "content": "__JSON__"}],
)
data = json.loads(resp.choices[0].message.content)const resp = await client.chat.completions.create({
model: "__MODEL__",
response_format: { type: "json_object" },
messages: [{ role: "user", content: "__JSON__" }],
});
const data = JSON.parse(resp.choices[0].message.content);ИзображенияImages
Модели с меткой «изображения» принимают картинки в сообщениях. Передайте content массивом частей: текст и image_url со ссылкой или data URL в base64.Models tagged “vision” accept images in messages. Pass content as an array of parts: text plus image_url with a link or a base64 data URL.
import base64
img = base64.b64encode(open("photo.jpg", "rb").read()).decode()
resp = client.chat.completions.create(
model="__MODEL__",
messages=[{
"role": "user",
"content": [
{"type": "text", "text": "__IMG__"},
{"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{img}"}},
],
}],
)
print(resp.choices[0].message.content)import { readFileSync } from "node:fs";
const img = readFileSync("photo.jpg").toString("base64");
const resp = await client.chat.completions.create({
model: "__MODEL__",
messages: [{
role: "user",
content: [
{ type: "text", text: "__IMG__" },
{ type: "image_url", image_url: { url: "data:image/jpeg;base64," + img } },
],
}],
});
console.log(resp.choices[0].message.content);Максимальный размер тела запроса — 32 МБ.The maximum request body size is 32 MB.
ЭмбеддингиEmbeddings
Векторные представления текста для поиска, кластеризации и RAG. Используйте модели с меткой «эмбеддинги».Vector representations of text for search, clustering and RAG. Use models tagged “embeddings”.
https://noxai.vip/v1/embeddingsres = client.embeddings.create(
model="__EMBMODEL__",
input=["__EMB__", "__EMB2__"],
)
print(len(res.data), len(res.data[0].embedding))const res = await client.embeddings.create({
model: "__EMBMODEL__",
input: ["__EMB__", "__EMB2__"],
});
console.log(res.data.length, res.data[0].embedding.length);curl https://noxai.vip/v1/embeddings \
-H "Authorization: Bearer sk-nox-..." \
-H "Content-Type: application/json" \
-d '{"model": "__EMBMODEL__", "input": ["__EMB__"]}'CompletionsCompletions
Устаревший формат «текст на входе — текст на выходе». Оставлен для совместимости со старыми инструментами и работает только с моделями, которые поддерживают его у провайдера.The legacy “text in, text out” format. Kept for compatibility with older tools; it works only with models whose provider supports it.
https://noxai.vip/v1/completionscurl https://noxai.vip/v1/completions \
-H "Authorization: Bearer sk-nox-..." \
-H "Content-Type: application/json" \
-d '{"model": "__MODEL__", "prompt": "__HI__", "max_tokens": 64}'ЛимитыLimits
Лимиты считаются отдельно для каждого ключа. Дневные счётчики обнуляются в 00:00 UTC, минутный работает как скользящее окно. Подробно — на странице Цены и лимиты.Limits are counted per key. Daily counters reset at 00:00 UTC; the per-minute limit is a sliding window. See Pricing & limits for details.
| ЛимитLimit | ЗначениеValue | Что считаетсяWhat counts |
|---|---|---|
| RPM | — | Запросов за любые 60 секундRequests in any 60 seconds |
| RPD | — | Запросов за сутки (UTC)Requests per UTC day |
| TPD | — | Токенов запроса и ответа за суткиPrompt and completion tokens per day |
| ПараллельностьConcurrency | — | Одновременных запросов с ключаSimultaneous requests per key |
| max_tokens | — | Максимальная длина одного ответаMaximum length of a single reply |
У отдельных моделей может быть собственный дневной лимит запросов — он указан в карточке модели и расходуется вместе с общим.Some models have their own daily request limit — it is shown on the model card and counts together with the overall one.
Заголовки ответаResponse headers
Каждый ответ содержит остаток дневных лимитов:Every response carries the remaining daily limits:
| ЗаголовокHeader | ЗначениеMeaning |
|---|---|
x-ratelimit-limit-requests | Дневной лимит запросовDaily request limit |
x-ratelimit-remaining-requests | Сколько запросов осталось сегодняRequests left today |
x-ratelimit-limit-tokens | Дневной лимит токеновDaily token limit |
x-ratelimit-remaining-tokens | Сколько токенов осталось сегодняTokens left today |
x-ratelimit-reset-requestsx-ratelimit-reset-tokens | Время до сброса, например 3600sTime until reset, e.g. 3600s |
retry-after | Только в ответах 429: через сколько секунд повторить429 responses only: seconds to wait before retrying |
x-request-id | ID запроса — укажите его, если пишете в поддержкуRequest ID — include it when contacting support |
Повторы при 429Retrying on 429
Официальные SDK сами повторяют запросы с ответом 429 и учитывают retry-after. Число попыток можно увеличить:The official SDKs retry 429 responses automatically and honor retry-after. You can raise the number of attempts:
client = OpenAI(base_url="https://noxai.vip/v1", api_key="sk-nox-...", max_retries=5)const client = new OpenAI({ baseURL: "https://noxai.vip/v1", apiKey: "sk-nox-...", maxRetries: 5 });__RETRYC__
curl --retry 5 https://noxai.vip/v1/chat/completions ...daily_limit_exceeded, daily_token_limit_exceeded) повторами не обойти — дождитесь сброса в 00:00 UTC.Daily limits (daily_limit_exceeded, daily_token_limit_exceeded) cannot be bypassed by retrying — wait for the reset at 00:00 UTC.ОшибкиErrors
Ошибки возвращаются в формате OpenAI: HTTP-статус и JSON с полями message, type и code. Ориентируйтесь на code — он стабилен, текст сообщения может меняться.Errors use the OpenAI format: an HTTP status plus JSON with message, type and code. Rely on code — it is stable, while the message text may change.
{
"error": {
"message": "Daily request limit reached (500 per day). The limit resets at 00:00 UTC.",
"type": "rate_limit_exceeded",
"code": "daily_limit_exceeded"
}
}| СтатусStatus | КодCode | Что случилосьWhat happened | Что делатьWhat to do |
|---|---|---|---|
400 | invalid_json | Тело запроса — не JSONThe body is not valid JSON | Проверьте экранирование и кодировкуCheck escaping and encoding |
400 | missing_model | Не указан modelmodel is missing | Передайте ID моделиPass a model ID |
400 | missing_messages | Нет messages (или prompt, input)No messages (or prompt, input) | Добавьте обязательное полеAdd the required field |
401 | missing_api_key | Ключ не переданNo key provided | Добавьте заголовок AuthorizationAdd the Authorization header |
401 | invalid_api_key | Ключ не найден или отозванKey not found or revoked | Проверьте ключ или получите новыйCheck the key or get a new one |
403 | key_blocked | Ключ заблокированThe key is blocked | Свяжитесь с намиContact us |
404 | model_not_found | Такой модели нетNo such model | Сверьтесь со списком /v1/modelsCheck /v1/models |
413 | body_too_large | Тело запроса больше 32 МБBody larger than 32 MB | Уменьшите изображения или историюShrink images or history |
429 | rate_limit_exceeded | Превышен лимит в минутуPer-minute limit hit | Повторите через retry-afterRetry after retry-after |
429 | concurrency_limit_exceeded | Слишком много одновременных запросовToo many concurrent requests | Дождитесь завершения текущихWait for running requests |
429 | daily_limit_exceeded | Исчерпан дневной лимит запросовDaily request limit used up | Дождитесь 00:00 UTCWait for 00:00 UTC |
429 | daily_token_limit_exceeded | Исчерпан дневной лимит токеновDaily token limit used up | Дождитесь 00:00 UTCWait for 00:00 UTC |
429 | model_daily_limit_exceeded | Исчерпан дневной лимит этой моделиThis model's daily limit used up | Выберите другую модельPick another model |
429 | service_capacity | Сервис исчерпал дневную ёмкостьThe service hit its daily capacity | Повторите позжеTry again later |
429 | upstream_rate_limited | Модель перегружена у провайдераThe model is overloaded upstream | Повторите через несколько секундRetry in a few seconds |
502 | upstream_error | Провайдер вернул ошибкуThe provider returned an error | Повторите запросRetry the request |
503 | model_unavailable | Модель временно недоступнаThe model is temporarily unavailable | Смотрите статусCheck the status |
503 | maintenance | Идут технические работыMaintenance in progress | Повторите позжеTry again later |
504 | upstream_timeout | Провайдер не ответил вовремяThe provider timed out | Повторите или включите стримингRetry or enable streaming |
Ошибки валидации от самой модели (например, неподдерживаемый параметр) возвращаются со статусом провайдера — 400 или 422 — и его сообщением.Validation errors from the model itself (e.g. an unsupported parameter) are returned with the provider status — 400 or 422 — and its message.
ИнтеграцииIntegrations
Nox работает везде, где есть поддержка OpenAI-совместимого API. Вот настройки для популярных инструментов — везде нужны только адрес и ключ.Nox works anywhere that supports an OpenAI-compatible API. Here are settings for popular tools — all you need is the address and the key.
Cursor
Settings → Models → OpenAI API Key: вставьте ключ, включите Override OpenAI Base URL и укажите адрес ниже. Затем добавьте модель по её ID.Settings → Models → OpenAI API Key: paste your key, enable Override OpenAI Base URL and set the address below. Then add a model by its ID.
https://noxai.vip/v1Continue
Расширение для VS Code и JetBrains. Добавьте модель в config.yaml:Extension for VS Code and JetBrains. Add a model to config.yaml:
models:
- name: Nox
provider: openai
model: __MODEL__
apiBase: https://noxai.vip/v1
apiKey: sk-nox-...Open WebUI
Admin Panel → Settings → Connections → OpenAI API: адрес и ключ. Или переменные окружения при запуске контейнера:Admin Panel → Settings → Connections → OpenAI API: address and key. Or environment variables when starting the container:
OPENAI_API_BASE_URL=https://noxai.vip/v1
OPENAI_API_KEY=sk-nox-...LibreChat
Добавьте свой эндпоинт в librechat.yaml, а ключ положите в .env как NOX_API_KEY:Add a custom endpoint to librechat.yaml and put the key into .env as NOX_API_KEY:
endpoints:
custom:
- name: "Nox"
apiKey: "${NOX_API_KEY}"
baseURL: "https://noxai.vip/v1"
models:
default: ["__MODEL__"]
fetch: true
titleConvo: true
titleModel: "current_model"n8n
Credentials → New → OpenAI: вставьте ключ в API Key и укажите адрес в поле Base URL. Узлы OpenAI и AI Agent подхватят модели автоматически.Credentials → New → OpenAI: paste the key into API Key and set the address in Base URL. The OpenAI and AI Agent nodes will pick up the models.
https://noxai.vip/v1LangChain
Пакет langchain-openai:The langchain-openai package:
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
model="__MODEL__",
base_url="https://noxai.vip/v1",
api_key="sk-nox-...",
)
print(llm.invoke("__HI__").content)LlamaIndex
Пакет llama-index-llms-openai-like:The llama-index-llms-openai-like package:
from llama_index.llms.openai_like import OpenAILike
llm = OpenAILike(
model="__MODEL__",
api_base="https://noxai.vip/v1",
api_key="sk-nox-...",
is_chat_model=True,
)
print(llm.complete("__HI__"))Vercel AI SDK
Провайдер @ai-sdk/openai-compatible:The @ai-sdk/openai-compatible provider:
import { createOpenAICompatible } from "@ai-sdk/openai-compatible";
import { generateText } from "ai";
const nox = createOpenAICompatible({
name: "nox",
baseURL: "https://noxai.vip/v1",
apiKey: process.env.NOX_API_KEY,
});
const { text } = await generateText({ model: nox("__MODEL__"), prompt: "__HI__" });