XUSS. / Документация AI API Панель
На этой странице

XUSS AI API

Продакшн-API, совместимый с OpenAI, поверх хостинг-платформы XUSS. Подключите любой OpenAI SDK, редактор или чат-клиент к XUSS — без привязки к вендору, один ключ, оплата по мере использования с вашего баланса XUSS.

Быстрый старт

1. Создайте API-ключ в панели: API → API-ключи → Создать ключ. Скопируйте его — он показывается только один раз. Ключи начинаются с xsk-.

2. Вызовите API на любом языке — выберите вкладку:

curl https://xuss.us/v1/chat/completions \
  -H "Authorization: Bearer xsk-YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "xuss/kitsune",
    "messages": [{"role": "user", "content": "Привет!"}]
  }'
from openai import OpenAI

client = OpenAI(base_url="https://xuss.us/v1", api_key="xsk-YOUR_KEY")

r = client.chat.completions.create(
    model="xuss/kitsune",
    messages=[{"role": "user", "content": "Привет!"}],
)
print(r.choices[0].message.content)
import OpenAI from "openai";

const client = new OpenAI({ baseURL: "https://xuss.us/v1", apiKey: "xsk-YOUR_KEY" });

const r = await client.chat.completions.create({
  model: "xuss/kitsune",
  messages: [{ role: "user", content: "Привет!" }],
});
console.log(r.choices[0].message.content);
package main

import (
	"bytes"
	"fmt"
	"io"
	"net/http"
)

func main() {
	body := []byte(`{"model":"xuss/kitsune","messages":[{"role":"user","content":"Привет!"}]}`)
	req, _ := http.NewRequest("POST", "https://xuss.us/v1/chat/completions", bytes.NewReader(body))
	req.Header.Set("Authorization", "Bearer xsk-YOUR_KEY")
	req.Header.Set("Content-Type", "application/json")

	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(string(out))
}
<?php
$ch = curl_init('https://xuss.us/v1/chat/completions');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer xsk-YOUR_KEY',
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'model' => 'xuss/kitsune',
        'messages' => [['role' => 'user', 'content' => 'Привет!']],
    ]),
]);
$res = json_decode(curl_exec($ch), true);
echo $res['choices'][0]['message']['content'], PHP_EOL;

Вот и всё — ваш баланс XUSS списывается за токены, подписка не нужна.

Аутентификация

Каждый запрос требует bearer-токен:

Authorization: Bearer xsk-YOUR_KEY
Content-Type: application/json

Ключи создаются и отзываются в Панель → API. Правила:

Никогда не показывайте ключ в клиентском коде или публичных репозиториях. Если ключ утёк — отзовите его в панели и создайте новый.

Эндпоинты

МетодПутьОписание
GET/v1/modelsСписок моделей, доступных вашему ключу, с ценами и возможностями
POST/v1/chat/completionsСоздать чат-завершение (стриминг или нет)
GET/v1/toolsСписок серверных инструментов, которые API может выполнить за вас
GET/v1/skillsСписок справочных навыков, которые может загрузить ассистент

Все принимают Authorization: Bearer xsk-….

Модели

…

GET /v1/models возвращает модели, доступные в API, включая окно контекста, поддержку зрения и цену за токен:

{
  "object": "list",
  "data": [
    {
      "id": "xuss/kitsune",
      "object": "model",
      "owned_by": "xuss",
      "context_window": 1048576,
      "vision": true,
      "pricing": {
        "prompt": 0.00000029,
        "completion": 0.00000129,
        "input_cache_read": 0.0000000099
      }
    }
  ]
}

Цены указаны в USD за токен. Умножьте на 1 000 000, чтобы получить цену за миллион, как в панели.

Маршрутизация модели. За одним идентификатором модели XUSS может направлять запросы на разные мощности, чтобы сервис оставался быстрым и доступным. Это незаметно для вас: запрошенная model всегда та, что возвращается в ответе, и модель знает своё имя. Цены в /v1/models — это цены, по которым с вас списывают.

Чат-завершения

POST /v1/chat/completions

Тело запроса

