Le service fonctionne en mode test — les tests bêta sont en cours. Des erreurs sont possibles.
Accueil/Documentation API

Documentation API pour les intégrations

API REST pour le doublage, la génération en flux, le catalogue de voix, la création de votre propre voix et la transcription.

# 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
interface d’intégration
Moteur
génération de doublage
318
voix dans le catalogue
WAV
format de réponse API
Fonctionnalités

Conçu pour l’intégration

Génération synchrone

Une requête POST renvoie un fichier WAV prêt à l’emploi.

REST sans SDK

Exemples pour cURL, Node.js et Python en HTTP simple.

Mode streaming

Un endpoint séparé pour les scénarios de streaming.

10 langues + Auto

Un endpoint, le paramètre de langue : russe, anglais, allemand, français, espagnol, italien, portugais, chinois, japonais et coréen.

Système, personnalisées et variantes

Utilisez la bibliothèque, les voix personnalisées enregistrées et les variantes sonores.

Hébergement EU

Serveurs en EU, GDPR.

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": "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" } ] }

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)
languageGénéralement inutile : la langue est détectée à partir du texte, et la voix lit le texte dans cette langue. Sans accent, une voix ne sonne que dans ses verified_languages (GET /api/v1/voices) ; dans les autres langues, elle garde son accent, et la réponse le signale : X-Synthesis-Language, X-Voice-Language, X-Language-Verified: false. Le paramètre ne compte que pour une voix sans langue propre, lorsque le texte est trop court pour détecter la langue : de, 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 25.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. À part : concurrency_limit (également 429) signifie trop de requêtes exécutées en même temps sur un compte (selon le forfait : Starter 2, Pro 3, Business 4, Scale 6 synthèses en parallèle) — réessayez dès qu'une se termine. Pas de Retry-After : l'attente dépend de votre propre requête en cours.
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, 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. 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) · concurrency_limit (429, concurrency) · 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)

Obtenez une clé en une minute

Obtenir une clé API →
POST /api/v1/ttsGET /api/v1/voicesPage SEO de l’API