# Node.js SDKの使い方

> @transcript1/sdkで、サーバーから動画リンクやローカルファイルを文字起こしします。テキスト・字幕の取得、進捗の監視、エラー処理を説明します。

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

TypeScriptやJavaScriptのサーバーから文字起こしするには、`@transcript1/sdk`を使います。ファイルのアップロードから完了待ち、文字起こしの取得までSDKで行えます。

SNSリンクには、SDKの1.1.0以降が必要です。1.0.1はYouTubeにしか対応しておらず、それ以外のリンクはAPIへの送信前にエラーになります。`npm i @transcript1/sdk@latest`で更新してください。

1.1.0では、YouTubeに加えてX、TikTok、Instagram、Facebook、Blueskyのリンクを扱えます。Twitch、Dailymotion、Pinterest、LinkedIn、Snapchatには、それぞれに対応したリリースを使ってください。古いSDKでは、リンクをAPIに送信する前に拒否することがあります。

## インストール

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

以下のコード例はESモジュールです。`.mjs`で保存するか、`package.json`に`"type": "module"`を設定して`.js`で保存してください。Node 20.19以降なら、`require('@transcript1/sdk')`のように`require()`でも読み込めます。

## 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`をスローします。エラーコードは`missing_api_key`です。

## 文字起こしを実行する

`transcribe(input, options)`は、ジョブを作成して完了まで待ちます。成功すると、`status: 'completed'`と`transcript`フィールドを持つ`CompletedTranscription`を返します。ジョブが失敗した場合やキャンセルされた場合、Promiseはrejectされます。

```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を渡すときは、`filename`も指定してください。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://`で始まればリンク、それ以外ならファイルパスとして扱います。YouTube、X、TikTok、Instagram、Facebook、Bluesky、Twitch、Dailymotion、Pinterest、LinkedIn、Snapchatのリンクに対応しています。追加対応したソースではHTTPSが必要です。文字起こしできる公開動画、字幕の対応状況、利用条件は[対応ソースとオプション](https://transcript1.com/ja/docs/sources-and-options)で確認してください。ファイルもアップロードできます。上限は2,000,000,000バイトで、拡張子はmp3、wav、m4a、flac、ogg、opus、mp4、mov、webm、mkvに対応しています。

SNSのリンクには公開投稿のURLを使ってください。動画が複数ある投稿では、最初の動画だけを文字起こしします。APIがリンクからプラットフォームを判定するため、手動での指定は不要です。短縮リンクの対応状況や制限は[対応ソースとオプション](https://transcript1.com/ja/docs/sources-and-options)を参照してください。

Blob、`ReadableStream<Uint8Array>`、Uint8Arrayのチャンクを返す非同期イテラブルも使えます。Blobには`filename`が必要ですが、名前を持つFileなら省略できます。ストリームと非同期イテラブルでは、`filename`に加えてバイト単位の`size`も指定してください。

## テキストや字幕をダウンロードする

`download(id, options)`で文字起こしを取得できます。処理中なら完了まで待ち、文字列で返します。JSONを選んだ場合も、パース済みのオブジェクトではなく、APIが返したJSON文字列です。

```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`でPromiseはrejectされます。対象のジョブが失敗した場合やキャンセルされた場合も、`download`のPromiseはrejectされます。

## 完了を待たずにジョブを作成する

`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: true`を付けると、`completed`、`failed`、`canceled`のいずれかになるまで待ちます。`transcribe`と違い、ジョブの失敗やキャンセルを理由にPromiseがrejectされることはありません。本文を読む前に、`finished.status`を確認してください。

## ジョブの一覧・削除とアカウントの確認

```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`で絞り込めます。`platform`の値は`youtube`、`x`、`tiktok`、`instagram`、`facebook`、`bluesky`、`twitch`、`dailymotion`、`pinterest`、`linkedin`、`snapchat`、`upload`です。`limit`は1ページの件数で、1〜100を指定できます。APIのデフォルトは20件です。レスポンスのフィールド名は、APIと同じ`snake_case`のままです。`media_id`は内部の形式を解釈せず、受け取った文字列のまま扱ってください。

`delete`は、処理中のジョブならキャンセルし、終了済みならジョブと文字起こしを削除します。`account`でプラン、残りの分数、利用上限を取得できます。

## オプション

インスタンスの作成時に、`apiKey`、`baseUrl`、`fetch`、`maxRetries`を指定できます。`baseUrl`を省略すると、環境変数`TRANSCRIPT1_API_URL`の値を使います。環境変数もなければ`https://api.transcript1.com`に接続します。独自のfetch実装を使うには`fetch`で渡してください。`maxRetries`は0〜10の整数で、デフォルトは2です。

`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` | 省略すると、呼び出すたびに新しい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` | 追加フィールドはありません。完了待ちの接続が途切れるたびに、1回だけ通知します。 |

## 呼び出しを中断する

呼び出しを途中で止めるには、AbortControllerから取得したAbortSignalを渡してください。時間で打ち切る場合は`AbortSignal.timeout`を使います。

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

最初のリクエストを送る前に中断した場合、Promiseは`aborted`でrejectされ、ジョブIDはありません。アップロード中に中断した場合は、SDKが`awaiting_upload`のジョブの削除を試みます。その後、ジョブIDを含む`aborted`エラーでPromiseはrejectされます。

完了待ちを中断しても、サーバー上のジョブは止まりません。エラーの`transcriptionId`を使い、`transcriptions.get(id, { wait: true })`で再び完了を待てます。ジョブそのものをキャンセルするには、`transcriptions.delete(id)`を呼び出してください。

完了待ちの間は、ネットワークエラーとHTTPの429、500、502、503、504を回数制限なしで再試行します。再接続までの待ち時間は2秒、4秒、8秒、16秒と延び、以降は30秒です。それ以外のリクエストには`maxRetries`を適用します。ジョブの作成時に同時処理枠が埋まっている場合も、空きを待って再試行します。待ち時間全体を制限したい場合は、`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ステータスです。ジョブの失敗やSDK内のエラーでは付きません。 |
| `details` | `minutes_needed`や`action_url`など、APIエラーの補足情報です。デフォルトは空のオブジェクトです。 |
| `retryable` | 再試行で成功する可能性があれば`true`です。デフォルトは`false`です。 |
| `transcriptionId` | 取得できている場合は、ジョブIDが入ります。 |
| `transcription` | 取得できている場合は、最後に受け取った文字起こしオブジェクトが入ります。 |

SDK側のエラーコードは、`missing_api_key`、`invalid_input`、`aborted`、`network_error`、`upload_token_refused`です。JSON以外のエラーレスポンスを受け取った場合は、`http_<status>`になります。

失敗したジョブにエラーオブジェクトがない場合は、`transcription_failed`になります。完了済みのジョブを取得したのに本文がない場合、`transcribe`のPromiseは`internal_error`でrejectされます。APIのエラーコードは[エラー](https://transcript1.com/ja/docs/errors)、レスポンスの各フィールドは[APIリファレンス](https://transcript1.com/ja/docs/api-reference)を参照してください。

## 動作環境

Node 20.19以降が必要です。BunやDenoでも`node:`互換機能での動作を想定していますが、自動テストはNodeでのみ実行しています。SDKはサーバー側で使ってください。APIキーをブラウザーに渡してはいけません。
