TypeScript SDK
Официальная TypeScript/JavaScript-библиотека Nexara: транскрибация, диаризация, роли и LLM-анализ в несколько строк кода.
nexara-sdk — официальная TypeScript/JavaScript-библиотека для Nexara API. Она берёт на себя сборку запросов, разбор ответов в типизированные объекты, обработку ошибок и повторные попытки, а асинхронные задачи превращает в один вызов job.wait(). Библиотека полностью типизирована и поставляет собственные .d.ts, тип результата сужается автоматически по task и response_format. Требуется Node.js 20+.
npm install nexara-sdkСохраните API-ключ в переменной окружения NEXARA_API_KEY. SDK читает её автоматически при создании клиента, поэтому ключ не нужно указывать в коде — и он не попадёт в репозиторий:
export NEXARA_API_KEY=nx-...Команда export задаёт переменную только для текущей сессии терминала. Чтобы
ключ сохранялся между сессиями, добавьте эту строку в файл конфигурации вашей
оболочки (например, ~/.zshrc или ~/.bashrc). На сервере переменную удобнее
задавать через настройки окружения или менеджер секретов.
Быстрый старт
import { Nexara } from "nexara-sdk";
const client = new Nexara(); // ключ из переменной окружения NEXARA_API_KEY
const { text } = await client.transcriptions.create({ file: "audio.mp3" });
console.log(text);Клиент берёт ключ из NEXARA_API_KEY — той самой переменной, что вы задали выше, — поэтому в коде его указывать не нужно. Передать ключ явным полем apiKey тоже можно, но не храните его в коде и не коммитьте в репозиторий.
Клиент
const client = new Nexara({
// apiKey по умолчанию берётся из переменной окружения NEXARA_API_KEY,
// либо можете передать ключ сами: apiKey: "nx-..."
timeoutMs: 600_000, // таймаут запроса в миллисекундах
maxRetries: 2, // повторы при 429 и сетевых сбоях
});Клиент асинхронный целиком — отдельного синхронного варианта нет (в отличие от Nexara/AsyncNexara в Python SDK). Все методы возвращают промисы.
Транскрибация
Передайте ровно один из параметров: file (путь, Uint8Array или Blob) или url (прямая ссылка). Файл, переданный путём, стримится с диска и не загружается в память целиком.
// Локальный файл
const local = await client.transcriptions.create({ file: "audio.mp3" });
console.log(local.text);
// Файл по ссылке
const remote = await client.transcriptions.create({
url: "https://example.com/audio.mp3",
});
console.log(remote.text);Параметры те же, что и у API: model, language, response_format, timestamp_granularities, profanity_filter и другие. Тип результата сужается автоматически: text, srt и vtt возвращаются строкой, json и verbose_json — типизированными объектами:
import { writeFile } from "node:fs/promises";
const srt = await client.transcriptions.create({
file: "video.mp4",
response_format: "srt",
});
await writeFile("video.srt", srt);
const verbose = await client.transcriptions.create({
file: "audio.mp3",
response_format: "verbose_json",
timestamp_granularities: ["word"],
});
for (const word of verbose.words ?? []) {
console.log(`${word.start.toFixed(2)}–${word.end.toFixed(2)}: ${word.word}`);
}Диаризация и роли
Разделение по говорящим включается так же, как в API, — task: "diarize". Роли передаются обычным массивом или объектом: SDK сам сериализует их в JSON.
const call = await client.transcriptions.create({
file: "call.mp3",
task: "diarize",
num_speakers: 2,
roles: ["Оператор", "Клиент"], // или "auto", или { "Роль": "описание" }
});
for (const segment of call.segments) {
console.log(`${segment.speaker}: ${segment.text}`);
}Подробнее о режимах — на странице спикеры и роли.
Асинхронные задачи
Для длинных записей используйте асинхронный режим: createJob() ставит задачу и сразу возвращает объект Job, а job.wait() опрашивает статус и возвращает готовый результат.
const job = await client.transcriptions.createJob({
file: "long_recording.mp3",
});
console.log(job.job_id, job.status); // in_progress
const result = await job.wait(); // опрашивает статус; таймаут по умолчанию — 1_800_000 мс
console.log((result as { text: string }).text);Задачу можно забрать позже — в том числе из другого процесса:
const job = await client.transcriptions.retrieveJob(jobId);
if (job.status === "complete") {
console.log(job.result);
}Что важно знать:
- Результат хранится 12 часов с момента создания задачи, затем удаляется — после этого
retrieveJob()броситNotFoundError. - Одновременно на один ключ может выполняться до 200 задач.
- Если задача завершилась ошибкой,
wait()бросаетJobFailedError. Неудавшаяся задача не тарифицируется — повторная отправка бесплатна. - Если задача не успела за таймаут,
wait()бросаетJobTimeoutError; сама задача при этом не отменяется, её можно забрать позже черезretrieveJob().
LLM-анализ
Передайте prompt, чтобы прогнать расшифровку через языковую модель, и json_schema — чтобы получить структурированный ответ. Схема передаётся обычным объектом, а llm_output возвращается уже разобранным — никакого ручного JSON.parse.
const result = await client.transcriptions.create({
file: "meeting.mp3",
prompt: "Составь протокол встречи: резюме, решения и задачи.",
json_schema: {
type: "object",
properties: {
summary: { type: "string" },
decisions: { type: "array", items: { type: "string" } },
action_items: { type: "array", items: { type: "string" } },
},
required: ["summary", "decisions", "action_items"],
},
});
console.log(result.llm_output); // объект по вашей схеме
console.log(result.transcription.text); // расшифровка, из которой он полученБез json_schema поле llm_output — строка со свободным ответом модели.
Параллельные запросы
Клиент асинхронный целиком — «async» здесь означает промисы. Отдельного синхронного клиента нет, поэтому несколько запросов запускаются обычным Promise.all:
const urls = [
"https://example.com/a.mp3",
"https://example.com/b.mp3",
"https://example.com/c.mp3",
];
const results = await Promise.all(
urls.map((url) => client.transcriptions.create({ url })),
);
for (const result of results) {
console.log(result.text);
}Ошибки
Некорректные запросы (например, file и url одновременно, слишком много ролей) отклоняются на стороне клиента с NexaraValidationError — ещё до обращения к серверу. Ошибки сервера превращаются в типизированные классы по коду статуса:
| Класс | Код | Когда возникает |
|---|---|---|
BadRequestError | 400 | Некорректные параметры запроса |
InsufficientBalanceError | 402 | Недостаточно средств на балансе |
AuthenticationError | 403 | Ключ не передан или недействителен |
NotFoundError | 404 | Задача, модель или ключ не найдены |
RateLimitError | 429 | Превышен лимит частоты или число одновременных задач |
InternalServerError | 500 | Внутренняя ошибка сервера |
APIConnectionError | — | Запрос не дошёл до сервера (сеть, таймаут) |
Все они наследуются от NexaraError, а у ошибок API есть поля status_code и detail с сообщением сервера. Тип ошибки проверяется через instanceof. Полный список кодов — на странице ошибок.
import { Nexara, InsufficientBalanceError, RateLimitError } from "nexara-sdk";
const client = new Nexara();
try {
await client.transcriptions.create({ file: "audio.mp3" });
} catch (e) {
if (e instanceof InsufficientBalanceError) {
console.log("Пополните баланс:", e.detail); // 402
} else if (e instanceof RateLimitError) {
console.log("Слишком много запросов, попробуйте позже.");
} else {
throw e;
}
}Ссылки
- Пакет на npm: npmjs.com/package/nexara-sdk
- Справочник параметров API: референс API