The short answer: cloning a voice with MiniMax takes two API calls, and the result works with the standard OpenAI text-to-speech SDK. First upload a recording of 10 seconds to 5 minutes (.mp3, .m4a or .wav, up to 20 MB) to POST https://api.hop-base.com/v1/files/upload with purpose=voice_clone. Then call POST /v1/voice_clone with the returned file_id and a voice_id you choose. From then on, pass that voice_id as voice to the OpenAI-compatible /v1/audio/speech endpoint with speech-2.8-hd or speech-2.8-turbo. In the OpenAI SDK, that means changing only base_url, model and voice. Uploading and cloning are free. The published clone fee is $1.5 per voice, charged once on the voice's first successful synthesis. Speech is billed per character: $100 per million on HD and $60 per million on Turbo, and each Chinese character counts as 2. A cloned voice that is not used within 7 days is deleted, and no clone fee is charged for it.
What you need before you start
- A HopBase API key whose group includes the MiniMax Speech models (
speech-2.8-hd,speech-2.8-turbo). You can add this group to a key you already use for chat or video. Confirm withGET /v1/models. - A clean recording of the voice: 10 seconds to 5 minutes long,
.mp3,.m4aor.wav, at most 20 MB. One speaker, little background noise, and natural pacing give the best results. - The right to use the voice. Clone only your own voice, or a voice whose speaker has given you explicit written permission. You are responsible for lawful use, including rules on deep synthesis and likeness.
Step 1: upload the recording
POST /v1/files/upload takes multipart/form-data with exactly two fields, purpose and file. Any other field returns 400.
curl https://api.hop-base.com/v1/files/upload \
-H "Authorization: Bearer sk-YOUR_KEY" \
-F purpose=voice_clone \
-F file=@my_voice.mp3
# → {"file":{"file_id":123456789,"bytes":...,"filename":"my_voice.mp3","purpose":"voice_clone"},"base_resp":{...}}
Format and size are checked at upload, and duration is checked when you clone. If you also want to give the model a short example clip, upload it separately with purpose=prompt_audio. It must be under 8 seconds.
Step 2: clone the voice
curl https://api.hop-base.com/v1/voice_clone \
-H "Authorization: Bearer sk-YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"file_id": 123456789,
"voice_id": "MyNarrator01",
"text": "Hello, this is my cloned voice.",
"model": "speech-2.8-hd",
"need_noise_reduction": true
}'
The fields that matter:
| Field | Rules |
|---|---|
file_id | Required. The integer from step 1. Each file can be used only once. |
voice_id | Required. 8-256 characters: letters, digits, - and _. It must start with a letter, must not end with - or _, and must be unique in your account. |
text + model | Optional preview script of up to 1,000 characters. If you send text, model is required. The response then includes demo_audio, a preview link valid for 24 hours, and the preview is billed as speech characters. |
clone_prompt | Optional: {"prompt_audio": <file_id>, "prompt_text": "..."}. Both keys are required. prompt_text is the exact transcript of the clip and ends with punctuation. |
text_validation / accuracy | Optional quality check. Provide the expected transcript (up to 200 characters) and a pass threshold from 0 to 1 (default 0.7). The clone fails if speech recognition does not match. |
need_noise_reduction, need_volume_normalization, aigc_watermark | Optional booleans, all false by default. |
Because the flow mirrors MiniMax's official voice-cloning API, code written against MiniMax's own SDK works after you change the base URL and key.
Step 3: use the cloned voice with the OpenAI SDK
This is the main reason to use the OpenAI-compatible endpoint. Your existing client.audio.speech.create code keeps working, and the only change is that voice becomes your new voice_id:
from openai import OpenAI
client = OpenAI(base_url="https://api.hop-base.com/v1", api_key="sk-YOUR_KEY")
response = client.audio.speech.create(
model="speech-2.8-turbo",
voice="MyNarrator01", # your cloned voice_id
input="Welcome back. Here is today's product update.",
response_format="mp3",
)
response.write_to_file("update.mp3")
Or with curl:
curl https://api.hop-base.com/v1/audio/speech \
-H "Authorization: Bearer sk-YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "speech-2.8-turbo", "input": "Hello again.", "voice": "MyNarrator01"}' \
--output cloned.mp3
Limits on the OpenAI-compatible endpoint: input can be up to 4,096 characters. response_format can be mp3, opus, flac, wav or pcm (aac returns 400). speed can be from 0.25 to 4. The response is the raw audio, returned in one piece. Fields from the native API such as voice_setting or language_boost are rejected on this endpoint.
When to use the native endpoint instead
For long scripts, emotion control or streaming, call POST /v1/t2a_v2 and pass the voice as voice_setting.voice_id. It accepts up to 10,000 characters and supports stream: true. In our measurements on short text, the synchronous endpoints returned the whole clip in about 1.5-2.4 seconds, and with streaming the first audio chunk arrived after roughly 1 second. When streaming, set stream_options.exclude_aggregated_audio: true. Otherwise the final event repeats the whole clip and a simple append doubles your audio. Full parameters are in the text-to-speech docs.
Lifecycle rules that catch people out
- Uploads can be used only once. A successful clone deletes both the source file and the prompt file, so to clone again you need to upload again. A failed clone keeps the files so you can retry.
- Unused uploads expire after 24 hours. Deleting a file never affects voices you have already cloned.
- Use the voice within 7 days. A cloned voice that is not used for synthesis within 7 days of cloning is deleted, and in that case no clone fee is charged. Synthesizing even a short sentence keeps it.
- Voices are private. A cloned voice belongs to your account. On an enterprise account it is shared by the member keys under the owner. Other accounts cannot use it even if they know the
voice_id. - Management is free.
POST /v1/get_voicewith{"voice_type": "voice_cloning"}lists your voices, andPOST /v1/delete_voicedeletes one and frees its name.
What it costs
| Item | Published price |
|---|---|
| Upload and clone | Free |
| Clone fee | $1.5 per voice, charged once on the voice's first successful synthesis |
speech-2.8-hd | $100 per 1M billed characters |
speech-2.8-turbo | $60 per 1M billed characters |
Billed characters: every Unicode character counts as 1, and each Han (CJK) character counts as 2. Punctuation, spaces, emoji and pause markers like <#0.5#> count as 1. So Hello, world. is 13 billed characters. A script of about 6,000 English characters costs about $0.36 on Turbo or $0.60 on HD at list price, plus the one-time $1.5 the first time a new voice is used. The clone fee shows up as a separate voice_clone_activation line in that request's usage record. Requests rejected with 400 or that fail during synthesis are not billed. See the pricing page for current list prices; your group's rate is in the signed-in model catalog.
Common errors
| Message | What to do |
|---|---|
file_id ... does not exist; uploaded files are single-use and expire 24 hours after upload | Upload the recording again |
voice_id ... already exists | Choose another name, or delete the old voice first |
audio duration out of range | The source must be 10 s to 5 min, and the prompt clip under 8 s |
voice id not exist | Typo, or the voice was deleted or expired after 7 days unused. Clone again. |
voice cloning is temporarily unavailable (503) | Retry later |
An alternative: Doubao voice cloning
HopBase also offers ByteDance's seed-icl-2.0 (Doubao Voice Cloning 2.0), which is set up differently. The recording goes into the JSON body of POST /v1/voice_clone as base64 (up to 10 MB, body up to 16 MiB), and every call needs "model": "seed-icl-2.0". You get back a voice_id starting with hbv_, which you use only with seed-icl-2.0 on /v1/audio/speech. There is no clone fee, and synthesis is ¥3 per 10,000 characters at the official list price. During the beta each account keeps one cloned voice. If you use both MiniMax and Doubao cloning, use a separate key for each. Details are in the same speech docs.
FAQ
Can I use a MiniMax cloned voice with the OpenAI Python SDK?
Yes. Point the client at https://api.hop-base.com/v1, set model to speech-2.8-hd or speech-2.8-turbo, and pass your voice_id as voice in client.audio.speech.create. Nothing else in your code needs to change.
How long should the source recording be?
Between 10 seconds and 5 minutes, as .mp3, .m4a or .wav, up to 20 MB. An optional prompt clip must be under 8 seconds.
When is the $1.5 clone fee charged?
Once, with the voice's first successful synthesis. Uploading and cloning are free, and the preview text in the clone call is billed only as speech characters, not as first use. If you never use the voice and it expires after 7 days, no clone fee is charged.
Why did my cloned voice stop working?
Most often it was never used for synthesis within 7 days of cloning, so it was deleted. Run POST /v1/get_voice to check, and clone again if needed. You will need to upload the recording again, because uploads can be used only once.
Can I stream speech in a cloned voice?
Yes, on the native POST /v1/t2a_v2 endpoint with stream: true and voice_setting.voice_id set to your voice. The OpenAI-compatible endpoint returns the full clip in one response and does not support stream_format.
How do I tell the model which language the text is in?
Use language_boost, which is available on the native endpoint and in the clone call. It has 40 options, including English, Chinese, Cantonese (Chinese,Yue), Japanese, Korean, Spanish, French, German, Arabic and Hindi, plus auto to detect the language. How well a cloned voice sounds in a language other than the one it was recorded in depends on the source audio, so test with a short preview first. The full list is in the speech docs.