The MiniMax AI API is one of the most pleasant multimodal APIs to integrate: clean REST endpoints, a typed Python SDK, a maintained JavaScript client, predictable rate limits, and first-class streaming. The catch is that the docs are spread across a few surfaces (Studio, reference, changelog) and most tutorials assume you've already been through them. This guide consolidates everything into one straight-line path from zero to working integration.

By the end, you'll have a real Python script, a real Node.js script, and a real curl one-liner that all do the same thing β€” generate a video from a prompt β€” plus production patterns for error handling, rate limits, and streaming. Let's get to it.

MiniMax API at a glance

The API is a JSON-over-HTTPS surface that follows familiar REST conventions. Every endpoint lives under a stable base URL, accepts standard HTTP verbs, and returns JSON with predictable status codes. There are three families of endpoints: generation (image, video, voice, music), utility (upload, fetch, transcode, moderation), and account (token balance, usage, billing).

Architecture diagram showing a client app connecting to MiniMax API endpoints across generation, utility, and account families
Figure 1 Β· The MiniMax API surface: three endpoint families behind a single auth layer.

The base URL is the same for everyone:

https://api.minimax.io/v1

From there, the path tells you what you want. Image generation is /v1/images/generations, video is /v1/videos/generations, text-to-speech is /v1/audio/speech, and the account usage endpoint is /v1/account/usage. The names are deliberately predictable so you can guess them without a docs tab open.

For day-to-day development, you'll also spend time in the image generation API surface, which is the most-used endpoint. The same patterns apply across all of them.

Getting an API key

API access is unlocked on the Pro plan and above. If you're on Starter, you'll need to upgrade first β€” see the token plans breakdown for a quick primer on which tier makes sense for your workload.

Screenshot-style visualization of the API key creation flow inside the MiniMax Studio dashboard
Figure 2 Β· Where to find the API keys section in Studio β€” Settings β†’ Developer β†’ API keys.

Once you're on a Pro-or-higher plan, the path to a working key is short:

  1. Open Studio and go to Settings β†’ Developer β†’ API keys.
  2. Click Create key, name it (e.g. dev-local, prod-edge), and choose a scope: default (all endpoints) or read-only (account endpoints only).
  3. Copy the key immediately. It is shown exactly once, and you cannot retrieve it later β€” you'll have to rotate it if you lose it.
  4. Store it in an environment variable: export MINIMAX_API_KEY="sk-mm-..." in your shell profile, or in a secrets manager if you're deploying.

Keep in mind: keys are scoped to the workspace that created them, inherit the permissions of the user that minted them, and can be revoked at any time from the same screen. Treat them like passwords.

How authentication works

MiniMax uses bearer-token auth. Every request needs an Authorization: Bearer <YOUR_KEY> header, plus a sensible User-Agent if you're calling from a server. That's it β€” no OAuth dance, no signing, no rotating nonce. The simplicity is the point.

For client-side code (browser, mobile), never embed the key in the bundle. Either proxy requests through your own backend, or use the recommended pattern of a short-lived session key minted from your server-side key. The Studio dashboard exposes both long-lived server keys and short-lived session keys for this reason.

For server-to-server use, the standard pattern is environment variables. A minimal loader might look like:

import os
api_key = os.environ["MINIMAX_API_KEY"]
if not api_key.startswith("sk-mm-"):
    raise RuntimeError("Unexpected API key format")

If you're working in a notebook or a quick script, you can also load from a .env file using python-dotenv or dotenv in Node. Just make sure .env is in your .gitignore from day one β€” leaking a key in a public repo is the most common integration mistake, and the platform will auto-revoke keys that show up in known leaks within minutes.

Python quickstart (full working code)

The official Python package wraps the REST endpoints with type hints, retries, and streaming helpers. Install it and you can be running in under a minute:

pip install minimax

The script below generates a short video from a text prompt, polls until the job is finished, and saves the result to disk. It is the same shape you'll use in production β€” error handling, retries, and a clean exit are all built in.

import os
import time
from minimax import MiniMax, APIError, RateLimitError

# 1. Load the key from the environment.
client = MiniMax(api_key=os.environ["MINIMAX_API_KEY"])

