# SDK per Node.js

> Integra @transcript1/sdk nel tuo server per trascrivere video da link e file, scaricare testo o sottotitoli e gestire avanzamento ed errori.

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

Con `@transcript1/sdk` puoi trascrivere da un server TypeScript o JavaScript. L'SDK crea la trascrizione, carica i file e aspetta che il testo sia pronto.

Per i link dei social serve almeno la versione 1.1.0. La 1.0.1 riconosce solo YouTube e rifiuta gli altri link prima di contattare l'API. Per aggiornare, esegui `npm i @transcript1/sdk@latest`.

La 1.1.0 copre le sei piattaforme iniziali. Per Twitch, Dailymotion, Pinterest, LinkedIn e Snapchat occorre una release che le includa esplicitamente: un SDK meno recente potrebbe rifiutare quei link senza inviarli all'API.

## Installare il pacchetto

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

Per eseguire gli esempi con moduli ES, salvali in file `.mjs`. Se usi `.js`, aggiungi `"type": "module"` al `package.json`. Su Node 20.19+ puoi anche caricare il pacchetto con `require()`, ad esempio `require('@transcript1/sdk')`.

## Configurare la chiave API

Genera una chiave in [“API keys”](https://transcript1.com/dashboard/account/tokens) e imposta la variabile d'ambiente `TRANSCRIPT1_API_KEY` sul server. In alternativa, fornisci `apiKey` al costruttore:

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

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

Se non trova una chiave, il costruttore genera un `Transcript1Error` con codice `missing_api_key`.

## Avviare una trascrizione e aspettare il testo

Chiama `transcribe(input, options)` per creare la trascrizione e attendere che sia pronta. Ricevi un `CompletedTranscription` con `status: 'completed'` e il campo `transcript`. Se il job non riesce o viene annullato, la promise viene rifiutata.

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

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

Se passi un Buffer o un Uint8Array, aggiungi il nome del file: serve all'SDK per riconoscere il formato.

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

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

L'SDK interpreta come link le stringhe che iniziano con `http://` o `https://`; tutte le altre sono percorsi di file. Accetta link di YouTube, X, TikTok, Instagram, Facebook, Bluesky, Twitch, Dailymotion, Pinterest, LinkedIn e Snapchat. Per le piattaforme aggiuntive serve HTTPS. Consulta [Link e opzioni di trascrizione](https://transcript1.com/it/docs/sources-and-options) per i formati dei link a registrazioni pubbliche, i sottotitoli disponibili e le restrizioni.

Puoi anche caricare file fino a 2.000.000.000 byte, con estensione mp3, wav, m4a, flac, ogg, opus, mp4, mov, webm o mkv.

Usa post pubblici: se contengono più video, trascriviamo solo il primo. Non devi indicare la piattaforma, perché l'API la riconosce dal link. Anche i link brevi ammessi sono elencati in [Link e opzioni di trascrizione](https://transcript1.com/it/docs/sources-and-options).

Sono accettati anche Blob, `ReadableStream<Uint8Array>` e iterabili asincroni di chunk Uint8Array. Per un Blob devi specificare `filename`, tranne quando è un File con un nome. Per stream e iterabili asincroni, indica sia `filename` sia `size` in byte.

## Scaricare testo e sottotitoli

Usa `download(id, options)` per aspettare la trascrizione e riceverla come stringa. Anche scegliendo JSON ottieni una stringa con il JSON dell'API, non un oggetto già deserializzato.

```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' });
```

Puoi usare `timestamps: true` solo con `text`. Negli altri formati, la promise viene rifiutata con `invalid_input`. La promise di `download` viene rifiutata anche se il job non riesce o viene annullato.

## Avviare il lavoro senza aspettare la trascrizione

Con `transcriptions.create` puoi inviare il lavoro e tornare al tuo codice prima che il testo sia pronto. Se passi un file, la chiamata aspetta comunque la fine del caricamento.

```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 });
```

Chiama `get` senza `wait` per leggere subito lo stato corrente. Con `wait: true`, la promise si risolve solo quando lo stato diventa `completed`, `failed` o `canceled`. Controlla quindi `finished.status` prima di usare il testo. A differenza di `transcribe`, la promise di `get` non viene rifiutata solo perché il job non è riuscito o è stato annullato.

## Consultare le trascrizioni e l'account

```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);
```

Durante l'iterazione, `list` carica le pagine man mano che servono. Puoi filtrare per `status` o `platform`, scegliendo tra `youtube`, `x`, `tiktok`, `instagram`, `facebook`, `bluesky`, `twitch`, `dailymotion`, `pinterest`, `linkedin`, `snapchat` e `upload`. Con `limit` scegli da 1 a 100 elementi per pagina; il valore predefinito dell'API è 20. I campi degli oggetti restano in `snake_case`, come nell'API. Conserva `media_id` come stringa opaca, senza interpretarlo.

Se il job è ancora in corso, `delete` lo annulla. Se è terminato, elimina sia il job sia il testo. Per leggere piano, minuti e limiti, chiama `account`.

## Configurare client e chiamate

Al costruttore puoi passare `apiKey`, `baseUrl`, `fetch` e `maxRetries`. Se non specifichi `baseUrl`, il client usa il valore di `TRANSCRIPT1_API_URL`, quando presente, oppure `https://api.transcript1.com`. Con `fetch` fornisci una tua implementazione. Per `maxRetries` puoi scegliere un intero da 0 a 10; di default è 2.

Queste opzioni valgono sia per `transcribe` sia per `transcriptions.create`:

| Opzione | Come usarla |
|---|---|
| `speakers` | Attiva il riconoscimento dei parlanti. |
| `language` | Lascia `auto`, il valore predefinito, oppure specifica un codice ISO 639-1. |
| `source` | Per i link, scegli `auto` o `stt`. Su YouTube, X, TikTok, Bluesky, Dailymotion e LinkedIn puoi anche usare `captions` se è disponibile una traccia adatta. |
| `fresh` | Per i link, evita di riusare una trascrizione delle ultime 24 ore. |
| `filename` | Indica il nome per Buffer, Blob senza nome e stream: è obbligatorio. Puoi usarlo anche per sostituire il nome di un file. |
| `size` | Indica la dimensione in byte. È obbligatoria per stream e iterabili asincroni. |
| `idempotencyKey` | Se non la specifichi, l'SDK genera un nuovo UUID per ogni chiamata. |
| `onProgress` | Fornisci la funzione che riceve gli aggiornamenti sull'avanzamento. |
| `signal` | Passa un AbortSignal per interrompere la chiamata. |

Per `transcriptions.get` sono disponibili `wait`, `includeWords`, `onProgress` e `signal`. Aggiungi `includeWords: true` se vuoi i timestamp delle parole. Durante l'attesa, `onProgress` ti segnala i cambiamenti.

Per `download` puoi scegliere `format`, `timestamps` e `signal`; anche `list` supporta `signal`. Per usarlo con `transcriptions.delete(id, options)` o `account(options)`, passa `{ signal }` nell'argomento delle opzioni.

## Seguire l'avanzamento

Usa `onProgress` con `transcribe`, `transcriptions.create` oppure `transcriptions.get` mentre aspetta il completamento:

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

| Evento | Dati disponibili |
|---|---|
| `upload` | Byte inviati in `sent` e byte complessivi in `total`. |
| `status` | Stato corrente del job nel campo `status`. |
| `waiting_slot` | Secondi da aspettare in `retryAfter` prima di provare di nuovo ad avviare il job. |
| `reconnecting` | Nessun campo aggiuntivo. Lo ricevi una volta per ogni interruzione della connessione durante l'attesa. |

## Interrompere una chiamata o fermare il job

Per interrompere una chiamata, passa l'`AbortSignal` di un AbortController. Se vuoi un timeout, usa `AbortSignal.timeout`:

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

Se interrompi prima della prima chiamata HTTP, la promise viene rifiutata con `aborted` e senza ID del job. Se interrompi un caricamento, l'SDK prova prima a eliminare il job, purché sia ancora `awaiting_upload`. Poi la promise viene rifiutata con `aborted` e l'ID.

Se interrompi solo l'attesa, il job continua. Recupera `transcriptionId` dall'errore e riprendi con `transcriptions.get(id, { wait: true })`. Se vuoi fermare anche il job, devi chiamare `transcriptions.delete(id)`.

Durante l'attesa, l'SDK riprova senza limite dopo errori di rete o risposte HTTP 429, 500, 502, 503 e 504. Prima di riconnettersi aspetta 2, poi 4, 8, 16 e infine 30 secondi. Per le altre chiamate vale `maxRetries`. Anche la creazione di un job aspetta e riprova se tutti i posti per le trascrizioni attive sono occupati. Usa `signal` per fissare un limite al tempo totale.

## Intercettare gli errori

Gli errori dell'API, dei job e dell'SDK arrivano come `Transcript1Error`. Intercettalo per leggerne il codice:

```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);
  }
}
```

| Campo | Cosa trovi |
|---|---|
| `message` | Spiegazione del problema. |
| `code` | Codice dell'API o dell'errore del job, `canceled` oppure un codice generato in locale dall'SDK. |
| `status` | Codice HTTP. Non è presente per gli errori del job o quelli locali. |
| `details` | Dati aggiuntivi dell'errore API, ad esempio `minutes_needed` o `action_url`. Di default è un oggetto vuoto. |
| `retryable` | Indica se ha senso riprovare. Il valore predefinito è false. |
| `transcriptionId` | ID del job, se disponibile. |
| `transcription` | L'ultimo oggetto trascrizione disponibile. |

L'SDK può generare in locale `missing_api_key`, `invalid_input`, `aborted`, `network_error` o `upload_token_refused`. Se la risposta di errore non è JSON, il codice segue il formato `http_<status>`.

Se un job non riesce ma non contiene un oggetto di errore, ricevi `transcription_failed`. Se invece risulta completato ma manca il testo anche dopo averlo recuperato, la promise di `transcribe` viene rifiutata con `internal_error`. Consulta [Gestire gli errori](https://transcript1.com/it/docs/errors) per i codici API e gli [Endpoint API](https://transcript1.com/it/docs/api-reference) per i campi delle risposte.

## Dove usare l'SDK

Serve Node 20.19+ e l'SDK va usato solo lato server. Bun e Deno dovrebbero funzionare grazie alla compatibilità `node:`, ma i test automatici vengono eseguiti solo su Node. Non includere mai una chiave API nel codice inviato al browser.
