Skip to main content
mage-space is the official Python client for the Mage API. It has a sync client and an asyncio client, types the config of every model, submits a generation and waits for the result in one call, and retries safely without paying twice.
The SDK is in beta at 0.x, so a minor version may still change it. The API itself is versioned separately and stays stable within v1.

Install

It needs Python 3.10 or later, and depends on httpx and typing-extensions. The package installs as mage-space and imports as mage_space.

Quick start

Create a key in API → API Keys and export it as MAGE_API_KEY.
run submits the generation, polls it with the backoff the API recommends, and returns the completed request. Responses are plain dictionaries shaped like the request object. The output is at result.url and is kept for 30 days, so download what you want to keep.

Async

AsyncMage has the same methods, awaited, and works as an async context manager.
Its on_update callback may be a plain function or a coroutine function.

Models

The first argument is the model’s architecture id, as in its endpoint path: mango for images, cherry for video, seed_audio for audio, and every other model. model_id selects a variant.
Each model has a TypedDict in mage_space.types with its fields, allowed values, and defaults. Annotate a config with it to have your type checker check it:
A model released after your version of the SDK still works by its id. mage_space.ARCHITECTURES holds the name, output type, and request JSON Schema of every model this version knows; mage.architectures.list() returns the live catalog with prices.

Submit and poll separately

wait polls from 2 seconds, multiplies the delay by 1.5 after each read up to 15 seconds, adds jitter, and returns the final request whatever its status. Past timeout it raises MageTimeoutError, and the request keeps running on Mage. requests.get(request_id) reads a request once, and requests.cancel(request_id) stops a live one. Gems are not returned for a cancelled request.

Inputs and uploads

Media fields take an https URL or a data URL. For a file larger than about 3 MB, or one that is not at a public URL, upload it first and send the URL the upload returns.
The content type comes from the file name; pass content_type= for raw bytes. Uploads expire after 30 days, at url_expires_at. See Inputs and uploads for formats and limits.

Characters and references

Errors

New error codes may appear; treat an unknown code by its HTTP status.

Retries and idempotency

Reads, cancels, deletes, and uploads are retried up to max_retries times (default 2) on connection errors and on 408, 429, and 5xx responses, with exponential backoff. generate and run send an Idempotency-Key with every submission, a fresh UUID unless you pass idempotency_key=, and retry with the same key only when no response arrived or on a 408 or 5xx that recorded no request. A replayed submission returns the original request and charges nothing. Pass your own key, such as a job id, to make retries across processes safe too. Creating characters and references is never retried.

Configuration

Use with Mage() as mage: or mage.close() to close the connection pool; the SDK closes only an HTTP client it created.

Reference

Source and releases

The SDK is MIT-licensed on GitHub and published to PyPI with build attestations. Its model types come from this API reference: when the reference changes, a pull request updates them, so new models and options arrive as new releases.

TypeScript SDK

The same API for Node.js, with typed configs.

ComfyUI

Every Mage model as ComfyUI nodes, built on this SDK.
Last modified on September 30, 2026