REST API

Call the MachGen REST API directly over HTTPS.

API is hosted at https://api.machgen.ai.

The general task lifecycle is always the same: submit a task, poll its status until it completes, then download the result.

Depending on the exact task, the task input may require specific fields. Please refer to the following example for details.

Provide your API key

Send your key (see Get Started) as a bearer token on every request:

# Key starts with `MGA_`
export MACHGEN_API_KEY=".."

curl -H "Authorization: Bearer $MACHGEN_API_KEY" https://api.machgen.ai/..

Submit a task

POST /api/v0/generate with a JSON TaskInput describing the task. It returns immediately with a task_id - it does not wait for generation. The body fields differ per task type.

Check the following examples to get a quick start.

For detailed API input/output reference, refer to the API Reference page.

Text to video
curl https://api.machgen.ai/api/v0/generate \
  -H "Authorization: Bearer $MACHGEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "A red panda exploring a misty forest at dawn",
    "model": "Wan2.2-A14B",
    "task_type": "T2V",
    "video_config": {"duration_secs": 5, "height": 720, "aspect_ratio": "16:9", "fps": 16, "infer_steps": 30}
  }'
Image to video
curl https://api.machgen.ai/api/v0/generate \
  -H "Authorization: Bearer $MACHGEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "slow dolly-in as the leaves drift in the wind",
    "model": "Vidu-Q3-Turbo",
    "task_type": "I2V",
    "src_image_urls": ["https://example.com/first-frame.png"],
    "video_config": {"duration_secs": 5, "height": 720}
  }'
Reference to video
curl https://api.machgen.ai/api/v0/generate \
  -H "Authorization: Bearer $MACHGEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "@alice waves to @bob across a busy street",
    "model": "Vidu-Q3",
    "task_type": "R2V",
    "src_image_urls": [
      "https://example.com/alice-1.png",
      "https://example.com/alice-2.png",
      "https://example.com/bob.png"
    ],
    "subject_to_image_ids": {"alice": [0, 1], "bob": [2]},
    "video_config": {"duration_secs": 5, "height": 720, "aspect_ratio": "16:9"}
  }'
Text to image
curl https://api.machgen.ai/api/v0/generate \
  -H "Authorization: Bearer $MACHGEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "An isometric illustration of a cozy reading nook, soft lighting",
    "model": "Nano-Banana-Pro",
    "task_type": "T2I",
    "image_config": {"aspect_ratio": "1:1", "height": 1024, "infer_steps": 30, "guidance_scale": [5.0]}
  }'
Image editing
curl https://api.machgen.ai/api/v0/generate \
  -H "Authorization: Bearer $MACHGEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "make the sky a dramatic sunset",
    "model": "Nano-Banana-Pro",
    "task_type": "I2I",
    "src_image_urls": ["https://example.com/landscape.png"],
    "image_config": {"aspect_ratio": "1:1", "height": 1024}
  }'

Config values are model-specific

duration_secs, height, and aspect_ratio must be one of the values the target model supports - the duration_secs: 5 and height above are representative, not universal.

A value outside a model's grid is rejected at submit with HTTP 400.

See Available Models for each model, and API Reference for the config fields.

The response carries the task_id you poll and download with:

{ "task_id": "t-abc123", ... }

Check status and download

Poll GET /api/v0/tasks/{task_id} until status is COMPLETED or FAILED.

curl -H "Authorization: Bearer $MACHGEN_API_KEY" \
  https://api.machgen.ai/api/v0/tasks/t-abc123
{
  "task_id": "t-abc123",
  "status": "COMPLETED",
  "metadata": {
    "prompt": "...",
    "height": 720,
    "width": 1280,
    "fps": 24,
    "duration_secs": 5,
    ...
  },
  "task_output": {
    "video": "https://api.machgen.ai/api/v0/assets/t-abc123"
  }
}
{
  "task_id": "t-abc123",
  "status": "COMPLETED",
  "metadata": {
    "prompt": "...",
    "height": 720,
    "width": 1280,
    ...
  },
  "task_output": {
    "image": "https://api.machgen.ai/api/v0/assets/t-abc123"
  }
}
{
  "task_id": "t-abc123",
  "status": "FAILED",
  "error_msg": "Your task failed because ..."
}
curl -H "Authorization: Bearer $MACHGEN_API_KEY" \
  https://api.machgen.ai/api/v0/assets/t-abc123 -o output.mp4

A task moves through these statuses; COMPLETED and FAILED are terminal:

StatusTerminalMeaning
PENDINGAccepted and queued, not yet started.
RUNNINGGeneration in progress.
COMPLETEDyesGeneration completed; ready to download.
FAILEDyesGeneration failed; see error_msg.

Errors

A FAILED status (above) reports a task that was accepted but could not be generated. A request that is rejected before acceptance instead returns a non-2xx HTTP status with a JSON body carrying a single detail string:

{ "detail": "Wan2.2-T2V-A14B does not support height=1080; allowed heights: [480, 720]" }
StatusMeaningExample detail
400 Bad RequestInvalid body: unknown model/task_type, missing config, or a shape/duration outside the model's grid.Invalid model
401 UnauthorizedMissing, malformed, or unknown API key.Invalid API key
403 ForbiddenKey is valid but the account may not use this feature or model.The 'generate' feature is not enabled for your account.
404 Not FoundNo task with the given id (e.g. when polling).Task t-abc123 not found
429 Too Many RequestsRate limit exceeded; retry later.Too many submissions; please try again later.

Sync mode

For self-hosted image models you can skip the poll-and-download round trip and receive the finished image inline. POST /api/v0/generate/sync takes the same JSON TaskInput body, but the request blocks until the worker streams back the encoded JPEG and returns those bytes directly.

Sync mode is available for T2I and I2I tasks on self-hosted (non-passthrough) models.

Sync text to image
curl https://api.machgen.ai/api/v0/generate/sync \
  -H "Authorization: Bearer $MACHGEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "An isometric illustration of a cozy reading nook, soft lighting",
    "model": "FLUX.2-dev",
    "task_type": "T2I",
    "image_config": {"width": 1024, "height": 1024}
  }' -o output.jpg

On success the response is 200 OK with the raw image/jpeg bytes as the body. The X-Machgen-Task-Id response header carries the task id: the durable task may still be finalizing when you receive the bytes, so use that id to poll status or fetch the canonical asset later, exactly as with an async task.

If the image cannot be delivered inline - generation runs past the timeout, the image is oversize, or an inline error occurs - the server falls back to the async path and returns 202 Accepted with the normal GenerateResponse JSON body plus an X-Machgen-Sync-Fallback-Reason header (timeout, oversize, or inline_error).

A fallback is not a failure: the task continues on the async path and can be polled and downloaded exactly like one submitted to POST /api/v0/generate.

Source images

For I2V, R2V, and I2I, every entry in src_image_urls must be a public http(s):// URL.

Request and response reference

The full field reference for the request body (TaskInput, VideoConfig, ImageConfig) and the status response (TaskStatusResponse) lives on the API Reference page.