Vai al contenuto principale

Sviluppatori

API di riconoscimento vocale per audio registrato

Usa l'API di riconoscimento vocale di Hushscript per caricare audio registrato, controllare il job e leggere la trascrizione con un token dotato degli scope necessari.

L’API di riconoscimento vocale di Hushscript accetta audio registrato tramite /v1/, poi permette al tuo script di controllare il job e leggere la trascrizione. È un flusso di trascrizione online, non un endpoint per lo streaming in diretta o per accedere direttamente al modello di riconoscimento. Il server MCP usa lo stesso account, saldo e token bearer se il tuo client preferisce gli strumenti alle chiamate HTTP.

Trascrizione audio e video tramite API

L’API di trascrizione audio accetta file audio già preparati, comprese le registrazioni vocali. Per un’integrazione STT (speech-to-text), invia file registrati: lo streaming in diretta dal microfono non è disponibile. Per trascrivere un video, carica così com’è un file MP4 o MOV con una traccia audio: il server legge la traccia audio e ignora il video. Estrai prima l’audio da qualsiasi altro formato video; l’API non accetta un URL video. Il flusso nel browser è spiegato nella pagina Da video a testo.

Avvio rapido

L’API richiede un token di accesso personale, e ci sono due modi per ottenerne uno. Una persona ne crea uno sotto Token nella pagina MCP dell’account, sceglie i suoi scope e decide se può acquistare minuti. Oppure un agente apre un proprio account senza un titolare umano: POST /v1/agent/accounts avvia una registrazione a pagamento, e POST /v1/agent/accounts/{signup_id}/claim scambia il suo segreto monouso di attivazione con un account vero e un primo token. In entrambi i casi il token viene mostrato una sola volta e ha la forma hsr1:<region>:pat.<id>.<secret>. Anche un token generato tramite l’accesso OAuth del server MCP funziona qui; vedi Connessione. Un token non può mai generare, elencare o revocare altri token, e un account ne può avere al massimo 25 attivi; il flusso completo per gli account agente, inclusa la rotazione delle credenziali, è la guida Uso automatizzato.

Una volta ottenuto un token, chiama l’API direttamente. Questo esempio rappresenta un nuovo account personale prima della verifica della carta o di un acquisto; un account creato da un agente parte con il pacchetto di minuti che ha pagato:

curl https://api.hushscript.com/v1/account \
  -H "Authorization: Bearer hsr1:eu:pat.7f3a9c.2b6e1d4a9f2c88b1a3d4e5f60718293"
{
  "balance_seconds": 0,
  "held_seconds": 0,
  "credits_expire_at": null,
  "card_on_file": false,
  "data_region": "eu",
  "limits": {
    "max_active_jobs": 50,
    "max_daily_seconds": 144000,
    "active_jobs": 0,
    "used_today_seconds": 0
  }
}

La risposta contiene il saldo in secondi, i secondi trattenuti dai job in corso, credits_expire_at (sempre null, perché i minuti non scadono), la presenza di una carta salvata, la regione dei dati e i limiti di ammissione (max_active_jobs, max_daily_seconds, e quanto è già stato usato). Il limite giornaliero è il limite effettivo attuale dell’account, non un valore da fissare nel codice. POST /v1/uploads controlla i minuti disponibili, non la carta: senza minuti sufficienti restituisce 3001 insufficient_balance.

L’API di riconoscimento vocale è gratuita?

Non esiste un piano API gratuito generale, ma puoi provare il flusso prima di scrivere codice: l’anteprima pubblica trascrive fino a cinque minuti di una registrazione prima dell’accesso. Un account personale idoneo riceve poi 30 minuti gratuiti dopo la verifica della carta (vedi i prezzi per i dettagli); un account creato da un agente non riceve i minuti di benvenuto e parte con il pacchetto acquistato durante la registrazione. Un job API completo richiede comunque un account e minuti.

Automatizzare dall’inizio alla fine

