minimax-laravel maintained by rayzenai
minimax-laravel
A thin Laravel client for the Minimax AI platform.
Wraps the four Minimax surfaces we use day-to-day — text-to-image,
text-to-speech, chat completions, and voice management (design,
list, delete) — behind a single Minimax facade with sensible Laravel defaults
(config, env, service container singletons, exception type).
It is deliberately small: each client is a few dozen lines, takes a prompt
or text, and returns plain PHP — URLs, bytes, strings, arrays. There is no
retry layer, no queue, no SDK-style fluent builder. Drop the result into a
job, a Storage disk, an Inertia response, whatever.
What's in the box
| Client | Facade | Responsibility |
|---|---|---|
ImageClient |
Minimax::image() |
Text-to-image (image_generation). Transparently batches above the 4-image-per-call API cap so you can ask for 10 in one go. |
TtsClient |
Minimax::tts() |
Text-to-speech (t2a_v2). Returns raw audio bytes (MP3 by default). Ships with a curated VOICES constant of common English voice IDs. |
TextClient |
Minimax::text() |
Chat completions (text/chatcompletion_v2). complete() returns the assistant string; raw() returns the full payload for tool-calling use. |
VoiceClient |
Minimax::voice() |
Voice design from a text prompt, list existing voices (system / cloned / generated), delete a custom voice. Custom-voice plan caps live in minimax.voice_slots. |
All clients raise RayzenAI\Minimax\Exceptions\MinimaxException on HTTP
failures or non-zero base_resp.status_code responses.
Install (path repository)
This package is not on Packagist. In the consuming app's composer.json:
{
"repositories": [
{ "type": "path", "url": "../../rayzenai/minimax-laravel" }
],
"require": {
"rayzenai/minimax-laravel": "@dev"
}
}
Then:
composer require rayzenai/minimax-laravel
php artisan vendor:publish --tag=minimax-config
Env
MINIMAX_API_KEY=
MINIMAX_GROUP_ID=
MINIMAX_BASE_URL=https://api.minimax.io/v1
MINIMAX_IMAGE_MODEL=image-01
MINIMAX_IMAGE_ASPECT=9:16
MINIMAX_IMAGE_RESPONSE_FORMAT=url
MINIMAX_TTS_MODEL=speech-2.8-hd
MINIMAX_TTS_VOICE=English_radiant_girl
MINIMAX_TEXT_MODEL=MiniMax-M2.7
# Plan-tier custom voice cap (designed + cloned). Bump for higher tiers.
MINIMAX_VOICE_SLOTS=3
Usage
use RayzenAI\Minimax\Facades\Minimax;
use Illuminate\Support\Facades\Storage;
// 10 portrait images from one prompt.
$urls = Minimax::image()->generate('a cyberpunk samurai at dusk', 10, [
'aspect_ratio' => '9:16',
]);
// Voiceover bytes — persist however you like.
$mp3 = Minimax::tts()->synthesize('Hello, world.', ['voice' => 'English_radiant_girl']);
Storage::disk('public')->put('hello.mp3', $mp3);
// Chat completion.
$copy = Minimax::text()->complete('Write a 30-second TikTok hook about coffee.');
// Design a new custom voice.
$voice = Minimax::voice()->design(
prompt: 'A warm, deep British male narrator. Calm and reassuring.',
previewText: 'Welcome back to the channel.',
);
// $voice = ['voice_id' => '…', 'trial_audio' => <raw mp3 bytes>]
// List + delete.
$voices = Minimax::voice()->list(); // ['system' => […], 'cloning' => […], 'generation' => […]]
Minimax::voice()->delete($voice['voice_id'], 'voice_generation');
Notes & gotchas
- Image URLs expire (~24h) on Minimax's side. Persist bytes if you need
long-term storage — the package returns whatever
response_formatyou ask for (URL ordata:URI whenbase64). - Cloned voices stay invisible until first use — they only appear in the
voice_cloningbucket ofMinimax::voice()->list()after you've used them in a TTS call once. - Custom voice cap is plan-tier, not API. Entry plans allow 3. The package
doesn't enforce this;
minimax.voice_slotsis exposed so the consuming app can guard before callingdesign(). - Voice IDs in
TtsClient::VOICESare a curated subset — the live system list fromMinimax::voice()->list('system')is canonical.