ПолеТипПримечания
modelstringобязательно — например, xuss/kitsune
messagesarrayобязательно — см. Messages
streambooleantrue = Server-Sent Events
temperaturenumber0–2, по умолчанию 0.2
max_tokensintegerограничивает длину ответа
max_completion_tokensintegerсиноним max_tokens
toolsarrayопределения функций/инструментов — см. Инструменты
tool_choicestring/objectпередаётся модели
response_formatobject{"type":"json_object"} для JSON-режима
top_p, stop, seed, presence_penalty, frequency_penalty, logit_bias, n, user, logprobs, top_logprobs—передаются дальше

messages следует схеме OpenAI (роли system, user, assistant, tool; мультимодальные массивы контента).

Ответ

{
  "id": "chatcmpl-3f9c1a...",
  "object": "chat.completion",
  "created": 1791000000,
  "model": "xuss/kitsune",
  "choices": [
    {
      "index": 0,
      "message": {"role": "assistant", "content": "Привет! Чем помочь?"},
      "finish_reason": "stop",
      "logprobs": null
    }
  ],
  "usage": {"prompt_tokens": 12, "completion_tokens": 7, "total_tokens": 19},
  "system_fingerprint": "xuss"
}

finish_reason — это stop, length или tool_calls.

Messages

Стандартный массив сообщений OpenAI. Минимальный одноходовой запрос:

{"model": "xuss/kitsune", "messages": [{"role": "user", "content": "Привет"}]}

Многоходовой диалог — отправляйте всю историю каждый раз:

{
  "model": "xuss/kitsune",
  "messages": [
    {"role": "system", "content": "Ты краткий ассистент."},
    {"role": "user", "content": "Что такое XUSS?"},
    {"role": "assistant", "content": "XUSS — это хостинг-платформа."},
    {"role": "user", "content": "У неё есть AI API?"}
  ]
}

Стриминг

Установите "stream": true, чтобы получать Server-Sent Events. Каждая строка — data: {json}; поток заканчивается data: [DONE].

Чанки выглядят так:

data: {"id":"chatcmpl-…","object":"chat.completion.chunk","created":…,"model":"xuss/kitsune","choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null}],"system_fingerprint":"xuss"}

data: {"id":"chatcmpl-…","choices":[{"index":0,"delta":{"content":"Тихий "},"finish_reason":null}]}

data: {"id":"chatcmpl-…","choices":[{"index":0,"delta":{"content":"гул стоек"},"finish_reason":null}]}

data: {"id":"chatcmpl-…","choices":[],"usage":{"prompt_tokens":14,"completion_tokens":9,"total_tokens":23}}

data: [DONE]

Чтение потока на любом языке:

curl -N https://xuss.us/v1/chat/completions \
  -H "Authorization: Bearer xsk-YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"xuss/kitsune","stream":true,
       "messages":[{"role":"user","content":"Напиши хайку про серверы"}]}'
stream = client.chat.completions.create(
    model="xuss/kitsune",
    messages=[{"role": "user", "content": "Напиши хайку про серверы"}],
    stream=True,
)
for chunk in stream:
    delta = chunk.choices[0].delta.content if chunk.choices else None
    if delta:
        print(delta, end="", flush=True)
const stream = await client.chat.completions.create({
  model: "xuss/kitsune",
  messages: [{ role: "user", content: "Напиши хайку про серверы" }],
  stream: true,
});
for await (const chunk of stream) {
  process.stdout.write(chunk.choices[0]?.delta?.content || "");
}
package main

import (
	"bufio"
	"bytes"
	"fmt"
	"net/http"
	"strings"
)