# 2. Submit a video generation job.
try:
    job = client.videos.generations.create(
        model="minimax-video-1",
        prompt="A drone shot of a coastal cliff at golden hour, slow push-in",
        duration_seconds=4,
        aspect_ratio="16:9",
    )
except RateLimitError as e:
    print(f"Rate limited β€” retry in {e.retry_after}s")
    raise
except APIError as e:
    print(f"API error {e.status_code}: {e.message}")
    raise

# 3. Poll until the job is finished (or failed).
deadline = time.time() + 300  # 5 minutes max
while job.status not in ("succeeded", "failed"):
    if time.time() > deadline:
        raise TimeoutError("Job did not finish within 5 minutes")
    time.sleep(2)
    job = client.videos.generations.retrieve(job.id)

# 4. Save the output.
if job.status == "succeeded":
    output_path = client.videos.generations.download(
        job.id, destination="cliff.mp4"
    )
    print(f"Saved to {output_path}")
else:
    raise RuntimeError(f"Generation failed: {job.error}")

A few things worth pointing out in the snippet above:

  • Exception types are first-class. RateLimitError and APIError are importable from the top-level package, so you can branch on them in your application code without string-matching on status codes.
  • Polling is the default. For long-running jobs (video, high-res images), you submit a job, get back an ID, and poll. The SDK also supports webhooks for fully async patterns β€” see the streaming section below.
  • Timeouts are explicit. The deadline pattern keeps a stuck job from blocking a worker indefinitely. Tune it for your own latency budget.

For image generation, the shape is simpler β€” no polling required, since image jobs return inline:

from minimax import MiniMax
import os, base64

client = MiniMax(api_key=os.environ["MINIMAX_API_KEY"])

result = client.images.generations.create(
    model="minimax-image-1",
    prompt="a watercolor fox reading a tiny book, soft pastels",
    size="1024x1024",
    n=2,
)

for i, img in enumerate(result.data):
    path = f"fox-{i}.png"
    with open(path, "wb") as f:
        f.write(base64.b64decode(img.b64_json))
    print(f"saved {path}")

JavaScript quickstart (full working code)

The JavaScript client is published as minimax on npm and ships with TypeScript types, ESM and CJS builds, and full Node + browser support. Install it with your package manager of choice:

npm install minimax
# or
pnpm add minimax
# or
yarn add minimax

The Node version of the same video-generation flow looks like this:

import MiniMax from "minimax";
import fs from "node:fs";
import { setTimeout as sleep } from "node:timers/promises";

const client = new MiniMax({ apiKey: process.env.MINIMAX_API_KEY });

// 1. Submit the job.
const job = await client.videos.generations.create({
  model: "minimax-video-1",
  prompt: "A drone shot of a coastal cliff at golden hour, slow push-in",
  duration_seconds: 4,
  aspect_ratio: "16:9",
});

// 2. Poll for completion.
const deadline = Date.now() + 5 * 60_000;
let status = job.status;
while (status !== "succeeded" && status !== "failed") {
  if (Date.now() > deadline) throw new Error("timeout");
  await sleep(2000);
  status = (await client.videos.generations.retrieve(job.id)).status;
}

if (status !== "succeeded") {
  throw new Error(`generation failed: ${status}`);
}

// 3. Download the result.
const stream = fs.createWriteStream("cliff.mp4");
const response = await client.videos.generations.download(job.id);
await new Promise((resolve, reject) => {
  response.pipe(stream);
  stream.on("finish", resolve);
  stream.on("error", reject);
});
console.log("saved cliff.mp4");

The browser shape is similar, but the SDK is tree-shakable so you only ship the modules you use:

import MiniMax from "minimax/browser";

const client = new MiniMax({ apiKey: window.__SESSION_KEY__ });

const { data } = await client.images.generations.create({
  model: "minimax-image-1",
  prompt: "an isometric tiny cafe in a snowglobe, 3d render",
  size: "1024x1024",
});

// data[0].url is a short-lived CDN URL valid for 1 hour
const img = document.createElement("img");
img.src = data[0].url;
document.body.appendChild(img);

The window.__SESSION_KEY__ pattern is the recommended approach for client-side apps: mint a short-lived session key on your server, pass it to the browser, and let it expire automatically. The Studio dashboard can issue session keys with a configurable TTL (1 hour by default, up to 24 hours).

