| name | minimax-m2-7 |
| description | MiniMax M2.7 Plus — Chat, TTS, Image Gen, Video (Hailuo), Music, Voice Cloning |
MiniMax M2.7 Plus — Guía Completo
Setup
Chave ja configurada no environment. Bearer token usado em todos os requests.
Base URL: https://api.minimaxi.com/v1 (OpenAI兼容) ou https://api.minimaxi.com/anthropic (Anthropic兼容)
NOTA: O dominio e minimaxi.com (com "i"), nao minimax.io.
◆ Nous Tool Gateway (Hermes v0.10.0+)
Se tens pago do Nous Portal (nousportal.com), o Hermes já tem acesso integrado:
- Web Search — busca em tempo real
- Image Gen — via MiniMax (mesmo model
image-01)
- TTS — voz natural sem API key separada
- Browser Automation — scraping, interações web
Zero API keys adicionais necessárias.
Isto é uma alternativa ao uso direto da API MiniMax. Se só precisas de chat, TTS simples ou search, o Tool Gateway pode ser mais rápido de configurar.
Cotas (Plan Plus)
| Recurso | Limite | Janela |
|---|
| Text Generation (M2.7) | 4.500 | 5h rolling |
| TTS HD (speech-02-hd) | 4.000 | diário |
| Image Generation (image-01) | 50 | diário |
| Video (Hailuo 2.3) | - | - |
| Music (Music-2.6) | 100 | diário |
| Music-cover | 100 | diário |
Verificar Cotas Atuais
curl -s -X GET "https://api.minimax.io/v1/query/quota" \
-H "Authorization: Bearer ***"
Resposta inclui remain, limit, reset_at por recurso. Verificar antes de tasks grandes.
1. TEXT / CHAT
Endpoint: POST /text/chatcompletion_v2
curl -s -X POST "https://api.minimax.io/v1/text/chatcompletion_v2" \
-H "Authorization: Bearer $MINIMAX_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"MiniMax-M2.7","messages":[{"role":"user","content":"Olá"}],"max_tokens":1024}'
Models: MiniMax-M2.7, MiniMax-M2.7-highspeed, MiniMax-M2.5, MiniMax-M2.5-highspeed
Modelo ERRADO: MiniMax-Text-01 dá erro 2061 — só funciona no plano pago. Usar sempre MiniMax-M2.7.
⚠️ CRÍTICO: max_tokens para content aparecer
O M2.7 usa reasoning interno que consome tokens. Se max_tokens for baixo (ex: 5-10), o content vem vazio e o texto aparece só em reasoning_content.
Fix: usar max_tokens: 200 mínimo para garantir que content é preenchido.
{"model": "MiniMax-M2.7", "messages": [...], "max_tokens": 200}
{"model": "MiniMax-M2.7", "messages": [...], "max_tokens": 5}
Resposta correta:
{
"choices": [{
"message": {
"content": "OK",
"reasoning_content": "..."
}
}]
}
Context Window (confirmado 30/04/2026 — documentacao oficial MiniMax)
| Model | Context Window |
|---|
| M2.7 | 204,800 tokens |
| M2.7-highspeed | 204,800 tokens |
| M2.5 | 204,800 tokens |
| M2.5-highspeed | 204,800 tokens |
| M2.1 | 204,800 tokens |
IMPORTANTE: Todos os modelos de texto MiniMax tem exatamente 204,800 tokens. Nao existe 1M de contexto.
M2.8 — NÃO EXISTE
Como de Abr/2026, não há registro de M2.8 no site oficial, docs ou release notes. Release mais recente é M2.7 (Mar/2026).
Diferencial: Modelo de Preço Unlimited
O MiniMax é raro no mercado — quase nenhum competitor oferece API unlimited por mensalidade fixa (~$20/mês). A maioria cobra por token (OpenAI, Anthropic, Google, DeepSeek, Grok).
2. TTS — Text to Speech
Endpoint: POST /t2a_v2
curl -s -X POST "https://api.minimax.io/v1/t2a_v2" \
-H "Authorization: Bearer $MINIMAX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "speech-2.8-hd",
"text": "Olá, como vai você?",
"stream": false,
"output_format": "hex",
"voice_setting": {"voice_id": "male-qn-qingse", "speed": 0.95, "vol": 1.0, "pitch": 0},
"audio_setting": {"sample_rate": 32000, "bitrate": 128000, "format": "mp3", "channel": 1}
}'
Models: speech-2.8-hd ✅ (único que funciona neste plano), speech-2.8-turbo, speech-2.6-hd, speech-2.6-turbo
Nota: speech-02-hd e speech-02-turbo NÃO estão disponíveis — erro 2061.
System Voice IDs
male-qn-qingse — masculino suave ✅ ← PADRÃO GLOBAL (config.yaml)
female-qn-bella — feminino alternativo ✅
English_expressive_narrator ✅
male-qn-junny | female-qn-floral | female-qn-yisu | male-qn-qingse_4k — verificar antes de usar
Emoções (speech-02-hd+)
happy, sad, angry, fearful, disgusted, surprised, neutral
Interjections (speech-2.8-* only)
(laughs), (chuckle), (coughs), (clear-throat), (groans), (breath), (pant), (inhale), (exhale), (gasps), (sniffs), (sighs), (snorts), (burps), (lip-smacking), (humming), (hissing), (emm), (sneezes)
Output
Retorna hex encoded. Para salvar como MP3:
echo "$HEX_RESPONSE" | xxd -r -p > output.mp3
Voz PT-BR
- Voice cloning via console.minimax.io (upload áudio → cria voice_id custom)
- Usar
male-qn-qingse ou male-qn-junny
- Ajustar
pitch e speed
3. IMAGE GENERATION
Endpoint: POST /image_generation
curl -s -X POST "https://api.minimax.io/v1/image_generation" \
-H "Authorization: Bearer $MINIMAX_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"image-01","prompt":"A serene portrait of a Brazilian therapist","output_format":"url","output_size":"1k"}'
Models: image-01
output_size: 1k, 2k, 3k, 1:1, 16:9, 9:16, 4:3, 3:4 (documentado)
⚠️ PITFALL CRÍTICO (04/05/2026): A API SEMPRE retorna 1024×1024 independente do output_size passado. Testado empiricamente: todas as opções (1k, 2k, 3k, 16:9, 9:16, etc.) retornam exatamente 1024×1024. O parâmetro é ignorado.
Workaround: Fazer post-processing com Pillow (Python) para crop/resize ao formato desejado:
from PIL import Image
def process_image(input_path, fmt):
img = Image.open(input_path)
if fmt == "youtube":
target_w, target_h = 1920, 1080
crop_h = int(1024 * 9 / 16)
top = (1024 - crop_h) // 2
cropped = img.crop((0, top, 1024, top + crop_h))
result = cropped.resize((target_w, target_h), Image.LANCZOS)
else:
target_w, target_h = 1080, 1350
crop_w = int(1024 * 4 / 5)
left = (1024 - crop_w) // 2
cropped = img.crop((left, 0, left + crop_w, 1024))
result = cropped.resize((target_w, target_h), Image.LANCZOS)
result.save(input_path)
Response: JSON com data.image_urls — array de URLs. Confirmar key: data.image_urls[0].
⚠️ CRÍTICO: output_size IGNORADO — API sempre retorna 1024x1024
O parâmetro output_size não funciona na prática. Todas as imagens vêm 1024x1024. Sempre usar PIL para crop/resize depois:
from PIL import Image
def process_image(input_path, fmt):
img = Image.open(input_path)
w, h = img.size
if fmt == "youtube":
target_w, target_h = 1920, 1080
crop_h = int(w * 9 / 16)
top = (h - crop_h) // 2
cropped = img.crop((0, top, w, top + crop_h))
result = cropped.resize((target_w, target_h), Image.LANCZOS)
else:
target_w, target_h = 1080, 1350
crop_w = int(h * 4 / 5)
left = (w - crop_w) // 2
cropped = img.crop((left, 0, left + crop_w, h))
result = cropped.resize((target_w, target_h), Image.LANCZOS)
result.save(input_path)
return f"{target_w}x{target_h}"
Formatos confirmados (Álvaro, 04/05/2026):
- YouTube: 1920×1080 (16:9)
- Instagram: 1080×1350 (4:5 portrait)
⚠️ macOS Python 3.14 SSL workaround: Python 3.14 no macOS tem issues de certificado SSL com urllib.request. Usar curl como subprocess em vez de urllib diretamente:
import subprocess, json
result = subprocess.run([
"curl", "-s", "-X", "POST",
"https://api.minimax.io/v1/image_generation",
"-H", f"Authorization: Bearer {api_key}",
"-H", "Content-Type: application/json",
"-d", json.dumps(payload)
], capture_output=True, text=True, timeout=120)
response = json.loads(result.stdout)
img_url = response["data"]["image_urls"][0]
references/image-generator-script.md — Script completo de geração em lote com Style Lock + cron (ver acima)
Para gerar múltiplas imagens com o MESMO estilo visual (não a mesma imagem, mas a mesma estética/técnica), usar um "Style Lock" — um bloco de descritores visuais que NUNCA muda:
STYLE_LOCK = (
"Photorealistic photography, maximum detail, 8K resolution, cinematic lighting, "
"shallow depth of field, professional color grading, Canon EOS R5, 85mm lens, f/1.8 aperture, "
"natural textures, volumetric lighting, desaturated shadows, warm highlights, "
"anamorphic lens flare, studio lighting setup, clean background with subtle gradient, "
"high dynamic range, sharp focus, professional retouching"
)
Template de uso:
STYLE_LOCK + ". YouTube thumbnail format 16:9. NO TEXT, NO WORDS, NO LETTERS, NO NUMBERS. Topic: X"
STYLE_LOCK + ". Instagram post format 1:1. NO TEXT, NO WORDS, NO LETTERS, NO NUMBERS. Topic: X"
Nota: Álvaro (04/05/2026) especificou que imagens NUNCA devem conter texto. Sempre incluir "NO TEXT, NO WORDS, NO LETTERS, NO NUMBERS" nos prompts.
O Style Lock vai no início do prompt e permanece IDENTICO em todas as gerações. Apenas o tema/conteúdo muda. Isso garante consistência visual sem ser a mesma imagem.
Download:
curl -s "URL_DA_IMAGEM" -o imagem.jpg
4. VIDEO GENERATION
Endpoint: POST /v1/video_generation
Model: MiniMax-Hailuo-2.3 ou MiniMax-Hailuo-2.3-Fast
curl -s -X POST "https://api.minimax.io/v1/video_generation" \
-H "Authorization: Bearer $MINIMAX_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"MiniMax-Hailuo-2.3-Fast","prompt":"A serene beach at sunset"}'
Resolução: 1080p (6s), 768p (6s/10s), 512p (6s/10s)
FPS: 24 fps
Para I2V (image to video), usar input_image_url em vez de prompt.
5. MUSIC GENERATION
Endpoint: POST /v1/music_generation
Model: Music-2.6 (latest), Music-Cover, Music-2.0, Music-1.5
curl -s -X POST "https://api.minimax.io/v1/music_generation" \
-H "Authorization: Bearer $MINIMAX_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"Music-2.6","prompt":"A calm ambient music track with soft piano"}'
Options:
prompt: text description
lyrics: lyrics text
audio_url: reference audio for style transfer (Music-Cover)
6. VOICE CLONING
Via console.minimax.io → Voice Clone:
- Upload 30s-5min de áudio (WAV/MP3, sem ruído)
- Sistema gera voice_id custom
- Usa voice_id nos requests TTS
◆ Token Plan Troubleshooting
O Problema
Erros HTTP 429: insufficient balance (1008) com plano MiniMax Token Plan pago ($20/4500 requests-hora), mesmo com quota aparentemente disponível.
Como o Token Plan funciona (NÃO é como pensas)
- Text models (M2.7) usam CONTAGEM DE REQUESTS, não tokens. O erro
insufficient balance (1008) significa que a quota de requests da janela de 5 horas foi agotada.
- Janela de 5 horas (rolling): o sistema calcula uso total dentro das últimas 5 horas. Qualquer request com mais de 5 horas é automaticamente libertado.
- Keys são incompatíveis: Token Plan API Key (
sk-cp-...) é exclusivamente para Token Plan. Não funciona com API standard.
Verificar quota em tempo real
curl -s -X GET "https://www.minimax.io/v1/token_plan/remains" \
-H "Authorization: Bearer $MINIMAX_API_KEY" \
-H "Content-Type: application/json"
Resposta:
{"model_remains": [{"model_name": "MiniMax-M*", "current_interval_usage_count": 404, "current_interval_total_count": 4500}]}
Cálculo rápido: 4500 - 404 = 4096 requests restantes na janela de 5h.
Regra de Ouro: Health Checks Devem Verificar CONECTIVIDADE, Não Fazer Calls LLM
Padrão correcto — HTTP Network Check (NÃO consome quota):
def check_minimax_connectivity():
try:
import urllib.request
url = "https://api.minimax.io/v1"
req = urllib.request.Request(url)
req.add_header("User-Agent", "BianinhoMonitor/1.0")
with urllib.request.urlopen(req, timeout=8) as resp:
if resp.status in (200, 404, 405, 400):
return True
return False
except Exception:
return False
Reduzir frequência dos cron jobs
| Cron Job | Antes | Depois | Impacto |
|---|
| Server Resilience Manager | */5 * * * * | */30 * * * * | -216 chamadas/dia |
| Proactive Monitor | 12x/dia LLM | 12x/dia HTTP only | -100% quota |
| Server Health Check | 1x/hora | 1x/2h | -12 chamadas/dia |
Armadilhas Comuns
- Chave mascarada no .env (
***): health checks não conseguem usar key mascarada — usar apenas HTTP check.
- OpenRouter como intermediário: health check vai pelo OpenRouter consome quota Token Plan da mesma forma.
/v1/token_plan/remains precisa de key real: se a key está mascarada, retorna 403. Não usar para health checks — apenas diagnóstico.
- A
.env production é lida pelo systemd: cron jobs user-level não herdam — verificar que scripts herdam variáveis correctas.
Falhas de Formato de API (Mudança de Contrato)
O erro NÃO é HTTP 4xx — é HTTP 200 com vectors: null e base_resp.status_code.
Sintomas:
- HTTP 200 OK mas
vectors: null
{"vectors": null, "base_resp": {"status_code": 2013, "status_msg": "invalid params"}}
Padrão de debug:
import json, urllib.request
key = "YOUR_KEY"
payload = {"model": "embo-01", "texts": ["test query"], "type": "db"}
req = urllib.request.Request("https://api.minimax.io/v1/embeddings",
data=json.dumps(payload).encode(),
headers={"Authorization": f"Bearer {key}", "Content-Type": "application/json"},
method="POST")
with urllib.request.urlopen(req, timeout=15) as resp:
print(resp.read().decode())
◆ API Key Types — Token Plan vs Pay-as-you-go
Two Different API Key Types
| Key Type | Prefix | Requires | Error if Empty |
|---|
| Pay-as-you-go | sk-api-xxx | Pre-paid balance | insufficient balance (1008) |
| Token Plan | sk-cp-xxx | Active plan | Works if plan active |
How to Identify
- Pay-as-you-go: Key starts with
sk-api-
- Token Plan: Key starts with
sk-cp-
Troubleshooting Flow
1. Test API → 401 Unauthorized → Key invalid/expired
2. Test API → 429 insufficient_balance → Wrong key type (pay-as-you-go without balance)
3. Solution → Use Token Plan key (sk-cp-xxx) instead
Real Example (25/04/2026)
- First API (sk-api-xxx):
401 login fail → Invalid
- Second API (sk-api-xxx):
429 insufficient balance → Valid but no balance
- Third API (sk-cp-xxx):
200 OK → Token Plan works!
Error Codes
| Code | Significado |
|---|
| 0 | Success |
| 1004 | Authentication failed |
| 2013 | Invalid params |
| 2054 | Voice ID not exist |
| 10001 | Rate limit |