@transcribe-api/sdk 0.1.3 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +389 -54
- package/index.js +1143 -1354
- package/package.json +1 -1
- package/worker.js +543 -296
package/README.md
CHANGED
|
@@ -1,75 +1,410 @@
|
|
|
1
|
-
# Transcribe API JavaScript SDK
|
|
2
|
-
|
|
3
|
-
Official JavaScript SDK for Transcribe API.
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
1
|
+
# Transcribe API JavaScript SDK
|
|
2
|
+
|
|
3
|
+
Official JavaScript SDK for Transcribe API.
|
|
4
|
+
|
|
5
|
+
Use this SDK to send one file, many files, local uploads, remote audio URLs, webhook jobs, and large multipart uploads to the Transcribe API from Node.js and modern JavaScript runtimes.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @transcribe-api/sdk
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Import
|
|
14
|
+
|
|
15
|
+
```js
|
|
16
|
+
import { TranscribeAPI, TranscribeAPIError } from "@transcribe-api/sdk";
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
The default export is also `TranscribeAPI`:
|
|
20
|
+
|
|
21
|
+
```js
|
|
22
|
+
import TranscribeAPI from "@transcribe-api/sdk";
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Quick start
|
|
26
|
+
|
|
13
27
|
```js
|
|
14
28
|
import { TranscribeAPI } from "@transcribe-api/sdk";
|
|
15
|
-
|
|
29
|
+
|
|
30
|
+
const client = new TranscribeAPI({
|
|
31
|
+
apiKey: process.env.TRANSCRIBE_API_KEY,
|
|
32
|
+
polling: {
|
|
33
|
+
interval: 10,
|
|
34
|
+
timeout: 15 * 60,
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const result = await client.transcribe({
|
|
39
|
+
language: "en",
|
|
40
|
+
files: [
|
|
41
|
+
{ reference_id: "meeting_001", file: "./meeting.mp3" },
|
|
42
|
+
],
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
console.log(result);
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
`client.transcribe({ files: [...] })` is the main API for both single-file and multi-file transcription.
|
|
49
|
+
|
|
50
|
+
## How `transcribe` routes work
|
|
51
|
+
|
|
52
|
+
The SDK automatically chooses the right API flow:
|
|
53
|
+
|
|
54
|
+
- One small local file is sent through the direct synchronous upload path.
|
|
55
|
+
- Remote URLs, webhook jobs, multiple files, files larger than 30 MB, and files estimated over 10 minutes are sent through the async job flow.
|
|
56
|
+
- Large local async uploads use signed R2 upload URLs returned by the API.
|
|
57
|
+
- Multipart upload is used automatically when the backend returns multipart upload instructions.
|
|
58
|
+
- If `polling` is configured, async calls wait until the job reaches a terminal status.
|
|
59
|
+
- If `polling` is not configured, async calls return the upload-completion/job response. Use `client.jobs.get(job_id)` or `client.waitForJobCompletion(job_id, ...)` to check later.
|
|
60
|
+
|
|
61
|
+
Terminal job statuses are `completed`, `failed`, and `insufficient_funds`. Completed job responses include `result_url` when the API has a result file ready.
|
|
62
|
+
|
|
63
|
+
## Client options
|
|
64
|
+
|
|
65
|
+
```js
|
|
16
66
|
const client = new TranscribeAPI({
|
|
17
67
|
apiKey: "YOUR_API_KEY",
|
|
68
|
+
baseUrl: "https://api.transcribeapi.com/v1",
|
|
69
|
+
uploadConcurrency: 4,
|
|
18
70
|
showLogs: true,
|
|
71
|
+
logger: console,
|
|
19
72
|
polling: {
|
|
20
73
|
interval: 10,
|
|
21
74
|
timeout: 15 * 60,
|
|
22
75
|
},
|
|
23
76
|
});
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
| Option | Description |
|
|
80
|
+
| --- | --- |
|
|
81
|
+
| `apiKey` | Required. Your Transcribe API key. |
|
|
82
|
+
| `baseUrl` | Optional. Defaults to `https://api.transcribeapi.com/v1`. |
|
|
83
|
+
| `uploadConcurrency` | Optional. Number of in-flight upload PUTs. Defaults to `1` and is capped at `32`. |
|
|
84
|
+
| `showLogs` | Optional. Prints upload progress, upload completion, polling status, and final result info. |
|
|
85
|
+
| `logger` | Optional. Logger object with a `log` method. Defaults to `console`. |
|
|
86
|
+
| `polling` | Optional. `{ interval, timeout }` in seconds. `interval` must be at least `10`. Omit or set to `null`/`false` to disable automatic polling. |
|
|
87
|
+
|
|
88
|
+
## File inputs
|
|
89
|
+
|
|
90
|
+
Each item in `files` must be an object with either `file` or `url`:
|
|
91
|
+
|
|
92
|
+
```js
|
|
93
|
+
{ reference_id: "episode_1", file: "./episode.mp3" }
|
|
94
|
+
{ reference_id: "episode_2", url: "https://example.com/signed-audio-url.mp3" }
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Supported local/upload inputs:
|
|
98
|
+
|
|
99
|
+
- Node.js local file path strings, such as `"./audio.mp3"`.
|
|
100
|
+
- `File` objects.
|
|
101
|
+
- `Blob` objects.
|
|
102
|
+
- `{ data, name, type }`, where `data` is a `Uint8Array` or `ArrayBuffer`.
|
|
103
|
+
|
|
104
|
+
Supported remote inputs:
|
|
105
|
+
|
|
106
|
+
- Public or signed URLs using `{ url: "https://..." }`.
|
|
107
|
+
|
|
108
|
+
Do not include both `file` and `url` in the same item.
|
|
109
|
+
|
|
110
|
+
## Single local file
|
|
111
|
+
|
|
112
|
+
```js
|
|
113
|
+
const result = await client.transcribe({
|
|
114
|
+
files: [
|
|
115
|
+
{ reference_id: "call_001", file: "./call.mp3" },
|
|
116
|
+
],
|
|
117
|
+
language: "en",
|
|
118
|
+
});
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
For one small local file, this usually uses the direct upload path. Larger files automatically become async jobs.
|
|
122
|
+
|
|
123
|
+
## Remote URL transcription
|
|
124
|
+
|
|
125
|
+
```js
|
|
126
|
+
const job = await client.transcribe({
|
|
35
127
|
files: [
|
|
36
|
-
{ reference_id: "
|
|
37
|
-
{ reference_id: "episode_2", file: "b.wav" },
|
|
128
|
+
{ reference_id: "remote_001", url: "https://example.com/audio.mp3" },
|
|
38
129
|
],
|
|
130
|
+
language: "en",
|
|
39
131
|
});
|
|
132
|
+
```
|
|
40
133
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
{ reference_id: "episode_1", file: "local.mp3" },
|
|
55
|
-
{ reference_id: "episode_2", url: "https://signed-get-url-2" },
|
|
56
|
-
],
|
|
134
|
+
Remote URL jobs are async because the API fetches the audio from the URL.
|
|
135
|
+
|
|
136
|
+
## Batch and mixed input transcription
|
|
137
|
+
|
|
138
|
+
```js
|
|
139
|
+
const job = await client.transcribe({
|
|
140
|
+
language: "en",
|
|
141
|
+
uploadConcurrency: 8,
|
|
142
|
+
files: [
|
|
143
|
+
{ reference_id: "episode_1", file: "./episode-1.mp3" },
|
|
144
|
+
{ reference_id: "episode_2", file: "./episode-2.wav" },
|
|
145
|
+
{ reference_id: "episode_3", url: "https://example.com/episode-3.m4a" },
|
|
146
|
+
],
|
|
57
147
|
});
|
|
58
148
|
```
|
|
59
149
|
|
|
60
|
-
|
|
150
|
+
Local files and remote URLs can be mixed in the same batch. When sending multiple files through `transcribe`, provide a unique `reference_id` for every item.
|
|
151
|
+
|
|
152
|
+
## Per-file language
|
|
153
|
+
|
|
154
|
+
Set `language` at the top level to apply a default to the whole job. Set `language` on a file item to override the default for that file.
|
|
155
|
+
|
|
156
|
+
```js
|
|
157
|
+
const job = await client.transcribe({
|
|
158
|
+
language: "en",
|
|
159
|
+
files: [
|
|
160
|
+
{ reference_id: "intro", file: "./intro.mp3" },
|
|
161
|
+
{ reference_id: "french_segment", file: "./segment.m4a", language: "fr" },
|
|
162
|
+
],
|
|
163
|
+
});
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
`language` must be a two-letter language code such as `en`, `fr`, or `es`. Omit it, pass an empty value, or pass `"auto"` to avoid sending an explicit language.
|
|
167
|
+
|
|
168
|
+
## Excluding outputs or features
|
|
169
|
+
|
|
170
|
+
Use `exclude` to pass API exclusions. Arrays are joined with commas before sending. Valid values are only `vtt`, `segments`, `metadata`, `billing`, and `detected_language`.
|
|
171
|
+
|
|
172
|
+
```js
|
|
173
|
+
const result = await client.transcribe({
|
|
174
|
+
files: [
|
|
175
|
+
{ reference_id: "meeting", file: "./meeting.mp3" },
|
|
176
|
+
],
|
|
177
|
+
exclude: ["vtt", "segments"],
|
|
178
|
+
});
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
You can also pass a comma-separated string:
|
|
182
|
+
|
|
183
|
+
```js
|
|
184
|
+
exclude: "metadata,billing"
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## Webhooks
|
|
188
|
+
|
|
189
|
+
```js
|
|
190
|
+
const job = await client.transcribe({
|
|
191
|
+
webhookUrl: "https://example.com/transcribe-webhook",
|
|
192
|
+
files: [
|
|
193
|
+
{ reference_id: "upload_001", file: "./long-audio.mp3" },
|
|
194
|
+
],
|
|
195
|
+
});
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Any request with `webhookUrl` uses the async job flow.
|
|
199
|
+
|
|
200
|
+
## Progress and logs
|
|
201
|
+
|
|
202
|
+
Use `onProgress` to receive structured progress events:
|
|
203
|
+
|
|
204
|
+
```js
|
|
205
|
+
const job = await client.transcribe({
|
|
206
|
+
files: [
|
|
207
|
+
{ reference_id: "episode_1", file: "./episode-1.mp3" },
|
|
208
|
+
{ reference_id: "episode_2", file: "./episode-2.mp3" },
|
|
209
|
+
],
|
|
210
|
+
uploadConcurrency: 4,
|
|
211
|
+
onProgress(event) {
|
|
212
|
+
console.log(event);
|
|
213
|
+
},
|
|
214
|
+
});
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
Common event names:
|
|
218
|
+
|
|
219
|
+
- `upload_urls_received`
|
|
220
|
+
- `upload_started`
|
|
221
|
+
- `upload_progress`
|
|
222
|
+
- `upload_completed`
|
|
223
|
+
|
|
224
|
+
Progress events may include `jobId`, `jobStatus`, `referenceId`, `loaded`, `total`, `fileLoaded`, `fileTotal`, `batchLoaded`, `batchTotal`, `uploadType`, `partNumber`, `totalParts`, and `multipartConcurrency`.
|
|
225
|
+
|
|
226
|
+
Set `showLogs: true` on the client or on a single call to print built-in progress and polling logs:
|
|
227
|
+
|
|
228
|
+
```js
|
|
229
|
+
const client = new TranscribeAPI({
|
|
230
|
+
apiKey: process.env.TRANSCRIBE_API_KEY,
|
|
231
|
+
showLogs: true,
|
|
232
|
+
});
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
## Manual async jobs
|
|
236
|
+
|
|
237
|
+
`transcribe` uploads automatically. Use `createBatchJob` when you want to separate job creation from upload.
|
|
238
|
+
|
|
239
|
+
```js
|
|
240
|
+
const job = await client.createBatchJob({
|
|
241
|
+
language: "en",
|
|
242
|
+
files: [
|
|
243
|
+
{ reference_id: "part_1", file: "./part-1.mp3" },
|
|
244
|
+
{ reference_id: "part_2", url: "https://example.com/part-2.mp3" },
|
|
245
|
+
],
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
console.log(job.jobId);
|
|
249
|
+
|
|
250
|
+
const completion = await job.upload();
|
|
251
|
+
console.log(completion);
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
For a single large local file, you can also use `createBigFileJob`:
|
|
255
|
+
|
|
256
|
+
```js
|
|
257
|
+
const job = await client.createBigFileJob({
|
|
258
|
+
file: { reference_id: "large_001", file: "./large.wav" },
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
const completion = await job.upload();
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
## Job helpers
|
|
265
|
+
|
|
266
|
+
```js
|
|
267
|
+
const job = await client.jobs.get("job_id_here");
|
|
268
|
+
const sameJob = await client.jobs.result("job_id_here");
|
|
269
|
+
|
|
270
|
+
const finalJob = await client.waitForJobCompletion("job_id_here", {
|
|
271
|
+
polling: { interval: 10, timeout: 15 * 60 },
|
|
272
|
+
});
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
Available job helpers:
|
|
276
|
+
|
|
277
|
+
| Method | Description |
|
|
278
|
+
| --- | --- |
|
|
279
|
+
| `client.jobs.get(jobId)` | Fetches `GET /v1/transcribe/{job_id}`. |
|
|
280
|
+
| `client.jobs.result(jobId)` | Alias for `jobs.get`. |
|
|
281
|
+
| `client.jobs.uploadCompleted(jobId)` | Calls `POST /v1/transcribe/{job_id}/upload-completed`. |
|
|
282
|
+
| `client.jobs.complete(jobId)` | Alias for `jobs.uploadCompleted`. |
|
|
283
|
+
| `client.jobs.createBatch(options)` | Creates a batch job and returns a `BatchJob`. |
|
|
284
|
+
| `client.jobs.createBigFile(options)` | Creates a one-file async upload job and returns a `BatchJob`. |
|
|
285
|
+
| `client.waitForJobCompletion(jobId, options)` | Polls until a terminal job status or timeout. |
|
|
286
|
+
|
|
287
|
+
## Limits and validation
|
|
288
|
+
|
|
289
|
+
- Batch jobs support up to `10,000` files.
|
|
290
|
+
- Batch local upload payloads support up to `10 GB` total local file size.
|
|
291
|
+
- Direct sync routing is used only for one local file up to `30 MB` and about `10 minutes`.
|
|
292
|
+
- Multipart upload starts when the backend returns multipart upload instructions. The SDK sends `size_bytes` for local files at least `128 MB` so the backend can choose multipart.
|
|
293
|
+
- `uploadConcurrency` defaults to `1` and is capped at `32`.
|
|
294
|
+
- `polling.interval` must be at least `10` seconds.
|
|
295
|
+
- Batch local uploads support `mp3`, `mpeg`, `mpga`, `m4a`, `wav`, and `webm`.
|
|
296
|
+
- `.mp4` is not supported.
|
|
297
|
+
|
|
298
|
+
## Error handling
|
|
299
|
+
|
|
300
|
+
```js
|
|
301
|
+
try {
|
|
302
|
+
const result = await client.transcribe({
|
|
303
|
+
files: [
|
|
304
|
+
{ reference_id: "bad_file", file: "./missing.mp3" },
|
|
305
|
+
],
|
|
306
|
+
});
|
|
307
|
+
console.log(result);
|
|
308
|
+
} catch (error) {
|
|
309
|
+
if (error instanceof TranscribeAPIError) {
|
|
310
|
+
console.error(error.message);
|
|
311
|
+
console.error(error.code);
|
|
312
|
+
console.error(error.status);
|
|
313
|
+
console.error(error.response);
|
|
314
|
+
console.error(error.toJSON());
|
|
315
|
+
} else {
|
|
316
|
+
throw error;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
`TranscribeAPIError` includes `message`, `code`, `status`, `response`, and any extra fields returned by the API or generated by the SDK.
|
|
322
|
+
|
|
323
|
+
## Cloudflare Workers and web runtimes
|
|
324
|
+
|
|
325
|
+
Use the Worker entrypoint when running in Cloudflare Workers or other web-standard runtimes:
|
|
326
|
+
|
|
327
|
+
```js
|
|
328
|
+
import { TranscribeAPI, TranscribeAPIError } from "@transcribe-api/sdk/worker";
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
The Worker entrypoint keeps the same public client API, but these runtimes do not support Node local file path strings such as `"./audio.mp3"`.
|
|
332
|
+
|
|
333
|
+
Supported Worker-safe inputs:
|
|
334
|
+
|
|
335
|
+
- `File` objects, such as files from `request.formData()`.
|
|
336
|
+
- `Blob` objects.
|
|
337
|
+
- `{ data, name, type }`, where `data` is a `Uint8Array` or `ArrayBuffer`.
|
|
338
|
+
- Remote URLs using `{ url: "https://..." }`.
|
|
339
|
+
|
|
340
|
+
Not supported in Worker runtimes:
|
|
341
|
+
|
|
342
|
+
- Local file path strings.
|
|
343
|
+
- Node.js streams.
|
|
344
|
+
- Node-only filesystem APIs.
|
|
345
|
+
|
|
346
|
+
## Cloudflare Worker quick start
|
|
61
347
|
|
|
62
348
|
```js
|
|
63
349
|
import { TranscribeAPI } from "@transcribe-api/sdk/worker";
|
|
350
|
+
|
|
351
|
+
export default {
|
|
352
|
+
async fetch(request, env) {
|
|
353
|
+
const client = new TranscribeAPI({
|
|
354
|
+
apiKey: env.TRANSCRIBE_API_KEY,
|
|
355
|
+
polling: {
|
|
356
|
+
interval: 10,
|
|
357
|
+
timeout: 15 * 60,
|
|
358
|
+
},
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
const result = await client.transcribe({
|
|
362
|
+
language: "en",
|
|
363
|
+
files: [
|
|
364
|
+
{
|
|
365
|
+
reference_id: "sample_001",
|
|
366
|
+
url: "https://example.com/audio.mp3",
|
|
367
|
+
},
|
|
368
|
+
],
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
return Response.json(result);
|
|
372
|
+
},
|
|
373
|
+
};
|
|
64
374
|
```
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
375
|
+
|
|
376
|
+
## Uploading a request file in a Worker
|
|
377
|
+
|
|
378
|
+
```js
|
|
379
|
+
import { TranscribeAPI } from "@transcribe-api/sdk/worker";
|
|
380
|
+
|
|
381
|
+
export default {
|
|
382
|
+
async fetch(request, env) {
|
|
383
|
+
const form = await request.formData();
|
|
384
|
+
const audio = form.get("file");
|
|
385
|
+
|
|
386
|
+
if (!(audio instanceof File)) {
|
|
387
|
+
return Response.json({ error: "Missing file" }, { status: 400 });
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
const client = new TranscribeAPI({
|
|
391
|
+
apiKey: env.TRANSCRIBE_API_KEY,
|
|
392
|
+
polling: {
|
|
393
|
+
interval: 10,
|
|
394
|
+
timeout: 15 * 60,
|
|
395
|
+
},
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
const result = await client.transcribe({
|
|
399
|
+
language: "en",
|
|
400
|
+
files: [
|
|
401
|
+
{ reference_id: "upload_001", file: audio },
|
|
402
|
+
],
|
|
403
|
+
});
|
|
404
|
+
|
|
405
|
+
return Response.json(result);
|
|
406
|
+
},
|
|
407
|
+
};
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
Remote URL transcription is usually the best fit for Workers when audio is already stored in R2, S3, or another storage service.
|