Il servizio è in modalità di test — il beta testing è in corso. Sono possibili errori.
Home/Documentazione API

Documentazione API per integrazioni

API REST per voiceover, generazione in streaming, catalogo voci, creazione della tua voce e trascrizione.

# Text-to-speech (voice — id from GET /api/v1/voices) curl https://hancvoice.com/api/v1/tts \ -H "X-API-Key: $HANCVOICE_KEY" \ -H "Content-Type: application/json" \ -d '{ "voice": "de_at_f1", "text": "Hallo! Das ist HancVoice.", "language": "de" }' --output out.wav
import fs from "node:fs/promises"; const response = await fetch("https://hancvoice.com/api/v1/tts", { method: "POST", headers: { "X-API-Key": process.env.HANCVOICE_KEY, "Content-Type": "application/json" }, body: JSON.stringify({ voice: "de_at_f1", text: "Hallo! Das ist HancVoice.", language: "de" }) }); const audio = Buffer.from(await response.arrayBuffer()); await fs.writeFile("out.wav", audio);
import os, requests response = requests.post( "https://hancvoice.com/api/v1/tts", headers={ "X-API-Key": os.environ["HANCVOICE_KEY"], "Content-Type": "application/json", }, json={ "voice": "de_at_f1", "text": "Hallo! Das ist HancVoice.", "language": "de", }, ) open("out.wav", "wb").write(response.content)
REST
interfaccia di integrazione
Motore
generazione voiceover
318
voci nel catalogo
WAV
formato di risposta API
Funzionalità

Pensato per l'integrazione

Generazione sincrona

Una richiesta POST restituisce un file WAV pronto.

REST senza SDK

Esempi per cURL, Node.js e Python su HTTP semplice.

Modalità streaming

Un endpoint separato per gli scenari di streaming.

10 lingue + Auto

Un solo endpoint, parametro lingua: russo, inglese, tedesco, francese, spagnolo, italiano, portoghese, cinese, giapponese e coreano.

Di sistema, personalizzate e varianti

Usa la libreria, le voci personalizzate salvate e le varianti sonore.

Hosting EU

Server in EU, GDPR.

Riferimento

API v1 — endpoint

GET/api/v1/voicesCatalogo voci: id, lingua, genere, stile, licenza, campione
GET/api/v1/voices/{voice}/avatarAvatar voce (immagine caricata o gradiente generato)
GET/api/v1/languagesLingue supportate: codice, nome, livello, numero di voci
POST/api/v1/ttsSintesi vocale → WAV o MP3 (parametro format)
POST/api/v1/tts_streamSintesi in streaming (PCM a blocchi) per bassa latenza — uno stream pulito senza post-effetti e senza mp3
POST/api/v1/voices/createCrea una voce: name, audio_b64 (≤10 MB base64), ref_text (=audio parola per parola), consent="voice-data-consent,privacy", language? → voice id
GET/api/v1/voices/mineLe tue voci (cloni creati + acquistate): voice (slug), name, language, kind, sample_url — richiesta la chiave API
POST/api/v1/transcribeTrascrivi un breve frammento: audio_b64, language? (nome completo) → testo. La durata conta nel limite mensile di minuti di trascrizione del piano
GET/api/v1/statusProntezza del motore (agenti in tempo reale): ready, model_ready, engine_up, latency_ms
POST/api/v1/warmupRiscalda il motore prima di una sessione di chiamata (senza addebitare caratteri)

GET /api/v1/voices — filtri: q (cerca per nome/stile), language (ru, en, de…), gender (male/female), limit (predefinito 200, max 500), offset. Passa il campo voice della risposta a POST /tts.

# GET /api/v1/voices?language=ru&gender=male&limit=200 { "object": "list", "total": 152, "count": 152, "voices": [ { "voice": "de_at_f1", "name": "Greta", "language": "de-AT", "gender": "female", "style": "Young", "description": "Female voice — Austrian German, young, joyful, for presentations.", // in the response language (?locale=) "labels": { // filter on the *_key fields: they are stable and never translated "gender": "female", "language": "de-AT", "language_name": "Austrian German", "accent": "Austrian German", "age": "young", // age is "" unless the catalogue marks it "style": "Young", "style_key": "young", "use_case": "presentations", "use_case_key": "presentations", "emotion": "joyful", "emotion_key": "joyful" }, "license": "commercial", "badge": null, // null | "beta" | "soon" (soon = synthesis disabled) "sample_url": "https://hancvoice.com/api/v1/voices/de_at_f1/sample", // permanent link, redirects to the current file "avatar_url": "https://hancvoice.com/api/v1/voices/de_at_f1/avatar" } ] }