func main() {
	body := []byte(`{"model":"xuss/kitsune","stream":true,"messages":[{"role":"user","content":"Напиши хайку про серверы"}]}`)
	req, _ := http.NewRequest("POST", "https://xuss.us/v1/chat/completions", bytes.NewReader(body))
	req.Header.Set("Authorization", "Bearer xsk-YOUR_KEY")
	req.Header.Set("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()

	sc := bufio.NewScanner(res.Body)
	for sc.Scan() {
		line := sc.Text()
		if !strings.HasPrefix(line, "data: ") || strings.HasSuffix(line, "[DONE]") {
			continue
		}
		fmt.Println(line[6:]) // parse JSON, read choices[0].delta.content
	}
}
<?php
$ch = curl_init('https://xuss.us/v1/chat/completions');
curl_setopt_array($ch, [
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer xsk-YOUR_KEY',
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'model' => 'xuss/kitsune',
        'stream' => true,
        'messages' => [['role' => 'user', 'content' => 'Напиши хайку про серверы']],
    ]),
    CURLOPT_WRITEFUNCTION => function ($ch, $chunk) {
        foreach (explode("\n", $chunk) as $line) {
            if (str_starts_with($line, 'data: ') && !str_contains($line, '[DONE]')) {
                $j = json_decode(substr($line, 6), true);
                echo $j['choices'][0]['delta']['content'] ?? '';
            }
        }
        return strlen($chunk);
    },
]);
curl_exec($ch);
Когда модель поддерживает рассуждения, стриминговые чанки могут дополнительно содержать поле reasoning_content в delta. Стандартные SDK его игнорируют, и его не нужно обрабатывать как вывод.

Системные промпты и идентичность

Ваши сообщения system учитываются. Модель также знает своё отображаемое имя и, когда её спрашивают, какая она модель, отвечает только этим именем — она никогда не раскрывает вышестоящего провайдера или маршрут.

{
  "model": "xuss/kitsune",
  "messages": [
    {"role": "system", "content": "Ты лаконичный DevOps-ассистент. Отвечай пунктами."},
    {"role": "user", "content": "Как перезапустить сервис systemd?"}
  ]
}

Зрение (изображения)

Передавайте изображения как части контента OpenAI image_url (data URL или публичные http(s) URL). Изображения принимают только модели с "vision": true в /v1/models; при отправке изображения модели без зрения возвращается текстовая пометка, и модель отвечает только по тексту.

r = client.chat.completions.create(
    model="xuss/kitsune",
    messages=[{
        "role": "user",
        "content": [
            {"type": "text", "text": "Что на этом изображении?"},
            {"type": "image_url", "image_url": {"url": "data:image/png;base64,iVBORw0KGgo..."}},
        ],
    }],
)

Лимиты: до 8 частей-изображений, каждая до ~6 МБ; изображения не учитываются в текстовом бюджете.

Вызов функций

Передавайте tools в стиле OpenAI. Когда модель решает вызвать функцию, finish_reason становится tool_calls, а сообщение содержит tool_calls.

tools = [{
    "type": "function",
    "function": {
        "name": "get_weather",
        "description": "Get current weather for a city",
        "parameters": {
            "type": "object",
            "properties": {"city": {"type": "string"}},
            "required": ["city"],
        },
    },
}]

r = client.chat.completions.create(
    model="xuss/kitsune",
    messages=[{"role": "user", "content": "Погода в Ташкенте?"}],
    tools=tools,
)

call = r.choices[0].message.tool_calls[0]
print(call.function.name, call.function.arguments)

Затем отправьте результат обратно как сообщение tool:

messages = [
    {"role": "user", "content": "Погода в Ташкенте?"},
    r.choices[0].message,
    {"role": "tool", "tool_call_id": call.id, "content": '{"temp_c": 24, "sky": "clear"}'},
]
final = client.chat.completions.create(model="xuss/kitsune", messages=messages)

Серверные инструменты (веб + навыки)

Включаются по запросу. Добавьте "xuss_tools": true (все) или массив нужных. Тогда XUSS выполняет эти инструменты за вас на сервере — модель вызывает их, сервер выполняет и продолжает, и вы получаете финальный ответ в том же запросе. Клиентский цикл не нужен.

r = client.chat.completions.create(
    model="xuss/kitsune",
    xuss_tools=True,                       # или ["web_search", "read_skill"]
    messages=[{"role": "user",
               "content": "Найди в интернете последний релиз Python и сделай сводку."}],
)
print(r.choices[0].message.content)
{
  "model": "xuss/kitsune",
  "xuss_tools": true,
  "messages": [{"role": "user", "content": "Открой https://example.com и дай заголовок страницы."}]
}
ИнструментЧто делает
web_searchВеб-поиск (метапоиск SearXNG): заголовки, URL и сниппеты
fetch_urlЗагружает HTTP(S) URL на сервере и возвращает текст (HTML преобразуется в текст)
browser_renderОткрывает страницу в настоящем headless-браузере: статус HTTP, заголовок, видимый текст, ошибки консоли, неудачные запросы, метрики вёрстки, опциональный JS eval
read_skillЗагружает один из справочных навыков ниже (полный гайд) в контекст модели

