# SDK для Node.js

> Подключите @transcript1/sdk к серверному коду. Отправляйте ссылки и файлы, получайте текст и субтитры, следите за прогрессом и обрабатывайте ошибки.

Canonical: https://transcript1.com/ru/docs/sdk
Language: ru
Last updated: 2026-10-16

Пакет `@transcript1/sdk` берёт на себя загрузку файлов, создание задач и ожидание готового текста. Используйте его в серверном коде на TypeScript или JavaScript.

Ссылки из соцсетей поддерживаются начиная с SDK 1.1.0. В версии 1.0.1 работает только YouTube; другие ссылки SDK отклонит до обращения к API. Для обновления выполните `npm i @transcript1/sdk@latest`.

Версия 1.1.0 — минимальная для первых шести платформ. Для Twitch, Dailymotion, Pinterest, LinkedIn и Snapchat нужен релиз, в который уже добавлена соответствующая платформа. Старый SDK может отклонить такую ссылку, не отправляя запрос к API.

## Установка

```bash
npm i @transcript1/sdk
```

Примеры написаны для ES-модулей: сохраните код в `.mjs` или добавьте `"type": "module"` в `package.json`, если используете `.js`. На Node 20.19+ можно также подключить пакет через `require()`: `require('@transcript1/sdk')`.

## API-ключ