Avatar e lingue. Avatar: 302 all'immagine o a un gradiente SVG — inseriscilo direttamente in <img>. Lingue: tier = principale (pronto) | beta | soon.

# GET /api/v1/languages — supported languages (code, name, tier, voice count) { "object": "list", "total": 24, "languages": [ { "code": "de", "name": "German", "native_name": "Deutsch", "tier": "main", "voice_count": 32 } ] } # GET /api/v1/voices/{voice}/avatar → 302 to image, or a generated SVG. Use directly in <img src>. <img src="https://hancvoice.com/api/v1/voices/de_at_f1/avatar" width="64" />
Accesso

Autenticazione

Tutti gli endpoint richiedono una chiave API: l'header X-API-Key: <key> o Authorization: Bearer <key> (eccetto GET /api/v1/voices, GET /api/v1/status, GET /api/v1/languages e GET /api/v1/voices/{voice}/avatar — aperti). La chiave viene creata nel tuo account → sezione “API”; l'API è disponibile dal piano Starter in su (altrimenti 403). La sintesi addebita caratteri sul piano della chiave — con saldo zero restituisce 402. Il rate limit dipende dal piano: Starter — 30 richieste/min, Pro — 120, Business — 300, Scale — 600 (fallback 60); il superamento → 429, intestazione Retry-After.

POST /api/v1/tts

Parametri

voiceID voce da GET /api/v1/voices. ⚠️ Se il campo manca, la sintesi torna alla voce predefinita (de_at_n1) e i caratteri vengono comunque addebitati — passa sempre l'ID esplicitamente.
texttesto da voce; la lunghezza massima dipende dal piano della chiave (obbligatorio)
languageDi solito non serve: la lingua viene rilevata dal testo e la voce legge il testo in quella lingua. Senza accento una voce suona solo nelle sue verified_languages (GET /api/v1/voices); nelle altre lingue mantiene il suo accento e la risposta lo segnala: X-Synthesis-Language, X-Voice-Language, X-Language-Verified: false. Il parametro conta solo per una voce senza lingua propria, quando il testo è troppo breve per rilevare la lingua: de, en, ru, fr, es, it, pt, zh, ja, ko (anche de-DE, en-US …) e nomi completi (German, English …). Più Auto: il motore rileva la lingua dal testo — l'unico modo per sintetizzare una lingua beta con la tua voce.
instructemozione/stile in inglese, ad es. "calm, friendly" (facoltativo)
emotionemozione studio-voice (per voci con riferimenti emotivi registrati): gioioso, entusiasta, tenero, calmo, triste, serio, teso, arrabbiato, impaurito, sorpreso (opt.; senza il parametro — neutro)
saturationsaturazione/“colorazione” armonica del timbro (post-processing): {"preset":"tube"|"tape"|"air","intensity":0–1} (opt.)
speedtempo del parlato 0.5–2.0 (opt.) I valori fuori intervallo vengono riportati al limite più vicino; la risposta contiene quindi X-Effects-Failed: speed_clamped_to_….
gain_dbvolume −24…+24 dB (opt.)
eqequalizzatore del timbro: {"bands":[{"hz":80,"db":4}, …]} (opt.)
effectpreset audio: radio, audiolibro, podcast, telefono, cinematografico, megafono, vintage, profondo, brillante, caldo, narrator_warm, intimo, spazioso, sussurro, concerto; personaggi: robot, cartone animato, scoiattolo, mostro, cattivo, eco_hall; studio: studio_announcer, studio_natural, studio_rich. Effetti Premium (personaggi, studio, cinematografico, concerto, megafono, vintage) — solo nei piani a pagamento, altrimenti ignorati (opt.)
seedun numero per ripetere in modo deterministico lo stesso voiceover (opt.)
cleantrue — denoising neurale (separato da effect, opt.)
backgroundsfondo/ambiente: pioggia, tuono, mare, foresta, uccelli, vento, ruscello, notte, strada, caffè, folla, fuoco (opt.)
bg_levelvolume dello sfondo 0.05–0.8 (opt., default 0.25)
lead_silence_mssilenzio all'inizio dell'audio, ms (opt., per agenti; default 0)
format"wav" (default) o "mp3" (opt.)
response_formatOutput telefonico (B2B/IVR): g711_alaw_8k, g711_ulaw_8k, g722_16k, opus, pcm_s16le_24k. La risposta è il flusso del codec + intestazione X-Audio-Format (opt.)
containersolo con response_format: wav (contenitore, default) o raw (frame grezzi per SIP/RTP) (opt.)