Le stesse chiamate /v1/ funzionano con un token creato da una persona nell’app o ottenuto da un agente dopo l’attivazione dell’account a seguito della registrazione a pagamento (vedi Uso automatizzato). Salvare una carta richiede il Checkout ospitato in un browser; un agente può guidarlo. Gli acquisti successivi fuori sessione possono comunque essere rifiutati se l’emittente della carta richiede un’autenticazione.

  1. Leggi l’account. GET /v1/account. Se devi acquistare minuti e card_on_file è false, salva prima una carta.

  2. Salva una carta, una volta sola. POST /v1/billing/setup-session restituisce un checkout_url, un session_id e un expires_at:

    curl -X POST https://api.hushscript.com/v1/billing/setup-session \
      -H "Authorization: Bearer hsr1:eu:pat.7f3a9c.2b6e1d4a9f2c88b1a3d4e5f60718293"
    {
      "checkout_url": "https://checkout.stripe.com/c/pay/cs_live_a1B2c3D4e5F6g7H8",
      "session_id": "seti_1PxYzQ2eZvKYlo2C",
      "expires_at": "2026-09-11T15:45:00Z"
    }

    Apri l’URL in un browser che controlli e completa la pagina Stripe ospitata; non viene addebitato nulla e Hushscript non vede mai la carta. Poi GET /v1/billing/cards la elenca con il suo id. POST /v1/billing/cards/default cambia quella predefinita se l’account ne possiede più di una.

  3. Acquista minuti. GET /v1/billing/packs elenca i cinque pacchetti con id, seconds, amount e currency:

    curl https://api.hushscript.com/v1/billing/packs \
      -H "Authorization: Bearer hsr1:eu:pat.7f3a9c.2b6e1d4a9f2c88b1a3d4e5f60718293"

    POST /v1/billing/purchase con pack, quick_payment_method_id (l’id della carta salvata) e un idempotency_key addebita la carta fuori sessione e risponde con il nuovo balance_seconds:

    curl -X POST https://api.hushscript.com/v1/billing/purchase \
      -H "Authorization: Bearer hsr1:eu:pat.7f3a9c.2b6e1d4a9f2c88b1a3d4e5f60718293" \
      -H "Content-Type: application/json" \
      -d '{
        "pack": "300min",
        "quick_payment_method_id": "pm_2QeT4bY7uX9mK3nP",
        "idempotency_key": "purchase-2026-09-11-02"
      }'
    { "balance_seconds": 18000 }

    Questo richiede lo scope billing, la fatturazione attivata sul token e la fatturazione attivata per l’account. Una richiesta senza l’id di una carta, o con una carta rifiutata, viene respinta con 4021 pat_purchase_requires_app; una carta che l’emittente vuole verificare viene respinta con 4023 pat_purchase_requires_authentication. Nessuno dei due errori apre una pagina che non può essere completata.

  4. Carica. POST /v1/uploads con size_bytes, duration_seconds (da 15 secondi a 10 ore), un title opzionale, transcription_options, matter_code e un idempotency_key:

    curl -X POST https://api.hushscript.com/v1/uploads \
      -H "Authorization: Bearer hsr1:eu:pat.7f3a9c.2b6e1d4a9f2c88b1a3d4e5f60718293" \
      -H "Content-Type: application/json" \
      -d '{
        "size_bytes": 41943040,
        "duration_seconds": 1200,
        "title": "Q3 board call",
        "transcription_options": { "speaker_detection": true },
        "idempotency_key": "upload-2026-09-11-02"
      }'

    matter_code è testo libero di al massimo 64 caratteri, e ha senso solo per un token che appartiene a uno spazio di lavoro: compare accanto al job nell’attività del pool e nei report di utilizzo di quello spazio di lavoro. Uno spazio di lavoro la cui politica sui codici pratica è impostata come obbligatoria rifiuta un caricamento che arriva senza, con org_matter_code_required. client_code viene accettato e ignorato, perché il cliente è un attributo della pratica, impostato da un amministratore dello spazio di lavoro.

    Il caricamento riserva credito e restituisce un job_id con una prima pagina di URL prefirmati per le parti:

    {
      "job_id": "job_5e2a91cf4d7b6081a9f3c2e4b5d6a7c8",
      "part_urls": [
        { "n": 1, "url": "https://r2.hushscript.com/uploads/job_5e2a91cf.../part-1?X-Amz-Signature=..." }
      ]
    }

    Esegui PUT di ogni parte sul suo URL (parti da 32 MiB per impostazione predefinita, l’ultima più piccola):

    curl -X PUT "https://r2.hushscript.com/uploads/job_5e2a91cf.../part-1?X-Amz-Signature=..." \
      --data-binary @part-01.bin

    Recupera altre pagine da GET /v1/uploads/{job}/part-urls?start=<n>, e chiama POST /v1/uploads/{job}/heartbeat ben entro il timeout di inattività di 20 minuti durante un trasferimento lungo. Quando gli URL prefirmati non sono disponibili, o una parte fallisce, PUT /v1/uploads/{job}/parts/{n} invia invece i byte di quella parte attraverso l’API; un PUT ripetuto sostituisce la parte, quindi i nuovi tentativi sono sicuri. Formati supportati: mp3, m4a, mp4 o mov (si usa la traccia audio, le tracce video vengono ignorate), wav, flac, ogg o opus, verificati sul server; estrai l’audio da qualsiasi altro formato video prima di caricarlo.

  5. Avvia e attendi. POST /v1/uploads/{job}/complete con n ed etag di ogni parte inviata a un URL prefirmato (ometti parts se ogni parte è passata attraverso l’API):

    curl -X POST https://api.hushscript.com/v1/uploads/job_5e2a91cf4d7b6081a9f3c2e4b5d6a7c8/complete \
      -H "Authorization: Bearer hsr1:eu:pat.7f3a9c.2b6e1d4a9f2c88b1a3d4e5f60718293" \
      -H "Content-Type: application/json" \
      -d '{
        "parts": [
          { "n": 1, "etag": "\"9f86d081884c7d65\"" }
        ]
      }'

    Poi interroga periodicamente GET /v1/jobs/{id}: state passa attraverso uploading, queued e processing fino a done o failed, e un job completato porta un transcript_id:

    curl https://api.hushscript.com/v1/jobs/job_5e2a91cf4d7b6081a9f3c2e4b5d6a7c8 \
      -H "Authorization: Bearer hsr1:eu:pat.7f3a9c.2b6e1d4a9f2c88b1a3d4e5f60718293"
    {
      "id": "job_5e2a91cf4d7b6081a9f3c2e4b5d6a7c8",
      "state": "done",
      "transcript_id": "trs_2b6e1d4a9f7c3088a1b2c3d4e5f6a7b9"
    }
  6. Leggi il risultato. GET /v1/transcripts/{id} restituisce i metadati e il corpo completo, con i nomi dei parlanti, la lingua rilevata, i tag e la data di eliminazione automatica:

    curl https://api.hushscript.com/v1/transcripts/trs_2b6e1d4a9f7c3088a1b2c3d4e5f6a7b9 \
      -H "Authorization: Bearer hsr1:eu:pat.7f3a9c.2b6e1d4a9f2c88b1a3d4e5f60718293"

    GET /v1/transcripts restituisce l’elenco a pagine.