Получите ключ на странице [«API keys»](https://transcript1.com/dashboard/account/tokens). Дальше либо задайте на сервере переменную `TRANSCRIPT1_API_KEY`, либо передайте ключ в конструктор через `apiKey`:

```javascript
import { Transcript1 } from '@transcript1/sdk';

const t1 = new Transcript1(); // reads TRANSCRIPT1_API_KEY
const other = new Transcript1({ apiKey: 't1_...' });
```

Если ключа нет, конструктор выбросит `Transcript1Error` с `code=missing_api_key`.

## Как получить транскрипт

Вызовите `transcribe(input, options)`, чтобы создать задачу и дождаться текста. При успехе вы получите `CompletedTranscription`: `status: 'completed'` и поле `transcript`. Если задача завершилась с ошибкой или её отменили, промис отклоняется.

```javascript
const done = await t1.transcribe('https://youtu.be/dQw4w9WgXcQ');
console.log(done.transcript.text);

const file = await t1.transcribe('./interview.m4a', { speakers: true });
```

При передаче Buffer или Uint8Array обязательно укажите имя файла. По нему SDK определяет формат записи:

```javascript
import { readFile } from 'node:fs/promises';

const buffer = await readFile('./call.mp3');
const call = await t1.transcribe(buffer, { filename: 'call.mp3' });
```

Если строка начинается с `http://` или `https://`, SDK примет её за ссылку. Любая другая строка — путь к файлу. Поддерживаются YouTube, X, TikTok, Instagram, Facebook, Bluesky, Twitch, Dailymotion, Pinterest, LinkedIn, Snapchat и загрузка своих файлов. Для дополнительных платформ нужен HTTPS. Форматы ссылок на публичные записи, поддержка субтитров и ограничения описаны в разделе [«Источники и параметры»](https://transcript1.com/ru/docs/sources-and-options).

Размер файла — до 2 000 000 000 байт. Допустимые расширения: mp3, wav, m4a, flac, ogg, opus, mp4, mov, webm и mkv.

Нужен публичный пост. Если в нём несколько роликов, расшифруем первый. Платформу определит API по ссылке; подходящие короткие ссылки перечислены в разделе [«Источники и параметры»](https://transcript1.com/ru/docs/sources-and-options).

Можно передать и Blob, `ReadableStream<Uint8Array>` или асинхронный итерируемый объект, который выдаёт части Uint8Array. Для Blob укажите `filename`; исключение — File, у которого уже есть имя. Для потоков и асинхронных итерируемых объектов обязательны оба поля: `filename` и `size` в байтах.

## Текст и файлы субтитров

Чтобы получить нужный формат, вызовите `download(id, options)`. Метод дождётся завершения задачи и вернёт строку. Для JSON это тоже строка с ответом API, а не готовый объект.

```javascript
const text = await t1.download(done.id); // text is the default
const withTimes = await t1.download(done.id, { timestamps: true });
const srt = await t1.download(done.id, { format: 'srt' });
const vtt = await t1.download(done.id, { format: 'vtt' });
const json = await t1.download(done.id, { format: 'json' });
```

Параметр `timestamps: true` доступен только для `text`. С другим форматом промис отклоняется с `invalid_input`. Ошибка или отмена задачи также приводит к отклонению промиса `download`.

## Запуск без ожидания транскрипта

Если текст пока не нужен, создайте задачу через `transcriptions.create`. Метод не ждёт транскрипта, но для файла сначала полностью завершает загрузку.

```javascript
const job = await t1.transcriptions.create('./long-interview.mp4');
const now = await t1.transcriptions.get(job.id);
const finished = await t1.transcriptions.get(job.id, { wait: true });
```

Вызов `get` без `wait` сразу вернёт текущее состояние. С `wait: true` он подождёт статуса `completed`, `failed` или `canceled`. Прежде чем обращаться к тексту, проверьте `finished.status`: в отличие от `transcribe`, промис `get` не отклоняется при ошибке или отмене самой задачи.

## Список задач, удаление и баланс

```javascript
for await (const item of t1.transcriptions.list({ status: 'completed', limit: 50 })) {
  console.log(item.id, item.created_at);
}

await t1.transcriptions.delete(job.id);
const account = await t1.account();
console.log(account.minutes.remaining);
```

Метод `list` сам запрашивает следующую страницу по мере обхода списка. Можно фильтровать задачи по `status` и `platform`: `youtube`, `x`, `tiktok`, `instagram`, `facebook`, `bluesky`, `twitch`, `dailymotion`, `pinterest`, `linkedin`, `snapchat` или `upload`. Размер страницы задаёт `limit` — от 1 до 100, по умолчанию в API 20. Поля в объектах сохраняют исходные имена API в `snake_case`. Значение `media_id` храните как есть, не пытаясь разобрать строку.

Через `delete` можно отменить текущую задачу или удалить завершённую вместе с текстом. Метод `account` покажет тариф, остаток минут и лимиты.

## Параметры

В конструктор можно передать `apiKey`, `baseUrl`, `fetch` и `maxRetries`. Если `baseUrl` не указан, SDK возьмёт адрес из `TRANSCRIPT1_API_URL`, а при отсутствии переменной — `https://api.transcript1.com`. Для своей реализации запросов передайте `fetch`. Число повторов `maxRetries` по умолчанию равно 2; допустимы целые значения от 0 до 10.

Для `transcribe` и `transcriptions.create` доступны одинаковые параметры:

| Параметр | Для чего нужен |
|---|---|
| `speakers` | Включает определение говорящих. |
| `language` | Выбирает язык: `auto` по умолчанию или код ISO 639-1. |
| `source` | Для ссылок — `auto` или `stt`. YouTube, X, TikTok, Bluesky, Dailymotion и LinkedIn также принимают `captions`, если доступна подходящая дорожка. |
| `fresh` | Создаёт новую транскрибацию по ссылке, не используя прежнюю за последние 24 часа. |
| `filename` | Задаёт или заменяет имя файла. Обязателен для Buffer, Blob без имени и потоков. |
| `size` | Задаёт размер в байтах. Обязателен для потоков и асинхронных итерируемых объектов. |
| `idempotencyKey` | Ключ идемпотентности. Если не задан, SDK создаёт новый UUID для каждого вызова. |
| `onProgress` | Обработчик событий прогресса. |
| `signal` | Передаёт AbortSignal для отмены вызова. |

Метод `transcriptions.get` принимает `wait`, `includeWords`, `onProgress` и `signal`. Для пословных временных меток передайте `includeWords: true`. Обработчик `onProgress` будет сообщать об изменениях, пока метод ждёт завершения.

У `download` есть `format`, `timestamps` и `signal`; у `list` также можно указать `signal`. Для `transcriptions.delete(id, options)` и `account(options)` передайте `{ signal }` в аргументе параметров.

## Как следить за прогрессом

Добавьте обработчик `onProgress` в `transcribe`, `transcriptions.create` или `transcriptions.get` с ожиданием:

```javascript
await t1.transcribe('./interview.m4a', {
  onProgress(event) {
    console.log(event);
  },
});
```

| Событие | Что приходит |
|---|---|
| `upload` | `sent` — отправлено байт, `total` — всего байт. |
| `status` | Текущий статус задачи в поле `status`. |
| `waiting_slot` | `retryAfter` — сколько секунд до следующей попытки занять место для задачи. |
| `reconnecting` | Событие без дополнительных полей. Приходит один раз на каждый обрыв соединения во время ожидания. |

## Как отменить вызов

Для отмены используйте `AbortSignal` из AbortController. Если нужен таймаут, подойдёт `AbortSignal.timeout`:

```javascript
await t1.transcribe('https://youtu.be/dQw4w9WgXcQ', {
  signal: AbortSignal.timeout(10 * 60_000),
});
```

При отмене до первого запроса промис отклоняется с `aborted`, без ID задачи. Если отменить вызов во время загрузки, SDK попытается удалить задачу, пока она ещё в `awaiting_upload`. После этого промис отклоняется с `aborted` и ID.

Отмена ожидания не останавливает транскрибацию. Чтобы снова дождаться текста, возьмите `transcriptionId` из ошибки и вызовите `transcriptions.get(id, { wait: true })`. Если нужно остановить саму задачу, используйте `transcriptions.delete(id)`.

Во время ожидания SDK повторяет запросы при сетевых ошибках и HTTP 429, 500, 502, 503, 504 без ограничения числа попыток. Паузы растут: 2, 4, 8, 16, затем 30 секунд. Для остальных запросов действует `maxRetries`. Если при создании задачи все места заняты, SDK тоже подождёт и попробует снова. Ограничить общее время вызова можно через `signal`.

## Ошибки

Ошибки API, транскрибации и самого SDK доступны через `Transcript1Error`:

```javascript
import { Transcript1Error } from '@transcript1/sdk';

try {
  await t1.transcribe('./call.mp3');
} catch (error) {
  if (error instanceof Transcript1Error) {
    console.error(error.code, error.message, error.transcriptionId);
  }
}
```

| Поле | Что содержит |
|---|---|
| `message` | Сообщение с описанием проблемы. |
| `code` | Код ошибки API, ошибки задачи, `canceled` или локальной ошибки SDK. |
| `status` | HTTP-код. У ошибок задач и локальных ошибок этого поля нет. |
| `details` | Дополнительные данные API: например, `minutes_needed` или `action_url`. По умолчанию — пустой объект. |
| `retryable` | Есть ли смысл повторить попытку. По умолчанию — `false`. |
| `transcriptionId` | ID задачи, если SDK успел его получить. |
| `transcription` | Последнее известное состояние объекта транскрибации. |

Собственные коды SDK: `missing_api_key`, `invalid_input`, `aborted`, `network_error` и `upload_token_refused`. Если сервер вернул ошибку не в JSON, код будет `http_<status>`.

Если задача завершилась с ошибкой, но без объекта `error`, SDK использует `transcription_failed`. Если задача завершилась успешно, а после запроса текста поле транскрипта так и не появилось, промис `transcribe` отклоняется с `internal_error`. Коды API разобраны в разделе [«Ошибки»](https://transcript1.com/ru/docs/errors), поля ответов — в [справочнике API](https://transcript1.com/ru/docs/api-reference).

## Где работает SDK

Нужен Node 20.19+. Bun и Deno должны работать благодаря совместимости с `node:`, но автоматические тесты мы запускаем только на Node. SDK предназначен для сервера. Не включайте API-ключ в браузерный код.
