Node.js + AI API

Нейросети в Node.js через один baseURL

Штатный openai-пакет для JavaScript и TypeScript: baseURL NormaHub, ключ из окружения, model ID из каталога. Потоковые ответы, типизированные ошибки, оплата рублями.

Для кого: node.js-разработчики и команды, строящие чаты, ботов и AI-фичи в JS-стеке

Создать API key

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

От ключа до первого ответа

  1. 01

    Установите openai-пакет, создайте ключ и положите его в переменную окружения.

  2. 02

    Укажите baseURL NormaHub и model ID из каталога в первом запросе.

  3. 03

    Вынесите вызовы в backend route и включите streaming с timeout перед продакшеном.

Рабочий шаблон

Скопируйте основу и замените модель

Используйте только идентификатор из актуального каталога. Ключ храните в переменной окружения.

TypeScript · первый запрос
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.NORMAHUB_API_KEY,
  baseURL: "https://api.normahub.cc/v1",
});

const response = await client.chat.completions.create({
  model: "MODEL_ID",
  messages: [{ role: "user", content: "Привет" }],
  max_tokens: 512,
});

console.log(response.choices[0].message.content);
Официальный openai-пакет — та же сигнатура create, те же choices.
Ключ живёт только на сервере: браузер ходит в ваш route, а не в API.
Streaming из коробки: интерфейс оживает без спиннера ожидания.

Детали решения

Как это устроено

Зачем Node.js-проекту единый API

Отдельного клиента NormaHub не существует — и это плюс: официальный openai-пакет работает как с оригиналом, отличие лишь в двух строках конфигурации. Модель переключается параметром model, поэтому GPT, Claude и остальные модели каталога пробуются без новых зависимостей. Прямые кабинеты провайдеров требуют зарубежные карты и упираются в региональные блокировки; здесь один ключ покрывает текстовые, кодовые и мультимодальные задачи, а endpoint доступен из России напрямую без VPN и с рублёвым балансом.

Сколько стоит запрос

Каждый вызов считается как входные токены плюс выходные по тарифу выбранной модели: длинные переписки и неограниченный max_tokens — два главных источника перерасхода. Ограничивайте длину ответа, обрезайте входные сообщения на границе вашего route и считайте стоимость полной операции, а не одного вызова. Точные ставки входа и выхода каждой модели — в каталоге, формула месячного бюджета — в гайде по стоимости токенов, а финальная сумма каждого запроса сохраняется в истории личного кабинета.

Нюансы и лимиты

Секретный ключ нельзя встраивать в клиентский JavaScript: его извлекут из bundle за минуту, поэтому браузерное приложение ходит в собственный backend route, а ключ добавляет уже сервер. Streaming — свойство конкретного endpoint и модели: если поток не поддержан, используйте обычный режим, а не бесконечные повторы. Ошибки делите на постоянные вроде 401, 402 и 403 и временные вроде 429 и 503 с повтором через backoff. Каждому запросу задавайте timeout и логируйте request ID вместо ключей и содержимого.

Оплата и контроль расходов

Запросы оплачиваются с предварительно пополненного баланса по актуальным ставкам выбранной модели. Минимум и комиссия показываются перед оплатой в кабинете; лимит расходов задаётся для API-ключа.

Ограничения доступности

Возможности зависят от модели и внешнего маршрута. При недоступности provider запрос может завершиться ошибкой; проверяйте каталог, статус и документацию перед production.

Частые вопросы

Какой baseURL указывать в Node.js-клиенте?

https://api.normahub.cc/v1 в параметре baseURL. Ключ SDK отправляет сам заголовком Authorization: Bearer — вручную собирать запросы не нужно.

Где хранить API-ключ?

В переменной окружения процесса, которую код читает через process.env.NORMAHUB_API_KEY. Не коммитьте .env в репозиторий и никогда не отдавайте ключ в браузерный bundle — только серверный route.

Как получать ответ по частям?

Передайте stream: true и читайте чанки через for await — токены уходят в интерфейс по мере генерации. Учтите: поток поддерживают не все модели и endpoint, проверяйте каталог.

Как обрабатывать ошибки запросов?

SDK бросает типизированные исключения: AuthenticationError для 401, RateLimitError для 429, APIError с полем status для остальных. Временные ошибки повторяйте с задержкой, постоянные чините по причине — таблица кодов в гайде по ошибкам.