音声合成 API
OpenAI 互換エンドポイントとネイティブエンドポイントで使える MiniMax Speech 2.8 HD / Turbo 音声合成:リクエストパラメータ、システムボイス、ストリーミング、文字数課金。
HopBase の MiniMax Speech 2.8 音声合成は、他のモデルと同じ Base URL と同じ Authorization: Bearer sk-your-key ヘッダーで利用できます。音声専用のホストや認証情報はありません。2 つの音声モデルは独立したプラン MiniMax Speech 公式に属し、チャットや動画のプランに紐づいたキーからは到達できません。
MiniMax Speech 2.8 はテキストを同期的に音声へ変換します。レスポンスが音声そのものなので、ポーリングするタスクはありません。2 つのエンドポイントは Base URL https://api.hop-base.com と Bearer 認証を共有します。OpenAI SDK からそのまま使える OpenAI 互換の POST /v1/audio/speech と、MiniMax の全パラメータとストリーミングに対応するネイティブの POST /v1/t2a_v2 です。
| モデル ID | 位置づけ | テキスト上限 |
|---|---|---|
speech-2.8-hd | 最高音質 | /v1/audio/speech は 4,096 文字、/v1/t2a_v2 は 10,000 文字 |
speech-2.8-turbo | 高速・低単価 | 同上 |
ID は大文字・小文字を区別し、エイリアスはありません。tts-1 / tts-1-hd は認識されません。MiniMax Speech 公式プランが有効なキーを使用し、GET /v1/models で ID を確認してください。
OpenAI 互換エンドポイント
POST /v1/audio/speech は OpenAI のリクエスト形式を受け付け、音声のバイト列をそのまま返します。
| フィールド | 値 | 備考 |
|---|---|---|
model | speech-2.8-hd / speech-2.8-turbo | 必須 |
input | テキスト、最大 4,096 文字 | 必須 |
voice | English_expressive_narrator や Chinese (Mandarin)_News_Anchor などの MiniMax ボイス ID、または OpenAI の名前(alloy、nova など) | OpenAI の名前はテキストの言語に応じたデフォルトボイスにフォールバックします。漢字を含む場合は標準中国語、それ以外は英語のボイスです |
response_format | mp3(デフォルト)/ opus / flac / wav / pcm | aac は非対応(400)。opus は OGG コンテナで返されます |
speed | 0.25〜4 | 範囲外は 400。範囲内の値は 0.5〜2 にクランプされます |
instructions | 受け付けますが無視されます | — |
stream_format は非対応で、指定すると 400 が返ります。レスポンスの Content-Type は response_format に応じて audio/mpeg、audio/ogg、audio/flac、audio/wav、audio/pcm のいずれかです。
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, world.",
"voice": "English_expressive_narrator",
"response_format": "mp3"
}' \
--output hello.mp3公式の openai SDK を使う場合、変えるのは Base URL と model / voice の値だけです。
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="Japanese_IntellectualSenior",
input="こんにちは、世界。",
response_format="mp3",
)
response.write_to_file("hello.mp3")
# 長いテキスト:クリップ全体をメモリに溜めず、届いたバイト列から順にディスクへ書き出す
with client.audio.speech.with_streaming_response.create(
model="speech-2.8-turbo",
voice="Japanese_IntellectualSenior",
input="ここに長めの原稿を入れます。",
) as streamed:
streamed.stream_to_file("long.mp3")ネイティブエンドポイント
POST /v1/t2a_v2 は MiniMax T2A v2 のリクエストボディをそのまま受け付けます。model、text(最大 10,000 文字)、voice_setting(voice_id、speed、vol、pitch、emotion)、audio_setting(format、sample_rate、bitrate、channel)、language_boost、stream、stream_options は変更なしで渡されます。各フィールドと受け付ける値はリクエストパラメータにまとめています。JSON レスポンスも公式の構造に従います。data.audio は 16 進数でエンコードされた音声、extra_info には usage_characters と音声のメタデータが含まれます。
output_formatはhex(デフォルト)のみ対応です。urlを指定すると 400 が返ります。voice_setting.speedは 0.5〜2 にクランプされます。audio_setting.formatが"opus"の場合はsample_rateを明示的に指定してください(例:24000)。指定しないとパラメータエラーで失敗します。stream: trueを指定すると SSE に切り替わります。各data: {...}イベントが音声チャンクを運び、最後のイベントはdata.statusが2でextra_infoを伴います。デフォルトでは最後のチャンクのdata.audioが結合済みの完全な音声です。stream_options.exclude_aggregated_audio: trueで省略できます。
import requests
resp = requests.post(
"https://api.hop-base.com/v1/t2a_v2",
headers={"Authorization": "Bearer sk-your-key"},
json={
"model": "speech-2.8-hd",
"text": "你好,世界",
"voice_setting": {"voice_id": "Chinese (Mandarin)_News_Anchor", "speed": 1.0},
"audio_setting": {"format": "mp3", "sample_rate": 32000},
},
)
body = resp.json()
open("hello.mp3", "wb").write(bytes.fromhex(body["data"]["audio"]))
print(body["extra_info"]["usage_characters"]) # 課金文字数ストリーミング:SSE のボディを 1 行ずつ読み、各 data: イベントの 16 進数チャンクをデコードしてファイルに追記します。exclude_aggregated_audio: true を指定して、最後のイベント(status が 2)が extra_info だけを運ぶようにしてください。指定しないと最後の data.audio にクリップ全体が再度入るため、単純に追記すると音声が二重になります。
import json
import requests
with requests.post(
"https://api.hop-base.com/v1/t2a_v2",
headers={"Authorization": "Bearer sk-your-key"},
json={
"model": "speech-2.8-turbo",
"text": "ここに長めの原稿を入れます。",
"stream": True,
"stream_options": {"exclude_aggregated_audio": True},
"voice_setting": {"voice_id": "Japanese_IntellectualSenior"},
"audio_setting": {"format": "mp3", "sample_rate": 32000},
},
stream=True,
timeout=(10, 300),
) as resp, open("long.mp3", "wb") as out:
resp.raise_for_status()
for line in resp.iter_lines():
if not line.startswith(b"data:"):
continue
event = json.loads(line[5:])
data = event.get("data") or {}
if data.get("audio"):
out.write(bytes.fromhex(data["audio"]))
if data.get("status") == 2:
print(event["extra_info"]["usage_characters"]) # 課金文字数リクエストパラメータ
ネイティブエンドポイントは公式の T2A v2 ボディを受け付けます。以下の値とデフォルトは公式のものです。最後の列に、HopBase の挙動が異なる箇所と、単に透過させるだけの箇所を示します。
トップレベルのフィールド
| フィールド | 値 | デフォルト | 備考 |
|---|---|---|---|
model | speech-2.8-hd / speech-2.8-turbo | — | 必須 |
text | 最大 10,000 文字 | — | 必須。段落は改行で区切ります。インライン制御は後述。公式には 3,000 文字を超える場合はストリーミングが推奨されています |
stream | true / false | false | true でレスポンスが SSE に切り替わります |
stream_options.exclude_aggregated_audio | true / false | false | true で最後のチャンクから結合済み音声を除きます |
language_boost | auto、または Chinese、Chinese,Yue、English、Arabic、Russian、Spanish、French、Portuguese、German、Turkish、Dutch、Ukrainian、Vietnamese、Indonesian、Japanese、Italian、Korean、Thai、Polish、Romanian、Greek、Czech、Finnish、Hindi、Bulgarian、Danish、Hebrew、Malay、Persian、Slovak、Swedish、Croatian、Filipino、Hungarian、Norwegian、Slovenian、Catalan、Nynorsk、Tamil、Afrikaans のいずれか | 未設定 | 指定した言語・方言の認識を強化します。auto ではモデルが自動判定します。広東語のボイスには Chinese,Yue が必要です |
pronunciation_dict.tone | 元の語/置換 形式の文字列配列 | — | 置換にはプレーンテキスト(omg/oh my god)、声調番号 1〜5 付きの括弧入りピンイン(处理/(chu3)(li3))、括弧入りの IPA(resume/(rɪˈzjuːm))、日本語のかな(東京/トウキョウ)が使えます。複数のルールは同時に適用されます |
voice_modify | pitch、intensity、timbre:-100〜100 の整数。sound_effects:spacious_echo / auditorium_echo / lofi_telephone / robotic | — | 公式の意味:pitch は低く → 明るく、intensity は力強く → 柔らかく、timbre は豊かに → 鮮明に。効果は一度に 1 つ。非ストリーミングでは mp3 / wav / flac、ストリーミングでは mp3 のみ。公式の意味どおりに透過し、ゲートウェイ側では検証していません |
output_format | hex | hex | url を指定すると 400 が返ります |
voice_setting
| フィールド | 値 | デフォルト | 備考 |
|---|---|---|---|
voice_id | システムボイスの ID。システムボイスを参照 | — | 必須 |
speed | 0.5〜2 | 1.0 | 範囲外の値はこの範囲にクランプされます |
vol | 0 より大きく 10 以下 | 1.0 | 音量 |
pitch | -12〜12 の整数 | 0 | 0 で元のピッチを保ちます |
emotion | happy / sad / angry / fearful / disgusted / surprised / calm / fluent / whisper | テキストから自動選択 | 感情を固定したいときだけ指定してください。fluent と whisper は公式には 2.6 系列向けに記載されており、whisper は Speech 2.8 では非対応と明記されています |
text_normalization | true / false | false | 中国語・英語の数字の読み上げを正規化します。レイテンシがわずかに増えます |
latex_read | true / false | false | 中国語のみ。数式は $$ で囲みます。language_boost が Chinese に固定されます |
audio_setting
| フィールド | 値 | デフォルト | 備考 |
|---|---|---|---|
format | mp3 / pcm / flac / wav / opus | mp3 | opus は Ogg/Opus 形式で、sample_rate の明示指定が必須です |
sample_rate | 8000 / 16000 / 22050 / 24000 / 32000 / 44100 | 公式に明記なし。公式の例では 32000 | — |
bitrate | 32000 / 64000 / 128000 / 256000 | 公式に明記なし。公式の例では 128000 | mp3 のみ |
channel | 1 / 2 | 1 | モノラル / ステレオ |
force_cbr | true / false | false | 固定ビットレート。ストリーミングの mp3 のみ |
テキスト内のインライン制御
- ポーズ:
<#x#>のxは秒数で、0.01〜99.99、小数点以下 2 桁まで(こんにちは<#0.5#>世界)。読み上げ可能なテキストの間に置きます。2 つ連続すると拒否されます。各マーカーは 1 文字として課金されます。 - インライン発音指定:対象の語の直後に、半角括弧で声調番号 1〜5 付きのピンイン、IPA、または声調番号 1〜6 付きの広東語粤拼を書きます:
This is (he2)平, not (huo4)面.、pronounced (lɪv) as a verb、去街市買啲(sung3)。 - 間投詞タグ(Speech 2.8 のみ):
(laughs)、(chuckle)、(coughs)、(clear-throat)、(groans)、(breath)、(pant)、(inhale)、(exhale)、(gasps)、(sniffs)、(sighs)、(snorts)、(burps)、(lip-smacking)、(humming)、(hissing)、(emm)、(sneezes)。
システムボイス
voice_id 列はそのまま使用してください。大文字・小文字、スペース、括弧も変更できません。「名前」は公式のラベルです。
voice_id | 言語 | 名前 |
|---|---|---|
English_expressive_narrator | 英語 | Expressive Narrator |
English_radiant_girl | 英語 | Radiant Girl |
English_magnetic_voiced_man | 英語 | Magnetic-voiced Male |
English_compelling_lady1 | 英語 | Compelling Lady |
English_Aussie_Bloke | 英語 | Aussie Bloke |
English_captivating_female1 | 英語 | Captivating Female |
English_Upbeat_Woman | 英語 | Upbeat Woman |
English_Trustworth_Man | 英語 | Trustworthy Man |
Chinese (Mandarin)_Reliable_Executive | 標準中国語 | Reliable Executive |
Chinese (Mandarin)_News_Anchor | 標準中国語 | News Anchor |
Chinese (Mandarin)_Unrestrained_Young_Man | 標準中国語 | Unrestrained Young Man |
Chinese (Mandarin)_Mature_Woman | 標準中国語 | Mature Woman |
Arrogant_Miss | 標準中国語 | Arrogant Miss |
Robot_Armor | 標準中国語 | Robot Armor |
Chinese (Mandarin)_Kind-hearted_Antie | 標準中国語 | Kind-hearted Antie |
Chinese (Mandarin)_HK_Flight_Attendant | 標準中国語 | HK Flight Attendant |
Japanese_IntellectualSenior | 日本語 | Intellectual Senior |
Japanese_DecisivePrincess | 日本語 | Decisive Princess |
Japanese_LoyalKnight | 日本語 | Loyal Knight |
Spanish_SereneWoman | スペイン語 | Serene Woman |
Spanish_MaturePartner | スペイン語 | Mature Partner |
Spanish_CaptivatingStoryteller | スペイン語 | Captivating Storyteller |
Cantonese_GentleLady | 広東語 | Gentle Lady |
広東語のボイスには language_boost: "Chinese,Yue" が必要です。上の表は入門用の抜粋にすぎません。MiniMax 公式のシステムボイス ID 一覧にあるボイス(24 言語・332 件)はすべて利用できます。voice_id は一覧の表記どおりに渡してください。2026-09-16 に全件検証済み:公式一覧に載っているのにサービス側が "voice id not exist" を返す Cantonese_ProfessionalHost (F) と Cantonese_ProfessionalHost (M) の 2 件を除き、すべて利用可能です。HopBase はまだボイス一覧のエンドポイントを提供していません。
パフォーマンスとタイムアウト
短いテキスト(1〜2 文)での実測値:同期エンドポイントはクリップ全体を約 1.5〜2.4 秒で返し、stream: true では最初の音声チャンクが約 1 秒で届きます。レイテンシはテキストの長さに応じて増えるため、長いものはストリーミングにし(MiniMax は 3,000 文字を超える場合にストリーミングを推奨)、上の SSE の例のようにチャンクが届いた順に書き出してください。同期リクエストのクライアント側の設定は、同時実行数、タイムアウト、課金にある他の同期エンドポイントと同じ指針に従ってください。読み取りタイムアウトは 300 秒以上です。
課金
音声合成は課金文字数に基づいて課金されます。正式な値はネイティブレスポンスの extra_info.usage_characters です。OpenAI 互換エンドポイントは音声しか返さないため、同じ数値はコンソールの利用量レコードで tts_characters として確認してください。Unicode の各文字を 1 と数え、漢字(CJK)はさらに 1 を加算するため、漢字 1 文字は 2 と数えます。句読点、スペース、絵文字、<#0.5#> のようなポーズ記号はそれぞれ 1 です。
Hello, world.→ 課金文字数 13你好,世界→ 5 文字のうち漢字が 4 文字 → 課金文字数 9
400 で拒否されたリクエストや合成中に失敗したリクエストは課金されず、最後のイベントの前に終了したストリームも課金されません。100 万文字あたりの公式リスト価格は料金ページに、お使いのプランの適用レートはログイン後のモデルカタログに掲載されています。
エラーとヒント
400 のボディはすべて {"error":{"message":…,"type":"invalid_request_error","code":…}} で、message に問題のフィールドが示されます。
| ステータス | 原因 | 対処 |
|---|---|---|
| 400 | 不正なパラメータ:範囲外の値、stream_format、output_format: "url"、または sample_rate なしの opus | message が示すフィールドを修正します。そのままの再試行は避けてください |
| 400 | 存在しないボイス ID | システムボイスの ID をそのまま使用します |
| 400 | 上限を超えるテキスト(4,096 / 10,000 文字) | 原稿を分割して順に送信します |
| 400 | 非対応の形式(response_format: "aac" など) | mp3 / opus / flac / wav / pcm を使用します |
| 402 | 残高切れ、またはキーのクォータ切れ | チャージまたはキーのクォータを調整します。ループでの再試行は避けてください |
| 404 | モデルがキーのプランに含まれていない | GET /v1/models で確認します |
| 429 | レート制限または同時実行数の上限 | Retry-After に従って再試行し、同時実行数を下げます |
| 503 | 現在利用できるサービスがない | 間隔を空けて再試行します(2 秒、5 秒、15 秒の順で最大 3 回) |
- 中国語のテキストには標準中国語のボイスを使用してください。
- 長い原稿はご自身で分割してください。OpenAI 互換エンドポイントは 1 リクエスト 4,096 文字、ネイティブエンドポイントは 10,000 文字です。
opusを使う場合は必ずsample_rateを併せて送信してください。
OpenAI 自身の TTS との違い:tts-1 というモデル名はなく(上記 2 つの ID を使用)、stream_format は利用できず、instructions は効果がなく、voice の値は MiniMax のボイス ID です。