La risposta è un file audio binario: audio/wav o audio/mpeg (se format=mp3); per un response_format telefonico, il contenitore del codec corrispondente (vedi X-Audio-Format).

POST /api/v1/tts_stream

Sintesi in streaming

Accetta voice, text, language, instruct, speed, gain_db, eq, effect, background, bg_level, saturation, seed e segments (fino a 40 elementi: text, instruct fino a 200 caratteri, silence 0–3000 ms). Risposta: PCM grezzo — 24 kHz, 16-bit, mono, little-endian (application/octet-stream, chunked); non c'è un'intestazione WAV, imposta tu la frequenza di campionamento.

# POST /api/v1/tts_stream → PCM stream (application/octet-stream, chunked) { "voice": "de_at_f1", "text": "Hallo! Das ist Streaming-Synthese.", "language": "de" }
POST /api/v1/voices/create

Creare una voce

namenome della voce (obbligatorio)
audio_b64registrazione campione in base64, ≤10 MB (obbligatorio)
ref_textTrascrizione della registrazione — parola per parola, max 2000 caratteri (più lungo → 400 ref_text_too_long). Se il testo non corrisponde all'audio, la voce suona confusa.
consentstringa di consenso — passa esattamente "voice-data-consent,privacy" (dati vocali, GDPR); senza di essa — 400 (richiesto)
languagelingua del campione, nome completo (russo, inglese…) o codice ISO; predefinito tedesco (facolt.)

Passa il campo voice dalla risposta a POST /tts. Il valore voice qui sotto è un esempio illustrativo; l'identificatore reale arriva nella risposta. Creare la tua voce è disponibile con un piano a pagamento; il numero delle tue voci è illimitato — crearne una costa 25.000 caratteri dal tuo saldo (salvarla e usarla è gratuito).

# Response — 200 OK (voice value is an example) { "ok": true, "voice": "usr_a1b2c3", "name": "My voice", "language": "German" }
GET /api/v1/voices/mine

Le tue voci

GET /api/v1/voices restituisce solo il catalogo pubblico. Per ottenere LE TUE voci — sia quelle create tramite API sia quelle generate nel tuo account/studio — autentica con la tua chiave API e chiama questo endpoint. Restituisce i tuoi cloni (kind="own") e le voci acquistate sul Marketplace (kind="marketplace"). Passa il campo voice (slug) a POST /api/v1/tts.

# GET /api/v1/voices/mine — your own voices (API key required) curl https://hancvoice.com/api/v1/voices/mine \ -H "X-API-Key: $HANCVOICE_KEY" # Response — 200 OK { "object": "list", "count": 1, "voices": [ { "voice": "usr_a1b2c3", "name": "My voice", "language": "German", "gender": null, "kind": "own", "sample_url": "https://hancvoice.com/voice-samples/usr_a1b2c3.wav", "avatar_url": "https://hancvoice.com/generated-audio/voice-avatars/usr_a1b2c3.webp" } ] }

gender è null per le voci proprie (non memorizzato); sample_url può essere null se non esiste alcun campione. Quando sintetizzi con la tua voce, la lingua viene presa dalla voce e sostituisce il parametro language in POST /tts.

Flusso completo copia e incolla — crea, elenca, sintetizza (sostituisci la chiave di esempio con la tua da Account → API):

# Full own-voice flow — create → list (mine) → synthesize. # Example key below — replace it with your own key from Account → API. KEY="sk-live-9f3c1a7b4e2d8c6f0a5b3e1d7c9f2a4b6d8e0c1a3f5b7d9e" # 1) Create your voice (skip if you already have one in your account) curl -X POST https://hancvoice.com/api/v1/voices/create \ -H "X-API-Key: $KEY" -H "Content-Type: application/json" \ -d '{"name":"My voice","ref_text":"exact transcript of the recording","audio_b64":"<24kHz sample, base64>","consent":"voice-data-consent,privacy"}' # → {"ok":true,"voice":"usr_a1b2c3","name":"My voice","language":"German"} # 2) List your own voices → take the "voice" (slug) curl https://hancvoice.com/api/v1/voices/mine -H "X-API-Key: $KEY" # 3) Synthesize with your voice curl -X POST https://hancvoice.com/api/v1/tts \ -H "X-API-Key: $KEY" -H "Content-Type: application/json" \ -d '{"voice":"usr_a1b2c3","text":"Hallo, das ist meine eigene Stimme.","language":"de"}' --output out.wav
POST /api/v1/transcribe