REST with curl

If you want to poke at the API without writing code, or you need a quick one-liner for a script or a CI pipeline, the REST surface is dead simple. The only thing you really need is curl and your key. This is the exact equivalent of the Python quickstart above, expressed as a single command:

curl -X POST https://api.minimax.io/v1/videos/generations \
  -H "Authorization: Bearer $MINIMAX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "minimax-video-1",
    "prompt": "A drone shot of a coastal cliff at golden hour, slow push-in",
    "duration_seconds": 4,
    "aspect_ratio": "16:9"
  }'

The response is a job object β€” copy the id, then poll the retrieve endpoint:

curl https://api.minimax.io/v1/videos/generations/$JOB_ID \
  -H "Authorization: Bearer $MINIMAX_API_KEY" \
  | jq .status

When the job is succeeded, the response includes a short-lived download URL. Fetch it with a normal GET and save to disk:

curl -L "https://cdn.minimax.io/..." -o cliff.mp4

The same pattern works for every endpoint. Image generation returns inline base64 in the response, so a single curl call gets you a generation in one shot. Text-to-speech returns a binary audio stream, so pipe the response directly into a file or a player. Account usage is a plain GET that returns your current token balance and the trailing 30 days of consumption.

For an at-a-glance map of where these costs come from, the token cost calculator breaks down per-modality burn and shows how the API bill actually adds up.

Error handling

The API uses standard HTTP status codes, with a small set of well-known error types. The pattern below works in any language β€” the same shape applies whether you're in Python, Node, Go, or a bash script with curl.

import time
from minimax import MiniMax, APIError, RateLimitError, AuthenticationError

client = MiniMax(api_key=os.environ["MINIMAX_API_KEY"], max_retries=3)

def safe_generate(prompt: str) -> dict:
    for attempt in range(3):
        try:
            return client.images.generations.create(
                model="minimax-image-1",
                prompt=prompt,
                size="1024x1024",
            )
        except RateLimitError as e:
            # 429 β€” wait the suggested interval, then retry.
            wait = int(e.headers.get("Retry-After", 5))
            print(f"rate limited; sleeping {wait}s (attempt {attempt + 1})")
            time.sleep(wait)
        except AuthenticationError:
            # 401 β€” your key is bad or revoked. Don't retry.
            raise
        except APIError as e:
            if e.status_code >= 500:
                # 5xx β€” server-side; back off and retry.
                time.sleep(2 ** attempt)
                continue
            # 4xx other than 401/429 β€” bad request, don't retry.
            raise
    raise RuntimeError("exhausted retries")

The three error categories worth knowing:

  • 4xx (client errors). Bad input, bad key, quota exceeded, missing scope. Don't retry β€” fix the request.
  • 429 (rate limit). The response includes a Retry-After header telling you exactly how long to wait. Honor it.
  • 5xx (server errors). Transient. Retry with exponential backoff, capped at 3 attempts. If you keep hitting 5xx, check the status page.

The SDK's built-in max_retries argument handles transient 5xx and 429 cases automatically. Turn it down to 0 if you want full control, or leave it on the default (3) and add your own logic only for application-specific cases.

Bar chart showing typical error rates and retry patterns across the MiniMax API endpoints
Figure 3 Β· A typical error distribution: most failures are 4xx from bad input, 429 from rate limits, and a small long tail of 5xx.

Rate limits and quotas

Rate limits are applied per-key, per-endpoint, and scale with your plan tier. The current published numbers look roughly like this:

Plan Requests / minute Concurrent jobs Daily token cap
Starter β€” β€” β€” (no API)
Pro 60 5 5M tokens / day
Business 600 25 30M tokens / day
Enterprise Custom Custom Custom

When you hit a limit, the response is a 429 with a Retry-After header. The right move is a simple token-bucket or leaky-bucket scheduler in your application β€” most production SDKs ship one. The key insight is that concurrent jobs is a separate axis from requests per minute: a single image generation is one request that returns in two seconds, but a video job is one request that holds a worker slot for minutes. Plan for both.

For batch jobs, the cleanest pattern is a worker pool with a small concurrency limit (often 4–8) and a token-bucket rate limiter in front of it. Most teams adopt the aiometer or p-limit libraries for this. The first time you hit 429 in production is usually the day you wish you'd added the limiter on day one.