Это только чтение: нет доступа к файлам, базам данных, хостингам или вашему аккаунту. Инструменты, которые что-то меняют (файловый менеджер, DNS, базы данных и т. д.), остаются в ваших руках и намеренно не предоставляются.

Доступные навыки

read_skill загружает полный справочный документ любого из них в контекст — просто скажите модели, какой (например, «используй навык product-design»).

ID навыкаО чём
telegram-botsполный Telegram Bot API 10.3: каждый метод/тип, примеры aiogram 3, платежи/Stars, вебхуки, премиум-эмодзи/подарки, rich-сообщения и стриминговые черновики
product-designсайты/страницы/галереи/UI, которые выглядят намеренно оформленными: токены, правила против «слопа», макеты, фото-галереи
cybersecurityписать и аудировать безопасный код: инъекции/XSS/CSRF/IDOR, работа с секретами, безопасность ботов, реагирование на инциденты
telegram-miniappsTelegram WebApps: авторизация initData, переменные темы, MainButton/BackButton, Stars, деплой
shop-botполный бот-магазин в Telegram: каталог, корзина, заказы, админка, доставка, оплата
paymentsClick/Payme/Paylov/Uzum + Crypto Pay + Telegram Stars: инвойсы, проверка вебхуков, идемпотентность
php-webPHP-сайты и WordPress: структура, PDO, авторизация/CSRF, шаблоны, безопасность, деплой
ai-integrationLLM внутри ваших приложений: чат/стриминг, RAG, промптинг, лимиты стоимости, безопасность API-ключей
python-backendпродакшн Python: боты, FastAPI/Flask, дисциплина asyncio, доступ к БД, run-сервисы, обработка ошибок
node-backendNode/TypeScript-бэкенды и боты: Express/Fastify/Telegraf, окружение, управление процессами, ошибки
databasesMySQL/PostgreSQL/SQLite: проектирование схем, индексы, миграции, транзакции, бэкапы
rest-apiдизайн API: авторизация, валидация, пагинация, единый формат ошибок, лимиты, подпись вебхуков
deployment-opsдеплой проектов на этом хостинге: домены/DNS/SSL, обратный прокси, порты, cron, бэкапы, логи
git-githubgit-процессы, деплой-ключи, вебхуки автодеплоя, гигиена секретов, откат
scraping-automationэтичные парсеры и наблюдатели: структурированные источники, backoff, дедупликация, расписание, алерты
seoтехнический SEO: заголовки, структурированные данные, карты сайта, hreflang, индексация (Google и Yandex)
media-pipelineпайплайны изображений/видео: ресайз, WebP, превью, сжатие, превью ffmpeg
i18n-localizationuz/ru/en + RTL: словари строк, форматы чисел/дат/множественных чисел, язык ботов, hreflang
testing-qualityдисциплина запуска/проверки/отладки, юнит-тесты, линтинг, привычки ревью перед «готово»
analytics-monitoringпроверки доступности, отслеживание ошибок, ежедневная статистика, приватная аналитика и алерты
legal-templatesстраницы privacy/terms/refund + согласие + удаление данных (практическая база)
react-best-practicesпроизводительность React/Next.js: водопады, бандлы, рендеринг, гидрация, ререндеры
mobile-designнативный мобильный UX: паттерны платформ, психология касаний, мобильная производительность
senior-frontendsenior frontend-инженерия: архитектура, компоненты, обзоры производительности
senior-backendsenior backend-инженерия: дизайн API/БД, масштабирование, код-ревью
senior-securityархитектура безопасности, моделирование угроз, реализация криптографии, аудиты
ui-design-systemдизайн-токены, компоненты, передача в разработку; генерация системы токенов из бренд-цвета
tgbot-cloneбезопасно клонировать функции Telegram-бота: исследование, карта функций, реализация и тесты
product-layersслоистый продуктовый/UX-метод: потребности → стратегия → концептуальная модель → поверхность
find-skillsнаходить и устанавливать переиспользуемые навыки для агентных проектов

