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": "Jung",
"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)
languagede, 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 10.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.
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, 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) · 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)