Le opzioni di trascrizione sono quelle dell’app, identiche: language_code oppure il rilevamento automatico, speaker_detection, medical_mode (richiede language_code in en, es, fr o de, fatturata al +100%), translation_targets (+25% per lingua), multichannel, keyterms_prompt, un prompt in testo libero, e i dictionary_ids e il prompt_preset_id salvati che GET /v1/transcription-context elenca.

Una parte dell’account resta ancora solo per MCP. Importare da un link, modificare o eliminare trascrizioni, gli Insights, le esportazioni, salvare dizionari e preset dei prompt, e le impostazioni dell’account non hanno ancora una rotta /v1/; il server MCP copre tutto questo con lo stesso token.

Autenticazione

Ogni chiamata /v1/ porta un token bearer nell’intestazione Authorization, verificato rispetto agli stessi scope che usa il server MCP:

Scope Cosa consente
transcripts:read Leggere ed esportare le trascrizioni, i loro metadati e l’elenco degli elementi eliminati
transcripts:write Modificare, taggare, tradurre, ripristinare ed eliminare le trascrizioni
transcribe Caricare registrazioni, importare da un link e avviare trascrizioni
insights Leggere, generare ed eliminare gli Insights
context Gestire i dizionari salvati e i preset dei prompt
account:read Leggere saldo, utilizzo, transazioni e trattenute
settings:write Modificare le impostazioni dell’account
org:read Leggere i membri dello spazio di lavoro, l’attività del pool, le fatture e il registro di audit
org:write Modificare i diritti dei membri, programmare il passaggio alla custodia aziendale (permanente), e applicare o revocare blocchi legali
export Richiedere un’esportazione completa dell’account, verificarne lo stato e scaricarla
billing Salvare una carta e acquistare pacchetti di minuti