Структурированный вывод (JSON-режим)

Установите response_format в {"type":"json_object"} и попросите модель выдавать JSON. content ответа — это строка JSON.

r = client.chat.completions.create(
    model="xuss/kitsune",
    response_format={"type": "json_object"},
    messages=[{"role": "user",
               "content": "Верни JSON с ключами a и b, a=1, b=2"}],
)
import json
print(json.loads(r.choices[0].message.content))  # {'a': 1, 'b': 2}
Всегда разбирайте защитно и описывайте нужную форму в промпте.

Биллинг и учёт токенов

Формула стоимости (на запрос):

cost = cache_miss_tokens × price_in
     + cache_hit_tokens  × price_cache
     + completion_tokens × price_out

(Цены за токен; разделите на 1 000 000 для цены за миллион.)

Лимиты и квоты

ОбластьПо умолчанию
На пользователя300 запросов / минуту
На API-ключ600 запросов / минуту

При превышении лимита возвращается 429 с семантикой Retry-After (сделайте паузу и повторите). Тело запроса ограничено 25 МБ.

Ошибки

Ошибки используют формат ошибок OpenAI:

{
  "error": {
    "message": "Model 'xuss/foo' not found",
    "type": "invalid_request_error",
    "param": "model",
    "code": "model_not_found"
  }
}
Статусtype / codeЗначение
400invalid_request_errorНекорректный запрос (отсутствуют/неверны поля, неразбираемое тело)
401authentication_error · invalid_api_key, key_expiredОтсутствует, неверный или истёкший API-ключ
402insufficient_quota · key_spend_limit_reachedБаланс пуст или ключ достиг лимита расходов
403permission_errorAPI не включён для аккаунта или аккаунт отключён
404invalid_request_error · model_not_foundНеизвестная модель
413invalid_request_errorТело запроса слишком велико (> 25 МБ)
422invalid_request_errorНеверная полезная нагрузка запроса (схема)
429rate_limit_error · rate_limit_exceededПревышен лимит — сбавьте темп
500 / 502api_error · upstream_errorВременная проблема вышестоящего сервиса — повторите с backoff
503api_error · service_unavailableAI API сейчас отключён

param устанавливается, когда ошибка касается конкретного поля запроса. Стандартные SDK читают error.message (и error.code) напрямую.

Временные сбои также приходят как обычное сообщение ассистента, начинающееся с «The model is temporarily unavailable…», если поток уже начался.

Использование с OpenAI-совместимыми инструментами

Работает любой клиент с поддержкой пользовательского базового URL OpenAI. Укажите:

Примеры:

# open-webui / LibreChat / Cursor / Cline / Continue / LangChain:
#   set the OpenAI base URL to https://xuss.us/v1 and paste your key

Стиль переменных окружения (многие инструменты их учитывают):

export OPENAI_BASE_URL="https://xuss.us/v1"
export OPENAI_API_KEY="xsk-YOUR_KEY"

LangChain (Python):

from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="xuss/kitsune", base_url="https://xuss.us/v1",
                 api_key="xsk-YOUR_KEY")
print(llm.invoke("Привет").content)

Расширенные параметры

Принимаются и передаются модели, когда поддерживаются: top_p, stop, seed, presence_penalty, frequency_penalty, logit_bias, user, n, parallel_tool_calls, tool_choice.

FAQ

Нужна ли отдельная подписка? Нет. Вы платите за токены со своего баланса XUSS.

Какие id моделей использовать? Ровно те, что в GET /v1/models (например, xuss/kitsune). Отображаемые имена вроде «Kitsune» показаны в панели.

Можно ли отправлять изображения? Да, моделям с "vision": true.

Используются ли мои данные для обучения? Нет — запросы проксируются к модели для получения ответа и не используются для обучения.

Что если провайдер медленный или недоступен? Запрос прозрачно повторяется на альтернативных мощностях; id модели и цены сохраняются.

Как сменить ключ? Создайте новый ключ, переключите приложения, затем отзовите старый в панели.

Поддержка