Trascrizione

audio_b64audio in base64; destinato a un breve frammento (richiesto)
languagesolo il nome COMPLETO della lingua: russo, inglese, tedesco, francese, italiano, spagnolo, portoghese, cinese, giapponese, coreano — più 14 lingue beta (bulgaro, ceco, greco, ucraino, polacco e altre) come suggerimento per il riconoscimento, e il letterale "auto" (i codici ISO NON sono accettati qui, a differenza di /tts; senza il parametro — rilevamento automatico) (facolt.)

I caratteri vengono addebitati in base al piano (≈1 min di audio = 1000 caratteri); si applica il limite mensile di minuti di trascrizione del piano.

# Response — language = vom Engine erkannter ISO-Code (z. B. de, en, ru) { "text": "Transkribierter Text des Fragments.", "language": "de" }
GET /api/v1/status · POST /api/v1/warmup

Stato e warm-up

GET /api/v1/status (senza chiave) — prontezza del motore in tempo reale. POST /api/v1/warmup (con una chiave; non addebita ALCUN carattere) riscalda il motore prima di una serie di chiamate.

# GET /api/v1/status { "ready": true, "model_ready": true, "engine_up": true, "latency_ms": 42 }
# POST /api/v1/warmup { "ok": true, "warmed": true, "warm_ms": 318 }
Risposta

Header e campo code

Content-Typeaudio/wav o audio/mpeg (in base al parametro format); per /tts_stream — application/octet-stream
X-Effects-Failedeffetti che NON sono stati applicati (sul motore o ridotti dal piano), separati da virgole — l'audio viene restituito senza di essi
X-CacheHIT / MISS — se la risposta proviene dalla cache. Nota: con una chiave API un HIT nella cache viene fatturato come un MISS (la cache fa risparmiare tempo di generazione, non caratteri).
Retry-Aftersu 429 — in quanti secondi riprovare la richiesta

Il campo code nel corpo dell'errore (leggibile dalla macchina): plan_required — serve un piano superiore; voice_limit — limite voci del piano; plan_quota — il limite mensile dei minuti di trascrizione è esaurito; email_unverified — verifica la tua email; voice_conflict — il nome della voce è già in uso (quando crei una voce).

Codici risposta

Errori

200Successo — il corpo della risposta contiene il file audio
400JSON danneggiato o testo vuoto. Una lingua sconosciuta restituisce il 4xx del motore (ad es. 400) con codice engine_bad_request — lo stesso sia su /v1/tts sia su /v1/tts_stream
401Chiave API mancante o non valida (intestazione X-API-Key / Authorization)
402Caratteri insufficienti sul saldo della chiave — ricarica il piano
403La funzione non è disponibile nel piano attuale (ad es. API — da Starter, voce personalizzata — da un piano a pagamento) oppure non hai accesso alla voce
409Conflitto (voice_conflict): una voce con questo nome esiste già — scegli un altro nome quando crei una voce
413File troppo grande: per una voce personalizzata l'audio è >10 MB (base64)
429Limite di richieste superato (per piano: Starter 30, Pro 120, Business 300, Scale 600 al minuto; /voices/create 5/min, /warmup 20/min). Rispetta l'intestazione Retry-After. Codice: rate_limited. A parte: concurrency_limit (anch'esso 429) indica troppe richieste in esecuzione contemporaneamente su un account (per piano: Starter 2, Pro 3, Business 4, Scale 6 sintesi in parallelo) — riprova appena una termina. Nessun Retry-After: l'attesa dipende dalla tua stessa richiesta in corso.
500Errore interno (ad esempio il database non è disponibile su GET /v1/voices) — riprova più tardi.
502Il motore di sintesi/trascrizione non ha risposto (Bad Gateway) — attendi un attimo e riprova
503Il motore è in sospeso/non disponibile oppure il servizio è sovraccarico — riprova tra qualche secondo

Il corpo dell'errore è JSON { "error": "description", "code": "machine-readable" }. Valori possibili di code: auth_required, plan_required, rate_limited, concurrency_limit, no_credits, voice_create_credits, bad_request, empty_text, text_too_long, ref_text_too_long, name_too_long, voice_limit, voice_conflict, voice_access, plan_quota, no_audio, engine_busy, engine_unavailable, engine_error, billing_unavailable, temporarily_unavailable. In caso di errore non vengono addebitati caratteri — tranne quando il client interrompe uno stream (l'audio consegnato viene fatturato pro rata).

Tutti i codici di errore