Una chiamata al di fuori degli scope del token fallisce con pat_scope_missing, con stato 403. Lo scope billing resta inerte a meno che la fatturazione non sia attivata sia sul token sia sull’account. Una chiamata di fatturazione con uno dei due interruttori spento fallisce con lo stesso pat_scope_missing; rigenerare il token non attiva l’interruttore dell’account. Un token non può creare, elencare o revocare token, e un account ne può avere al massimo 25 attivi.

Questi 11 scope sono selezionabili da chi chiama. pat:rotate è uno scope separato, concesso al primo token di un account agente e ai suoi successori ruotati; permette a quel token di sostituire se stesso, non di gestire altri token. Non puoi selezionarlo quando crei un token nell’app.

Endpoint

Il documento OpenAPI di produzione elenca 38 operazioni metodo/percorso su 37 percorsi. Ogni operazione qui sotto è vincolata allo scope indicato:

Metodo Percorso Scope
POST /v1/agent/accounts none
POST /v1/agent/accounts/{signup_id}/claim none
POST /v1/agent/credentials/rotate pat:rotate
GET /v1/account account:read
POST /v1/billing/setup-session billing
GET /v1/billing/cards billing
POST /v1/billing/cards/default billing
GET /v1/billing/packs billing
POST /v1/billing/purchase billing
GET /v1/billing/transactions account:read
GET /v1/billing/ledger account:read
GET /v1/billing/holds account:read
POST /v1/uploads transcribe
GET /v1/uploads/{job}/part-urls transcribe
PUT /v1/uploads/{job}/parts/{n} transcribe
POST /v1/uploads/{job}/heartbeat transcribe
POST /v1/uploads/{job}/complete transcribe
GET /v1/jobs transcribe
GET /v1/jobs/{id} transcribe
GET /v1/transcripts transcripts:read
GET /v1/transcripts/deleted transcripts:read
GET /v1/transcripts/{id} transcripts:read
GET /v1/transcription-context context
GET /v1/org org:read
GET /v1/org/members org:read
PATCH /v1/org/members/{user_id} org:write
GET /v1/org/matters org:read
GET /v1/org/transcripts org:read
POST /v1/org/transcripts/{id}/hold org:write
DELETE /v1/org/transcripts/{id}/hold org:write
POST /v1/org/custody org:write
GET /v1/org/invoices org:read
GET /v1/org/ledger org:read
GET /v1/org/ledger.csv org:read
GET /v1/org/usage org:read
GET /v1/org/usage.csv org:read
GET /v1/org/audit org:read
GET /v1/org/audit.csv org:read

/v1/agent/accounts avvia una registrazione headless senza ancora un token, /v1/agent/accounts/{signup_id}/claim trasforma una registrazione a pagamento in un account vero e nel suo primo token, e /v1/agent/credentials/rotate genera un successore per il token chiamante e lo ritira al primo uso del successore, senza toccare nessun’altra credenziale sull’account. La guida Uso automatizzato copre tutti e tre per intero.

Ogni elenco accetta un limit e un cursor opaco, e risponde con un next_cursor che è null sull’ultima pagina. Restituisci il cursore invariato; codifica la posizione, così una pagina non viene mai saltata o ripetuta quando arrivano nuove righe tra una chiamata e l’altra.

La definizione completa e aggiornata, con parametri e schemi di risposta per ogni operazione, è il documento OpenAPI: trattalo come fonte di verità rispetto a questa tabella. Viene servito a qualsiasi token bearer indipendentemente dallo scope, così un client può recuperarlo con le credenziali che già possiede.

Interfaccia MCP

