音声合成 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 のリクエスト形式を受け付け、音声のバイト列をそのまま返します。

フィールド備考
modelspeech-2.8-hd / speech-2.8-turbo必須
inputテキスト、最大 4,096 文字必須
voiceEnglish_expressive_narratorChinese (Mandarin)_News_Anchor などの MiniMax ボイス ID、または OpenAI の名前(alloynova など)OpenAI の名前はテキストの言語に応じたデフォルトボイスにフォールバックします。漢字を含む場合は標準中国語、それ以外は英語のボイスです
response_formatmp3(デフォルト)/ opus / flac / wav / pcmaac は非対応(400)。opus は OGG コンテナで返されます
speed0.25〜4範囲外は 400。範囲内の値は 0.5〜2 にクランプされます
instructions受け付けますが無視されます

stream_format は非対応で、指定すると 400 が返ります。レスポンスの Content-Typeresponse_format に応じて audio/mpegaudio/oggaudio/flacaudio/wavaudio/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 のリクエストボディをそのまま受け付けます。modeltext(最大 10,000 文字)、voice_setting(voice_idspeedvolpitchemotion)、audio_setting(formatsample_ratebitratechannel)、language_booststreamstream_options は変更なしで渡されます。各フィールドと受け付ける値はリクエストパラメータにまとめています。JSON レスポンスも公式の構造に従います。data.audio は 16 進数でエンコードされた音声、extra_info には usage_characters と音声のメタデータが含まれます。

  • output_formathex(デフォルト)のみ対応です。url を指定すると 400 が返ります。
  • voice_setting.speed は 0.5〜2 にクランプされます。
  • audio_setting.format"opus" の場合は sample_rate を明示的に指定してください(例:24000)。指定しないとパラメータエラーで失敗します。
  • stream: true を指定すると SSE に切り替わります。各 data: {...} イベントが音声チャンクを運び、最後のイベントは data.status2extra_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 を指定して、最後のイベント(status2)が 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 の挙動が異なる箇所と、単に透過させるだけの箇所を示します。

トップレベルのフィールド

フィールドデフォルト備考
modelspeech-2.8-hd / speech-2.8-turbo必須
text最大 10,000 文字必須。段落は改行で区切ります。インライン制御は後述。公式には 3,000 文字を超える場合はストリーミングが推奨されています
streamtrue / falsefalsetrue でレスポンスが SSE に切り替わります
stream_options.exclude_aggregated_audiotrue / falsefalsetrue で最後のチャンクから結合済み音声を除きます
language_boostauto、または ChineseChinese,YueEnglishArabicRussianSpanishFrenchPortugueseGermanTurkishDutchUkrainianVietnameseIndonesianJapaneseItalianKoreanThaiPolishRomanianGreekCzechFinnishHindiBulgarianDanishHebrewMalayPersianSlovakSwedishCroatianFilipinoHungarianNorwegianSlovenianCatalanNynorskTamilAfrikaans のいずれか未設定指定した言語・方言の認識を強化します。auto ではモデルが自動判定します。広東語のボイスには Chinese,Yue が必要です
pronunciation_dict.tone元の語/置換 形式の文字列配列置換にはプレーンテキスト(omg/oh my god)、声調番号 1〜5 付きの括弧入りピンイン(处理/(chu3)(li3))、括弧入りの IPA(resume/(rɪˈzjuːm))、日本語のかな(東京/トウキョウ)が使えます。複数のルールは同時に適用されます
voice_modifypitchintensitytimbre:-100〜100 の整数。sound_effects:spacious_echo / auditorium_echo / lofi_telephone / robotic公式の意味:pitch は低く → 明るく、intensity は力強く → 柔らかく、timbre は豊かに → 鮮明に。効果は一度に 1 つ。非ストリーミングでは mp3 / wav / flac、ストリーミングでは mp3 のみ。公式の意味どおりに透過し、ゲートウェイ側では検証していません
output_formathexhexurl を指定すると 400 が返ります

voice_setting

フィールドデフォルト備考
voice_idシステムボイスの ID。システムボイスを参照必須
speed0.5〜21.0範囲外の値はこの範囲にクランプされます
vol0 より大きく 10 以下1.0音量
pitch-12〜12 の整数00 で元のピッチを保ちます
emotionhappy / sad / angry / fearful / disgusted / surprised / calm / fluent / whisperテキストから自動選択感情を固定したいときだけ指定してください。fluentwhisper は公式には 2.6 系列向けに記載されており、whisper は Speech 2.8 では非対応と明記されています
text_normalizationtrue / falsefalse中国語・英語の数字の読み上げを正規化します。レイテンシがわずかに増えます
latex_readtrue / falsefalse中国語のみ。数式は $$ で囲みます。language_boostChinese に固定されます

audio_setting

フィールドデフォルト備考
formatmp3 / pcm / flac / wav / opusmp3opus は Ogg/Opus 形式で、sample_rate の明示指定が必須です
sample_rate8000 / 16000 / 22050 / 24000 / 32000 / 44100公式に明記なし。公式の例では 32000
bitrate32000 / 64000 / 128000 / 256000公式に明記なし。公式の例では 128000mp3 のみ
channel1 / 21モノラル / ステレオ
force_cbrtrue / falsefalse固定ビットレート。ストリーミングの 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_formatoutput_format: "url"、または sample_rate なしの opusmessage が示すフィールドを修正します。そのままの再試行は避けてください
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 です。

このページの内容