Streaming responses

For chat, long completions, and progressive UI updates, streaming is the right pattern. The MiniMax API supports server-sent streaming on the chat and text endpoints β€” pass stream: true and consume the response as a stream of partial deltas.

from minimax import MiniMax

client = MiniMax(api_key=os.environ["MINIMAX_API_KEY"])

stream = client.chat.completions.create(
    model="minimax-text-1",
    messages=[{"role": "user", "content": "Write a haiku about debugging."}],
    stream=True,
)

for chunk in stream:
    delta = chunk.choices[0].delta.content
    if delta:
        print(delta, end="", flush=True)
print()

Under the hood this is Server-Sent Events: each chunk is a JSON object with a delta, and the connection closes when the model is done. Most HTTP libraries handle SSE for you β€” the SDK above is the standard pattern. The Node equivalent uses an async iterator:

const stream = await client.chat.completions.create({
  model: "minimax-text-1",
  messages: [{ role: "user", content: "Write a haiku about debugging." }],
  stream: true,
});

for await (const chunk of stream) {
  const delta = chunk.choices[0]?.delta?.content;
  if (delta) process.stdout.write(delta);
}
process.stdout.write("\n");

Streaming pairs well with webhooks for fully async jobs. Instead of polling a video generation, you can register a webhook URL on your workspace, and the API will POST a completion event to you the moment the job finishes. That eliminates polling load and lets your workers stay idle until there's actually work to do. Webhook signatures are HMAC-signed β€” verify them with the shared secret in your workspace settings.

Screenshot-style view of the Studio dashboard showing API usage, rate limit headroom, and a streaming job in progress
Figure 4 Β· The Studio dashboard gives you live visibility into rate limit headroom, token burn, and active jobs.

For a deeper look at the rest of the developer surface, the image generation API deep-dive covers the most-used endpoint, and the how AI tokens work primer explains what the API is actually charging you for.

Frequently asked questions

Which MiniMax plan includes API access?

API access is included on the Pro, Business, and Enterprise plans. The Starter plan is web-only and does not include API keys. If you're already on Pro, the keys live under Settings β†’ Developer β†’ API keys in Studio.

Is there an official MiniMax SDK for Python?

Yes. The official Python package is minimax on PyPI. pip install minimax gets you a typed client with retries, streaming, and a CLI. It's the recommended path for any non-trivial integration.

What are the MiniMax API rate limits?

Pro plans allow 60 requests per minute and 5 concurrent jobs. Business plans scale to 600 requests per minute and 25 concurrent jobs. Enterprise is fully custom. When you hit a limit, the API returns a 429 with a Retry-After header.

Can the MiniMax API stream responses?

Yes. The chat and text endpoints support stream: true, which returns a Server-Sent Events stream of partial deltas. For long-running jobs, you can also register a webhook to receive completion events instead of polling.

How do I keep my MiniMax API key secure?

Never commit keys to source control. Load them from environment variables or a secrets manager, scope them to the smallest set of permissions needed, and rotate immediately if a key is exposed. The platform auto-revokes any key found in a public leak within minutes.

The cleanest production integrations I've seen all do the same three things: scope the key, honor Retry-After, and stream anything user-facing. β€” Sam Rivera, on patterns that survive contact with real traffic

Conclusion

The MiniMax API is designed to get out of your way. Bearer-token auth, predictable REST endpoints, an official SDK in the languages you'll actually use, and a streaming model that doesn't fight you. Most teams can ship a working integration in an afternoon, and most of the time spent after that is on the application logic around the API rather than the API itself.

The patterns that matter most, in order: scope your key to the smallest set of permissions needed, honor the Retry-After header on every 429, and stream anything user-facing. Get those three right and the rest is product work.

If you don't have API access yet, you'll need a Pro plan or higher. The fastest path is to start there, mint a key, and follow the Python or JavaScript quickstart above. The same five lines of code that work in a notebook will work in production with retries and error handling bolted on.

Ready to wire up the API?

Start with a Pro plan to unlock API keys, then use the quickstarts above to ship your first integration. Most teams go from zero to a deployed endpoint in under a day.

πŸ‘‰ Get Your Token Plan Now

*Affiliate link β€” we may earn a commission at no extra cost to you.