@transcribe-api/sdk 0.1.7 → 0.1.8

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.
Files changed (4) hide show
  1. package/README.md +51 -0
  2. package/index.js +118 -12
  3. package/package.json +1 -1
  4. package/worker.js +118 -12
package/README.md CHANGED
@@ -68,6 +68,10 @@ const client = new TranscribeAPI({
68
68
  apiKey: "YOUR_API_KEY",
69
69
  baseUrl: "https://api.transcribeapi.com/v1",
70
70
  uploadConcurrency: 4,
71
+ autoReload: {
72
+ amount: 10,
73
+ ifBalanceBelow: 20,
74
+ },
71
75
  showLogs: true,
72
76
  logger: console,
73
77
  polling: {
@@ -82,6 +86,7 @@ const client = new TranscribeAPI({
82
86
  | `apiKey` | Required. Your Transcribe API key. |
83
87
  | `baseUrl` | Optional. Defaults to `https://api.transcribeapi.com/v1`. |
84
88
  | `uploadConcurrency` | Optional. Number of in-flight upload PUTs. Defaults to `1` and is capped at `32`. |
89
+ | `autoReload` | Optional. Automatically calls `POST /v1/add-funds` after a transcription result when `remaining_balance` is below `ifBalanceBelow`. |
85
90
  | `showLogs` | Optional. Prints upload progress, upload completion, polling status, and final result info. |
86
91
  | `logger` | Optional. Logger object with a `log` method. Defaults to `console`. |
87
92
  | `polling` | Optional. `{ interval, timeout }` in seconds. `interval` must be at least `10`. Omit or set to `null`/`false` to disable automatic polling. |
@@ -187,6 +192,52 @@ exclude: "metadata,billing"
187
192
 
188
193
  For single-file outputs, if `exclude` leaves only one transcript field and removes metadata, billing, and detected language, the API returns that remaining value directly instead of a JSON object. Text-only responses return a plain string, VTT-only responses return a plain string, and segments-only responses return an array. Multi-file outputs still return JSON so each result stays associated with its `reference_id`.
189
194
 
195
+ If `autoReload` is enabled, the SDK always keeps billing in the request even if you included `billing` in `exclude`. It needs `remaining_balance` to decide whether to call `POST /v1/add-funds`.
196
+
197
+ ## Auto reload
198
+
199
+ ```js
200
+ const client = new TranscribeAPI({
201
+ apiKey: process.env.TRANSCRIBE_API_KEY,
202
+ autoReload: {
203
+ amount: 10,
204
+ ifBalanceBelow: 20,
205
+ },
206
+ });
207
+ ```
208
+
209
+ When `autoReload` is enabled, the SDK:
210
+
211
+ - checks `remaining_balance` after a transcription result
212
+ - only calls `POST /v1/add-funds` when the balance is below `ifBalanceBelow`
213
+ - sends `{ amount, if_balance_below }` to the API for backend-side protection too
214
+ - ignores `billing` inside `exclude` so the SDK can always read `remaining_balance`
215
+
216
+ Auto reload only runs when the transcription result returned to the SDK includes `remaining_balance`. If you disable polling for async jobs, immediate non-terminal async responses do not have enough billing data for the SDK to auto reload yet.
217
+
218
+ ### Manual addFunds for webhooks
219
+
220
+ When using webhooks with batch jobs, the transcription result goes to your webhook URL instead of the SDK. The `autoReload` config won't fire because the SDK never sees the result. Call `client.addFunds()` inside your webhook handler instead:
221
+
222
+ ```js
223
+ // Webhook handler (Express example)
224
+ app.post("/webhook", async (req, res) => {
225
+ const { remaining_balance } = req.body;
226
+
227
+ if (remaining_balance < 20) {
228
+ const client = new TranscribeAPI({ apiKey: process.env.TRANSCRIBE_API_KEY });
229
+ await client.addFunds(10, { ifBalanceBelow: 20 });
230
+ }
231
+
232
+ res.sendStatus(200);
233
+ });
234
+ ```
235
+
236
+ `addFunds(amount, { ifBalanceBelow })` calls `POST /v1/add-funds`:
237
+
238
+ - `amount` — whole dollar amount from 5 to 100.
239
+ - `ifBalanceBelow` — server-side guard. The API only charges if your current balance is actually below this threshold, making it safe against duplicate webhook deliveries.
240
+
190
241
  ## Webhooks
191
242
 
192
243
  ```js
package/index.js CHANGED
@@ -143,6 +143,54 @@ function normalizePollingConfig(polling) {
143
143
  };
144
144
  }
145
145
 
146
+ function normalizeAutoReloadConfig(autoReload) {
147
+ if (autoReload === undefined || autoReload === null || autoReload === false) {
148
+ return null;
149
+ }
150
+ if (typeof autoReload !== "object" || Array.isArray(autoReload)) {
151
+ throw new TranscribeAPIError("`autoReload` must be an object with `amount` and `ifBalanceBelow`.", {
152
+ code: "invalid_auto_reload_config",
153
+ });
154
+ }
155
+
156
+ const amount = Number.parseInt(String(autoReload.amount ?? ""), 10);
157
+ if (!Number.isInteger(amount) || amount < 5 || amount > 100) {
158
+ throw new TranscribeAPIError("`autoReload.amount` must be a whole dollar value from 5 to 100.", {
159
+ code: "invalid_auto_reload_amount",
160
+ });
161
+ }
162
+
163
+ const rawIfBalanceBelow = autoReload.ifBalanceBelow ?? autoReload.if_balance_below;
164
+ const ifBalanceBelow = Number(rawIfBalanceBelow);
165
+ if (!Number.isFinite(ifBalanceBelow) || ifBalanceBelow < 0) {
166
+ throw new TranscribeAPIError("`autoReload.ifBalanceBelow` must be a number >= 0.", {
167
+ code: "invalid_auto_reload_if_balance_below",
168
+ });
169
+ }
170
+
171
+ return {
172
+ amount,
173
+ ifBalanceBelow,
174
+ };
175
+ }
176
+
177
+ function normalizeExcludeList(exclude) {
178
+ if (exclude === undefined || exclude === null || exclude === "") {
179
+ return [];
180
+ }
181
+ if (Array.isArray(exclude)) {
182
+ return exclude.map((item) => String(item || "").trim()).filter(Boolean);
183
+ }
184
+ return String(exclude)
185
+ .split(",")
186
+ .map((item) => item.trim())
187
+ .filter(Boolean);
188
+ }
189
+
190
+ function stringifyExclude(excludeList) {
191
+ return excludeList.length ? excludeList.join(",") : null;
192
+ }
193
+
146
194
  function contentTypeFromName(name = "") {
147
195
  const lower = String(name).toLowerCase();
148
196
  if (lower.endsWith(".mp3")) return "audio/mpeg";
@@ -1229,6 +1277,7 @@ export class TranscribeAPI {
1229
1277
  showLogs = false,
1230
1278
  logger = console,
1231
1279
  polling = null,
1280
+ autoReload = null,
1232
1281
  } = {}) {
1233
1282
  if (!apiKey) {
1234
1283
  throw new Error("Missing API key");
@@ -1240,6 +1289,7 @@ export class TranscribeAPI {
1240
1289
  this.showLogs = Boolean(showLogs);
1241
1290
  this.logger = logger || console;
1242
1291
  this.polling = normalizePollingConfig(polling);
1292
+ this.autoReload = normalizeAutoReloadConfig(autoReload);
1243
1293
  this.jobs = {
1244
1294
  createBigFile: (options) => this.createBigFileJob(options),
1245
1295
  createBatch: (options) => this.createBatchJob(options),
@@ -1265,6 +1315,54 @@ export class TranscribeAPI {
1265
1315
  return retryable ? retry(run) : run();
1266
1316
  }
1267
1317
 
1318
+ getEffectiveExclude(exclude) {
1319
+ const excludeList = normalizeExcludeList(exclude);
1320
+ if (!this.autoReload) {
1321
+ return excludeList;
1322
+ }
1323
+ return excludeList.filter((field) => field !== "billing");
1324
+ }
1325
+
1326
+ async addFunds(amount, { ifBalanceBelow } = {}) {
1327
+ const body = { amount };
1328
+ if (ifBalanceBelow !== undefined && ifBalanceBelow !== null) {
1329
+ body.if_balance_below = ifBalanceBelow;
1330
+ }
1331
+ return this.requestJson("/add-funds", {
1332
+ method: "POST",
1333
+ body,
1334
+ retryable: true,
1335
+ });
1336
+ }
1337
+
1338
+ async maybeAutoReload(result, { showLogs = this.showLogs, logger = this.logger } = {}) {
1339
+ if (!this.autoReload || !result || typeof result !== "object" || Array.isArray(result)) {
1340
+ return result;
1341
+ }
1342
+
1343
+ const remainingBalance = Number(result.remaining_balance);
1344
+ if (!Number.isFinite(remainingBalance) || remainingBalance >= this.autoReload.ifBalanceBelow) {
1345
+ return result;
1346
+ }
1347
+
1348
+ try {
1349
+ const autoReloadResult = await this.addFunds(this.autoReload.amount, {
1350
+ ifBalanceBelow: this.autoReload.ifBalanceBelow,
1351
+ });
1352
+ if (showLogs && typeof logger?.log === "function") {
1353
+ logger.log(JSON.stringify(autoReloadResult, null, 2));
1354
+ }
1355
+ } catch (error) {
1356
+ if (showLogs && typeof logger?.log === "function") {
1357
+ logger.log(JSON.stringify({
1358
+ auto_reload_error: extractErrorInfo(error),
1359
+ }, null, 2));
1360
+ }
1361
+ }
1362
+
1363
+ return result;
1364
+ }
1365
+
1268
1366
  async waitForJobCompletion(jobId, {
1269
1367
  polling = this.polling,
1270
1368
  showLogs = this.showLogs,
@@ -1325,6 +1423,7 @@ export class TranscribeAPI {
1325
1423
  exclude,
1326
1424
  uploadConcurrency,
1327
1425
  } = {}) {
1426
+ const effectiveExclude = this.getEffectiveExclude(exclude);
1328
1427
  const progress = composeProgressHandler({
1329
1428
  onProgress,
1330
1429
  showLogs: showLogs ?? this.showLogs,
@@ -1353,7 +1452,7 @@ export class TranscribeAPI {
1353
1452
  logger: logger ?? this.logger,
1354
1453
  uploadConcurrency,
1355
1454
  language,
1356
- exclude,
1455
+ exclude: effectiveExclude,
1357
1456
  });
1358
1457
  }
1359
1458
 
@@ -1381,7 +1480,7 @@ export class TranscribeAPI {
1381
1480
  logger: logger ?? this.logger,
1382
1481
  uploadConcurrency,
1383
1482
  language,
1384
- exclude,
1483
+ exclude: effectiveExclude,
1385
1484
  });
1386
1485
  }
1387
1486
 
@@ -1390,7 +1489,7 @@ export class TranscribeAPI {
1390
1489
  url: normalizedItem.url,
1391
1490
  referenceId: normalizedItem.referenceId,
1392
1491
  language: effectiveLanguage,
1393
- exclude,
1492
+ exclude: effectiveExclude,
1394
1493
  webhookUrl,
1395
1494
  showLogs: showLogs ?? this.showLogs,
1396
1495
  logger: logger ?? this.logger,
@@ -1401,7 +1500,7 @@ export class TranscribeAPI {
1401
1500
  file: normalizedSingleFile,
1402
1501
  referenceId: normalizedItem.referenceId,
1403
1502
  language: effectiveLanguage,
1404
- exclude,
1503
+ exclude: effectiveExclude,
1405
1504
  webhookUrl,
1406
1505
  showLogs: showLogs ?? this.showLogs,
1407
1506
  logger: logger ?? this.logger,
@@ -1450,7 +1549,10 @@ export class TranscribeAPI {
1450
1549
  if ((showLogs ?? this.showLogs) && TERMINAL_JOB_STATUSES.has(String(result?.job_status || ""))) {
1451
1550
  logTerminalAsyncResult(result, logger ?? this.logger);
1452
1551
  }
1453
- return result;
1552
+ return this.maybeAutoReload(result, {
1553
+ showLogs: showLogs ?? this.showLogs,
1554
+ logger: logger ?? this.logger,
1555
+ });
1454
1556
  }
1455
1557
 
1456
1558
  async transcribeDirect({
@@ -1470,7 +1572,8 @@ export class TranscribeAPI {
1470
1572
  if (String(referenceId || "").trim()) form.set("reference_id", String(referenceId).trim());
1471
1573
  form.set("file", directFile, directFile.name);
1472
1574
  if (language) form.set("language", language);
1473
- if (exclude) form.set("exclude", Array.isArray(exclude) ? exclude.join(",") : exclude);
1575
+ const excludeValue = stringifyExclude(this.getEffectiveExclude(exclude));
1576
+ if (excludeValue) form.set("exclude", excludeValue);
1474
1577
  if (webhookUrl) form.set("webhook_url", webhookUrl);
1475
1578
 
1476
1579
  const response = await fetch(`${this.baseUrl}/transcribe`, {
@@ -1489,10 +1592,11 @@ export class TranscribeAPI {
1489
1592
  initialJob: result,
1490
1593
  });
1491
1594
  }
1595
+ const finalResult = await this.maybeAutoReload(result, { showLogs, logger });
1492
1596
  if (showLogs && typeof logger?.log === "function") {
1493
- logger.log(typeof result === "string" ? result : JSON.stringify(result, null, 2));
1597
+ logger.log(typeof finalResult === "string" ? finalResult : JSON.stringify(finalResult, null, 2));
1494
1598
  }
1495
- return result;
1599
+ return finalResult;
1496
1600
  }
1497
1601
 
1498
1602
  async transcribeUrlDirect({
@@ -1508,7 +1612,8 @@ export class TranscribeAPI {
1508
1612
  form.set("url", String(url || "").trim());
1509
1613
  if (String(referenceId || "").trim()) form.set("reference_id", String(referenceId).trim());
1510
1614
  if (language) form.set("language", language);
1511
- if (exclude) form.set("exclude", Array.isArray(exclude) ? exclude.join(",") : exclude);
1615
+ const excludeValue = stringifyExclude(this.getEffectiveExclude(exclude));
1616
+ if (excludeValue) form.set("exclude", excludeValue);
1512
1617
  if (webhookUrl) form.set("webhook_url", webhookUrl);
1513
1618
 
1514
1619
  const response = await fetch(`${this.baseUrl}/transcribe`, {
@@ -1527,10 +1632,11 @@ export class TranscribeAPI {
1527
1632
  initialJob: result,
1528
1633
  });
1529
1634
  }
1635
+ const finalResult = await this.maybeAutoReload(result, { showLogs, logger });
1530
1636
  if (showLogs && typeof logger?.log === "function") {
1531
- logger.log(typeof result === "string" ? result : JSON.stringify(result, null, 2));
1637
+ logger.log(typeof finalResult === "string" ? finalResult : JSON.stringify(finalResult, null, 2));
1532
1638
  }
1533
- return result;
1639
+ return finalResult;
1534
1640
  }
1535
1641
 
1536
1642
  async transcribeMany({
@@ -1650,7 +1756,7 @@ export class TranscribeAPI {
1650
1756
  )),
1651
1757
  ...(normalizedLanguage ? { language: normalizedLanguage } : {}),
1652
1758
  ...(webhookUrl ? { webhook_url: webhookUrl } : {}),
1653
- ...(exclude ? { exclude: Array.isArray(exclude) ? exclude.join(",") : exclude } : {}),
1759
+ ...(stringifyExclude(this.getEffectiveExclude(exclude)) ? { exclude: stringifyExclude(this.getEffectiveExclude(exclude)) } : {}),
1654
1760
  },
1655
1761
  retryable: true,
1656
1762
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@transcribe-api/sdk",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "description": "Official JavaScript SDK for Transcribe API.",
5
5
  "type": "module",
6
6
  "main": "index.js",
package/worker.js CHANGED
@@ -143,6 +143,54 @@ function normalizePollingConfig(polling) {
143
143
  };
144
144
  }
145
145
 
146
+ function normalizeAutoReloadConfig(autoReload) {
147
+ if (autoReload === undefined || autoReload === null || autoReload === false) {
148
+ return null;
149
+ }
150
+ if (typeof autoReload !== "object" || Array.isArray(autoReload)) {
151
+ throw new TranscribeAPIError("`autoReload` must be an object with `amount` and `ifBalanceBelow`.", {
152
+ code: "invalid_auto_reload_config",
153
+ });
154
+ }
155
+
156
+ const amount = Number.parseInt(String(autoReload.amount ?? ""), 10);
157
+ if (!Number.isInteger(amount) || amount < 5 || amount > 100) {
158
+ throw new TranscribeAPIError("`autoReload.amount` must be a whole dollar value from 5 to 100.", {
159
+ code: "invalid_auto_reload_amount",
160
+ });
161
+ }
162
+
163
+ const rawIfBalanceBelow = autoReload.ifBalanceBelow ?? autoReload.if_balance_below;
164
+ const ifBalanceBelow = Number(rawIfBalanceBelow);
165
+ if (!Number.isFinite(ifBalanceBelow) || ifBalanceBelow < 0) {
166
+ throw new TranscribeAPIError("`autoReload.ifBalanceBelow` must be a number >= 0.", {
167
+ code: "invalid_auto_reload_if_balance_below",
168
+ });
169
+ }
170
+
171
+ return {
172
+ amount,
173
+ ifBalanceBelow,
174
+ };
175
+ }
176
+
177
+ function normalizeExcludeList(exclude) {
178
+ if (exclude === undefined || exclude === null || exclude === "") {
179
+ return [];
180
+ }
181
+ if (Array.isArray(exclude)) {
182
+ return exclude.map((item) => String(item || "").trim()).filter(Boolean);
183
+ }
184
+ return String(exclude)
185
+ .split(",")
186
+ .map((item) => item.trim())
187
+ .filter(Boolean);
188
+ }
189
+
190
+ function stringifyExclude(excludeList) {
191
+ return excludeList.length ? excludeList.join(",") : null;
192
+ }
193
+
146
194
  function contentTypeFromName(name = "") {
147
195
  const lower = String(name).toLowerCase();
148
196
  if (lower.endsWith(".mp3")) return "audio/mpeg";
@@ -1229,6 +1277,7 @@ export class TranscribeAPI {
1229
1277
  showLogs = false,
1230
1278
  logger = console,
1231
1279
  polling = null,
1280
+ autoReload = null,
1232
1281
  } = {}) {
1233
1282
  if (!apiKey) {
1234
1283
  throw new Error("Missing API key");
@@ -1240,6 +1289,7 @@ export class TranscribeAPI {
1240
1289
  this.showLogs = Boolean(showLogs);
1241
1290
  this.logger = logger || console;
1242
1291
  this.polling = normalizePollingConfig(polling);
1292
+ this.autoReload = normalizeAutoReloadConfig(autoReload);
1243
1293
  this.jobs = {
1244
1294
  createBigFile: (options) => this.createBigFileJob(options),
1245
1295
  createBatch: (options) => this.createBatchJob(options),
@@ -1265,6 +1315,54 @@ export class TranscribeAPI {
1265
1315
  return retryable ? retry(run) : run();
1266
1316
  }
1267
1317
 
1318
+ getEffectiveExclude(exclude) {
1319
+ const excludeList = normalizeExcludeList(exclude);
1320
+ if (!this.autoReload) {
1321
+ return excludeList;
1322
+ }
1323
+ return excludeList.filter((field) => field !== "billing");
1324
+ }
1325
+
1326
+ async addFunds(amount, { ifBalanceBelow } = {}) {
1327
+ const body = { amount };
1328
+ if (ifBalanceBelow !== undefined && ifBalanceBelow !== null) {
1329
+ body.if_balance_below = ifBalanceBelow;
1330
+ }
1331
+ return this.requestJson("/add-funds", {
1332
+ method: "POST",
1333
+ body,
1334
+ retryable: true,
1335
+ });
1336
+ }
1337
+
1338
+ async maybeAutoReload(result, { showLogs = this.showLogs, logger = this.logger } = {}) {
1339
+ if (!this.autoReload || !result || typeof result !== "object" || Array.isArray(result)) {
1340
+ return result;
1341
+ }
1342
+
1343
+ const remainingBalance = Number(result.remaining_balance);
1344
+ if (!Number.isFinite(remainingBalance) || remainingBalance >= this.autoReload.ifBalanceBelow) {
1345
+ return result;
1346
+ }
1347
+
1348
+ try {
1349
+ const autoReloadResult = await this.addFunds(this.autoReload.amount, {
1350
+ ifBalanceBelow: this.autoReload.ifBalanceBelow,
1351
+ });
1352
+ if (showLogs && typeof logger?.log === "function") {
1353
+ logger.log(JSON.stringify(autoReloadResult, null, 2));
1354
+ }
1355
+ } catch (error) {
1356
+ if (showLogs && typeof logger?.log === "function") {
1357
+ logger.log(JSON.stringify({
1358
+ auto_reload_error: extractErrorInfo(error),
1359
+ }, null, 2));
1360
+ }
1361
+ }
1362
+
1363
+ return result;
1364
+ }
1365
+
1268
1366
  async waitForJobCompletion(jobId, {
1269
1367
  polling = this.polling,
1270
1368
  showLogs = this.showLogs,
@@ -1325,6 +1423,7 @@ export class TranscribeAPI {
1325
1423
  exclude,
1326
1424
  uploadConcurrency,
1327
1425
  } = {}) {
1426
+ const effectiveExclude = this.getEffectiveExclude(exclude);
1328
1427
  const progress = composeProgressHandler({
1329
1428
  onProgress,
1330
1429
  showLogs: showLogs ?? this.showLogs,
@@ -1353,7 +1452,7 @@ export class TranscribeAPI {
1353
1452
  logger: logger ?? this.logger,
1354
1453
  uploadConcurrency,
1355
1454
  language,
1356
- exclude,
1455
+ exclude: effectiveExclude,
1357
1456
  });
1358
1457
  }
1359
1458
 
@@ -1381,7 +1480,7 @@ export class TranscribeAPI {
1381
1480
  logger: logger ?? this.logger,
1382
1481
  uploadConcurrency,
1383
1482
  language,
1384
- exclude,
1483
+ exclude: effectiveExclude,
1385
1484
  });
1386
1485
  }
1387
1486
 
@@ -1390,7 +1489,7 @@ export class TranscribeAPI {
1390
1489
  url: normalizedItem.url,
1391
1490
  referenceId: normalizedItem.referenceId,
1392
1491
  language: effectiveLanguage,
1393
- exclude,
1492
+ exclude: effectiveExclude,
1394
1493
  webhookUrl,
1395
1494
  showLogs: showLogs ?? this.showLogs,
1396
1495
  logger: logger ?? this.logger,
@@ -1401,7 +1500,7 @@ export class TranscribeAPI {
1401
1500
  file: normalizedSingleFile,
1402
1501
  referenceId: normalizedItem.referenceId,
1403
1502
  language: effectiveLanguage,
1404
- exclude,
1503
+ exclude: effectiveExclude,
1405
1504
  webhookUrl,
1406
1505
  showLogs: showLogs ?? this.showLogs,
1407
1506
  logger: logger ?? this.logger,
@@ -1450,7 +1549,10 @@ export class TranscribeAPI {
1450
1549
  if ((showLogs ?? this.showLogs) && TERMINAL_JOB_STATUSES.has(String(result?.job_status || ""))) {
1451
1550
  logTerminalAsyncResult(result, logger ?? this.logger);
1452
1551
  }
1453
- return result;
1552
+ return this.maybeAutoReload(result, {
1553
+ showLogs: showLogs ?? this.showLogs,
1554
+ logger: logger ?? this.logger,
1555
+ });
1454
1556
  }
1455
1557
 
1456
1558
  async transcribeDirect({
@@ -1470,7 +1572,8 @@ export class TranscribeAPI {
1470
1572
  if (String(referenceId || "").trim()) form.set("reference_id", String(referenceId).trim());
1471
1573
  form.set("file", directFile, directFile.name);
1472
1574
  if (language) form.set("language", language);
1473
- if (exclude) form.set("exclude", Array.isArray(exclude) ? exclude.join(",") : exclude);
1575
+ const excludeValue = stringifyExclude(this.getEffectiveExclude(exclude));
1576
+ if (excludeValue) form.set("exclude", excludeValue);
1474
1577
  if (webhookUrl) form.set("webhook_url", webhookUrl);
1475
1578
 
1476
1579
  const response = await fetch(`${this.baseUrl}/transcribe`, {
@@ -1489,10 +1592,11 @@ export class TranscribeAPI {
1489
1592
  initialJob: result,
1490
1593
  });
1491
1594
  }
1595
+ const finalResult = await this.maybeAutoReload(result, { showLogs, logger });
1492
1596
  if (showLogs && typeof logger?.log === "function") {
1493
- logger.log(typeof result === "string" ? result : JSON.stringify(result, null, 2));
1597
+ logger.log(typeof finalResult === "string" ? finalResult : JSON.stringify(finalResult, null, 2));
1494
1598
  }
1495
- return result;
1599
+ return finalResult;
1496
1600
  }
1497
1601
 
1498
1602
  async transcribeUrlDirect({
@@ -1508,7 +1612,8 @@ export class TranscribeAPI {
1508
1612
  form.set("url", String(url || "").trim());
1509
1613
  if (String(referenceId || "").trim()) form.set("reference_id", String(referenceId).trim());
1510
1614
  if (language) form.set("language", language);
1511
- if (exclude) form.set("exclude", Array.isArray(exclude) ? exclude.join(",") : exclude);
1615
+ const excludeValue = stringifyExclude(this.getEffectiveExclude(exclude));
1616
+ if (excludeValue) form.set("exclude", excludeValue);
1512
1617
  if (webhookUrl) form.set("webhook_url", webhookUrl);
1513
1618
 
1514
1619
  const response = await fetch(`${this.baseUrl}/transcribe`, {
@@ -1527,10 +1632,11 @@ export class TranscribeAPI {
1527
1632
  initialJob: result,
1528
1633
  });
1529
1634
  }
1635
+ const finalResult = await this.maybeAutoReload(result, { showLogs, logger });
1530
1636
  if (showLogs && typeof logger?.log === "function") {
1531
- logger.log(typeof result === "string" ? result : JSON.stringify(result, null, 2));
1637
+ logger.log(typeof finalResult === "string" ? finalResult : JSON.stringify(finalResult, null, 2));
1532
1638
  }
1533
- return result;
1639
+ return finalResult;
1534
1640
  }
1535
1641
 
1536
1642
  async transcribeMany({
@@ -1650,7 +1756,7 @@ export class TranscribeAPI {
1650
1756
  )),
1651
1757
  ...(normalizedLanguage ? { language: normalizedLanguage } : {}),
1652
1758
  ...(webhookUrl ? { webhook_url: webhookUrl } : {}),
1653
- ...(exclude ? { exclude: Array.isArray(exclude) ? exclude.join(",") : exclude } : {}),
1759
+ ...(stringifyExclude(this.getEffectiveExclude(exclude)) ? { exclude: stringifyExclude(this.getEffectiveExclude(exclude)) } : {}),
1654
1760
  },
1655
1761
  retryable: true,
1656
1762
  });