Référence
API v1 — endpoints
GET/api/v1/voicesCatalogue de voix : id, langue, genre, style, licence, extrait
GET/api/v1/voices/{voice}/avatarAvatar de voix (image importée ou dégradé généré)
GET/api/v1/languagesLangues prises en charge : code, nom, niveau, nombre de voix
POST/api/v1/ttsSynthèse vocale → WAV ou MP3 (paramètre format)
POST/api/v1/tts_streamSynthèse en streaming (PCM découpé) pour une faible latence — un flux propre sans post-effets et sans mp3
POST/api/v1/voices/createCréer une voix : name, audio_b64 (≤10 MB base64), ref_text (=audio mot pour mot), consent="voice-data-consent,privacy", language? → voice id
GET/api/v1/voices/mineVos propres voix (clones créés + achetées) : voice (slug), name, language, kind, sample_url — clé API requise
POST/api/v1/transcribeTranscrire un court fragment : audio_b64, language? (nom complet) → texte. La durée compte dans la limite mensuelle de minutes de transcription du plan
GET/api/v1/statusÉtat de préparation du moteur (agents en temps réel) : ready, model_ready, engine_up, latency_ms
POST/api/v1/warmupPréparer le moteur avant une session d’appel (sans facturer de caractères)
GET /api/v1/voices — filtres : q (recherche par nom/style), language (ru, en, de…), gender (male/female), limit (par défaut 200, max 500), offset. Passez le champ voice de la réponse à 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"
}
]
}
Avatars & langues. Avatar : 302 vers l’image ou un dégradé SVG — insérez-le directement dans <img>. Langues : tier = principal (prêt) | beta | bientôt.
# 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" />
Accès
Authentification
Tous les endpoints nécessitent une clé API : l’en-tête X-API-Key: <key> ou Authorization: Bearer <key> (sauf GET /api/v1/voices, GET /api/v1/status, GET /api/v1/languages et GET /api/v1/voices/{voice}/avatar — ouverts). La clé est créée dans votre compte → la section “API” ; l’API est disponible à partir du plan Starter et au-delà (sinon 403). La synthèse facture les caractères sur le plan de la clé — à solde nul, elle renvoie 402. La limite de débit dépend du plan : Starter — 30 requêtes/min, Pro — 120, Business — 300, Scale — 600 (repli 60) ; au-delà → 429, l’en-tête Retry-After.
POST /api/v1/tts
Paramètres
voiceID de voix depuis GET /api/v1/voices. ⚠️ Si le champ est manquant, la synthèse revient à la voix par défaut (de_at_n1) et des caractères sont quand même facturés — passez toujours l’ID explicitement.
texttexte à voix ; la longueur max dépend du plan de la clé (requis)
languagede, en, ru, fr, es, it, pt, zh, ja, ko (ainsi que de-DE, en-US …) et noms complets (allemand, anglais …). Plus Auto : le moteur détecte la langue à partir du texte — le seul moyen de synthétiser une langue beta avec votre propre voix.
instructémotion/style en anglais, par ex. "calm, friendly" (opt.)
emotionémotion de voix de studio (pour les voix avec des références émotionnelles enregistrées) : joyeux, excité, tendre, calme, triste, sérieux, tendu, en colère, effrayé, surpris (opt. ; sans le paramètre — neutre)
saturationsaturation/« coloration » harmonique du timbre (post-traitement) : {"preset":"tube"|"tape"|"air","intensity":0–1} (opt.)
speedtempo de parole 0.5–2.0 (opt.) Les valeurs hors plage sont ramenées à la borne la plus proche ; la réponse porte alors X-Effects-Failed: speed_clamped_to_….
gain_dbvolume −24…+24 dB (opt.)
eqégaliseur du timbre : {"bands":[{"hz":80,"db":4}, …]} (opt.)
effectpréréglage sonore : radio, audiobook, podcast, phone, cinematic, megaphone, vintage, deep, bright, warm, narrator_warm, intimate, spacious, whisper, concert ; personnages : robot, cartoon, chipmunk, monster, villain, echo_hall ; studio : studio_announcer, studio_natural, studio_rich. Les effets Premium (characters, studio, cinematic, concert, megaphone, vintage) — uniquement sur les offres payantes, sinon ignorés (opt.)
seedun nombre pour répéter de façon déterministe le même voiceover (opt.)
cleantrue — débruitage neuronal (séparé de effect, opt.)
backgroundfond/ambiance : rain, thunder, sea, forest, birds, wind, stream, night, street, cafe, crowd, fire (opt.)
bg_levelvolume du fond 0.05–0.8 (opt., par défaut 0.25)
lead_silence_mssilence au début de l'audio, ms (opt., pour les agents ; par défaut 0)
format"wav" (par défaut) ou "mp3" (opt.)
response_formatSortie téléphonie (B2B/IVR) : g711_alaw_8k, g711_ulaw_8k, g722_16k, opus, pcm_s16le_24k. La réponse est le flux du codec + l'en-tête X-Audio-Format (opt.)
containeravec response_format uniquement : wav (conteneur, par défaut) ou raw (frames brutes pour SIP/RTP) (opt.)
La réponse est un fichier audio binaire : audio/wav ou audio/mpeg (si format=mp3) ; pour un response_format de téléphonie, le conteneur de codec correspondant (voir X-Audio-Format).
POST /api/v1/tts_stream
Synthèse en streaming
Accepte voice, text, language, instruct, speed, gain_db, eq, effect, background, bg_level, saturation, seed et segments (jusqu'à 40 éléments : text, instruct jusqu'à 200 caractères, silence 0–3000 ms). Réponse : PCM brut — 24 kHz, 16 bits, mono, little-endian (application/octet-stream, chunked) ; il n'y a pas d'en-tête WAV, définissez vous-même la fréquence d'échantillonnage.
# 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
Créer une voix
namenom de la voix (obligatoire)
audio_b64extrait audio en base64, ≤10 Mo (obligatoire)
ref_textTranscription de l’enregistrement — mot pour mot, max. 2000 caractères (plus long → 400 ref_text_too_long). Si le texte ne correspond pas à l’audio, la voix sonne de travers.
consentchaîne de consentement — passer exactement "voice-data-consent,privacy" (données vocales, GDPR) ; sinon — 400 (required)
languagelangue de l’échantillon, nom complet (russe, anglais…) ou code ISO ; allemand par défaut (opt.)
Passez le champ voice de la réponse à POST /tts. La valeur voice ci-dessous est un exemple illustratif ; le véritable identifiant vient dans la réponse. La création de votre propre voix est disponible avec un forfait payant ; le nombre de vos propres voix est illimité — en créer une coûte 10.000 caractères de votre solde (le stockage et l’utilisation sont gratuits).
# Response — 200 OK (voice value is an example)
{
"ok": true,
"voice": "usr_a1b2c3",
"name": "My voice",
"language": "German"
}
GET /api/v1/voices/mine
Vos propres voix
GET /api/v1/voices ne renvoie que le catalogue public. Pour obtenir VOS propres voix — celles créées via l’API et celles générées dans votre compte/studio — authentifiez-vous avec votre clé API et appelez cet endpoint. Il renvoie vos propres clones (kind="own") et les voix achetées sur le Marketplace (kind="marketplace"). Passez le champ voice (slug) à 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 vaut null pour les propres voix (non stocké) ; sample_url peut être null si aucun échantillon n’existe. Lors de la synthèse avec votre propre voix, la langue est prise depuis la voix et remplace le paramètre language dans POST /tts.
Flux complet à copier-coller — créer, lister, synthétiser (remplacez la clé d’exemple par la vôtre depuis Compte → 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
Transcription
audio_b64audio en base64 ; prévu pour un court fragment (required)
languageuniquement le nom COMPLET de la langue : russe, anglais, allemand, français, italien, espagnol, portugais, chinois, japonais, coréen — plus 14 langues bêta (bulgare, tchèque, grec, ukrainien, polonais et autres) comme indice de reconnaissance, ainsi que la chaîne littérale "auto" (les codes ISO ne sont PAS acceptés ici, contrairement à /tts ; sans le paramètre — détection automatique) (opt.)
Les caractères sont facturés selon le forfait (≈ 1 min d’audio = 1000 caractères) ; la limite mensuelle de minutes de transcription du forfait s’applique.
# 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
Statut et préchauffage
GET /api/v1/status (sans clé) — disponibilité du moteur en temps réel. POST /api/v1/warmup (avec une clé ; ne facture AUCUN caractère) préchauffe le moteur avant une série d’appels.
# 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
}
Réponse
En-têtes et champ code
Content-Typeaudio/wav ou audio/mpeg (selon le paramètre format) ; pour /tts_stream — application/octet-stream
X-Effects-Failedeffets qui n’ont PAS été appliqués (sur le moteur ou tronqués par le forfait), séparés par des virgules — l’audio revient sans eux
X-CacheHIT / MISS — indique si la réponse provient du cache. Remarque : avec une clé API, un HIT du cache est facturé comme un MISS (le cache économise du temps de génération, pas des caractères).
Retry-Afteren cas de 429 — dans combien de secondes retenter la requête
Le champ code dans le corps d’erreur (lisible par machine) : plan_required — un plan supérieur est nécessaire ; voice_limit — la limite de voix du plan ; plan_quota — la limite mensuelle de minutes de transcription est atteinte ; email_unverified — vérifiez votre e-mail ; voice_conflict — le nom de la voix est déjà pris (lors de la création d’une voix).
Codes de réponse
Erreurs
200Succès — le corps de la réponse contient le fichier audio
400JSON invalide ou texte vide. Une langue inconnue renvoie le 4xx du moteur (p. ex. 400) avec le code engine_bad_request — identique sur /v1/tts et /v1/tts_stream
401Clé API manquante ou invalide (en-tête X-API-Key / Authorization)
402Nombre de caractères insuffisant sur le solde de la clé — rechargez le plan
403La fonctionnalité n’est pas disponible sur le plan actuel (p. ex. API — à partir de Starter, voix personnalisée — à partir d’un plan payant) ou pas d’accès à la voix
409Conflit (voice_conflict) : une voix avec ce nom existe déjà — choisissez un autre nom lors de la création d’une voix
413Fichier trop volumineux : pour une voix personnalisée, l’audio fait plus de 10 MB (base64)
429Limite de débit dépassée (par plan : Starter 30, Pro 120, Business 300, Scale 600 par minute ; /voices/create 5/min, /warmup 20/min). Respectez l’en-tête Retry-After. Code : rate_limited.
500Erreur interne (par ex. la base de données est indisponible sur GET /v1/voices) — réessayez plus tard.
502Le moteur de synthèse/transcription n’a pas répondu (Bad Gateway) — attendez un instant puis réessayez
503Le moteur est en veille/indisponible ou le service est surchargé — réessayez dans quelques secondes
Le corps d’erreur est du JSON { "error": "description", "code": "machine-readable" }. Valeurs possibles de 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. En cas d’échec, aucun caractère n’est facturé — sauf si le client interrompt un flux (l’audio livré est facturé au prorata).
Tous les codes d’erreur
Liste complète des codes machine dans le champ code : auth_required (401) · plan_required (403, API depuis 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, avec Retry-After) · engine_bad_request (moteur 4xx) · engine_error, engine_unavailable, engine_not_configured, temporarily_unavailable, mp3_failed, telephony_failed, transcribe_failed (5xx) · client_abort (499, le client a interrompu la connexion).
Remarques
Détails pratiques faciles à manquer : le corps de la requête est limité à 2 MB pour /v1/tts et /v1/tts_stream (413 sinon) et à 30 MB en base64 pour /v1/transcribe · speaker est un synonyme de voice · le marqueur de pause ‖ (U+2016) placé dans le texte produit exactement 400 ms de silence · instruct est tronqué silencieusement à 500 caractères et lead_silence_ms est plafonné à 5000 · sans seed, la valeur 4242 est utilisée, donc la sortie est reproductible par défaut (modifiez vous-même la seed si vous voulez de la variation) · sans language, l’allemand est supposé · GET /v1/languages accepte ?locale · la limite de débit est comptée par point de terminaison séparément ; limites propres : /voices/create 5/min, /warmup 20/min, /voices/mine 60/min, points de terminaison GET ouverts 120/min par IP · POST /v1/voices/clone est un alias de /voices/create.
Catalogue
Effets et arrière-plans
Le paramètre effect — un préréglage par requête. Les gratuits sont disponibles pour tous ; les premium — sur les offres payantes.
Delivery (gratuit)radio — diffusion sèche · audiobook — livre audio · narrator_warm — narrateur chaleureux · podcast — podcast · phone — téléphone · intimate — rapproché · spacious — ample · whisper — chuchoté · deep — plus grave · bright — plus clair · warm — plus chaud
Studio (premium)studio_announcer — annonceur diffusion · studio_natural — studio naturel · studio_rich — riche « cher » · cinematic — cinéma · concert — salle de concert · megaphone — mégaphone · vintage — vintage
Personnages (premium)robot — robot · cartoon — cartoon · chipmunk — tamia · monster — monstre · villain — méchant · echo_hall — salle d’écho
Arrière-plans (fond)Nature : rain (pluie) · thunder (orage) · sea (mer) · forest (forêt) · birds (oiseaux) · wind (vent) · stream (ruisseau) · night (nuit). Ville : street (rue) · cafe (café) · crowd (foule). Cosy : fire (cheminée). Volume — bg_level 0.05–0.8
eq (timbre)8 bandes : 80, 160, 300, 600, 1500, 3500, 6500, 10500 Hz, chacune −12…+12 dB. Exemple : {"bands":[{"hz":80,"db":-4},{"hz":3500,"db":3}]} — supprimer les ronflements, ajouter de la clarté
Quotas
Limites
Débit de requêtesselon le plan de la clé : Starter — 30/min, Pro — 120/min, Business — 300/min, Scale — 600/min. Points de terminaison avec leur propre limite stricte, quel que soit le plan : POST /v1/voices/create — 5/min, POST /v1/warmup — 20/min, GET /v1/status — 60/min par IP, GET /v1/voices — 120/min par IP.
Longueur du textele nombre maximal de caractères par POST /api/v1/tts dépend du plan de la clé
Solde de caractèresla synthèse débite des caractères du plan de la clé ; à solde nul — 402
Transcription≈1 min d’audio = 1000 caractères ; les minutes mensuelles du plan s’appliquent : Pro 100, Business 300, Scale 800 min. Free et Starter n’incluent AUCUNE transcription — l’API répond 403 (plan_required). Quota épuisé → 403 (plan_quota).
Taille du fichiercréation de voix : échantillon ≤10 MB (base64), sinon 413
Exemple
Requête complète
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)