Preferisci gli strumenti alle chiamate HTTP dirette? Il server MCP espone lo stesso account tramite 56 strumenti anziché questi endpoint, per un client che usa già MCP invece di REST. Pubblica solo gli strumenti consentiti dagli scope del token connesso.

Limiti

Le richieste effettuate con il token di un account umano sono limitate a 1.200 al minuto per token. I token ruotati di un account agente condividono quel budget a livello di account. Le rotte di fatturazione che chiamano Stripe condividono un budget più stretto di 60 al minuto per account per i chiamanti PAT: sessione di configurazione, acquisto, cambio della carta predefinita, rimozione della carta e richieste dell’elenco carte non presenti nella cache. La limitazione ordinaria risponde 429 rate_limited con Retry-After in secondi; attendi quel tempo prima di riprovare. Gli acquisti di un account agente o effettuati con il PAT di un account umano condividono un tetto di 3 tentativi per ogni intervallo mobile di 24 ore per account. L’acquisto di registrazione dell’agente conta; contano anche i rifiuti o gli errori dopo che un tentativo è stato riservato. Un acquisto da una sessione browser umana è escluso. Un rifiuto per il tetto risponde con HTTP 429, 4038 agent_purchase_capped e Retry-After. Le registrazioni possono durare da 15 secondi a 10 ore. GET /v1/account riporta gli attuali limiti di ammissione dell’account (max_active_jobs, max_daily_seconds).

Sandbox

Non esiste una sandbox generale per la trascrizione: le normali chiamate /v1/ vengono eseguite su account reali e gli acquisti spendono denaro vero. L’eccezione è la convalida della registrazione: POST /v1/agent/accounts accetta dry_run: true, restituisce un id di registrazione dry_ non utilizzabile per attivare un account e non apre alcuna sessione Stripe né alcun account.

Errori

Un errore è un corpo JSON che contiene un code numerico stabile e uno slug error, allo stato HTTP mostrato sotto. I corpi di errore /v1/ sono una proiezione congelata: error, code e un insieme fisso di chiavi di dettaglio. La struttura degli errori di /api non è congelata e può contenere altri campi. I codici che un chiamante automatizzato deve gestire:

Stato Codice Slug Significato
401 2000 unauthorized Token bearer mancante o non valido
403 2022 pat_forbidden La rotta non accetta alcun token
403 2023 pat_scope_missing Al token manca lo scope richiesto da questa chiamata, oppure la fatturazione è disattivata per l’account
403 4021 pat_purchase_requires_app Non è stata indicata nessuna carta salvata, oppure l’addebito è stato rifiutato; nessun importo è stato addebitato
403 4023 pat_purchase_requires_authentication L’emittente della carta richiede una verifica che chi chiama non può completare; la carta in sé è valida
402 3001 insufficient_balance Saldo insufficiente per ammettere il job
402 3002 card_declined La carta salvata è stata rifiutata
402 3003 org_insufficient_balance Il pool dello spazio di lavoro che finanzia questo caricamento è insufficiente
404 4000 not_found Nessun job, caricamento o risorsa di questo tipo
409 4001 wrong_state La risorsa non si trova in uno stato che consente questa operazione
422 1021 duration_out_of_range La durata dichiarata è inferiore a 15 secondi o superiore a 10 ore
429 4038 agent_purchase_capped L’account ha esaurito i tentativi di acquisto consentiti tramite token; attendi il tempo indicato da Retry-After
429 5000 rate_limited Troppe richieste; attendi il valore di Retry-After
502 6001 provider_error Un servizio a monte è fallito
500 9000 internal_error Un errore inatteso del server

Il documento OpenAPI indica il codice esatto che ogni operazione può restituire, e il server MCP pubblica il catalogo completo come risorsa hushscript://error-codes.

Inizia a trascrivere con 30 minuti da provare

Prova un’anteprima fino a 5 minuti prima di creare un account; un nuovo account personale riceve inoltre un’anteprima gratuita del primo caricamento nell’app. La trascrizione completa richiede un account e minuti; gli account personali idonei ricevono 30 minuti gratuiti una sola volta, dopo la verifica della carta o con il primo acquisto. Nessun abbonamento.

Inizia con 30 minuti gratuiti