Elenco completo dei codici macchina nel campo code: auth_required (401) · plan_required (403, API da Starter) · text_too_long, bad_request, name_required, ref_text_required, ref_text_too_long, name_too_long, audio_b64_required, consent_required, voice_required (400) · voice_access · voice_not_found (404) · no_credits (402) · body_too_large, audio_too_large (413) · concurrency_limit (429, concurrency) · rate_limited (429, con Retry-After) · engine_bad_request (engine 4xx) · engine_error, engine_unavailable, engine_not_configured, temporarily_unavailable, mp3_failed, telephony_failed, transcribe_failed (5xx) · client_abort (499, il client ha interrotto la connessione).

Note

Dettagli pratici facili da perdere: il corpo della richiesta ha un limite di 2 MB per /v1/tts e /v1/tts_stream (altrimenti 413) e di 30 MB in base64 per /v1/transcribe · speaker è sinonimo di voice · il marcatore di pausa ‖ (U+2016) inserito nel testo genera esattamente 400 ms di silenzio · instruct viene troncato silenziosamente a 500 caratteri e lead_silence_ms è limitato a 5000 · senza seed viene usato il valore 4242, quindi l'output è riproducibile per impostazione predefinita (cambia tu il seed se vuoi variazione) · senza language si assume il tedesco · GET /v1/languages accetta ?locale · il limite di richieste è conteggiato per endpoint separatamente; limiti propri: /voices/create 5/min, /warmup 20/min, /voices/mine 60/min, endpoint GET aperti 120/min per IP · POST /v1/voices/clone è un alias di /voices/create.

Catalogo

Effetti e sfondi

Il parametro effect — un preset per richiesta. Quelli gratuiti sono disponibili per tutti; premium — sui piani a pagamento.

Consegna (gratis)radio — trasmissione asciutta · audiobook — audiolibro · narrator_warm — narratore caldo · podcast — podcast · phone — telefono · intimate — vicino · spacious — spazioso · whisper — sussurro · deep — più basso · bright — più brillante · warm — più caldo
Studio (premium)studio_announcer — annunciatore broadcast · studio_natural — studio naturale · studio_rich — ricco “costoso” · cinematic — cinema · concert — sala · megaphone — megafono · vintage — vintage
Characters (premium)robot — robot · cartoon — cartone animato · chipmunk — chipmunk · monster — mostro · villain — cattivo · echo_hall — eco in sala
Sfondi (background)Natura: rain (pioggia) · thunder (temporale) · sea (mare) · forest (foresta) · birds (uccelli) · wind (vento) · stream (ruscello) · night (notte). Città: street (strada) · cafe (caffè) · crowd (folla). Accogliente: fire (camino). Volume — bg_level 0.05–0.8
eq (timbro)8 bande: 80, 160, 300, 600, 1500, 3500, 6500, 10500 Hz, ciascuna −12…+12 dB. Esempio: {"bands":[{"hz":80,"db":-4},{"hz":3500,"db":3}]} — rimuovi il rimbombo, aggiungi chiarezza
Quote

Limiti

Rate limit delle richiestein base al piano della chiave: Starter — 30/min, Pro — 120/min, Business — 300/min, Scale — 600/min. Endpoint con limite rigido proprio, indipendentemente dal piano: POST /v1/voices/create — 5/min, POST /v1/warmup — 20/min, GET /v1/status — 60/min per IP, GET /v1/voices — 120/min per IP.
Lunghezza del testoi caratteri massimi per POST /api/v1/tts dipendono dal piano della chiave
Saldo caratterila sintesi addebita i caratteri sul piano della chiave; con saldo zero — 402
Trascrizione≈1 min di audio = 1000 caratteri; si applicano i minuti mensili del piano: Pro 100, Business 300, Scale 800 min. Free e Starter NON includono la trascrizione — l'API risponde 403 (plan_required). Quota esaurita → 403 (plan_quota).
Dimensione filecreazione della voce: sample ≤10 MB (base64), altrimenti 413
Esempio

Richiesta completa

POST /api/v1/tts { "voice": "cml_de", "text": "Heute ist das Wetter wunderbar.", "language": "de", "instruct": "calm, friendly", "speed": 1.0, "effect": "podcast", "eq": { "bands": [ { "hz": 3500, "db": 3 } ] }, "background": "rain", "bg_level": 0.2, "format": "mp3" } → 200 OK, Content-Type: audio/mpeg (binary file)

Ottieni una chiave in un minuto

Ottieni una chiave API →
POST /api/v1/ttsGET /api/v1/voicesPagina SEO dell'API