> ## Documentation Index
> Fetch the complete documentation index at: https://docs.aireiter.com/llms.txt
> Use this file to discover all available pages before exploring further.

# FLUX 3 Max Video Generation

> - Black Forest Labs FLUX 3 Max video generation model, post-trained on FLUX 3 Video, featuring stronger prompt adherence, higher visual quality, and lower generation latency
- Asynchronous processing mode, returning a task ID for subsequent queries
- Supports three modes: text-to-video, first-and-last frame, and keyframe (up to 10 images)
- Supports 720p / 1080p output, video duration of 5-20 seconds, with native audio generated by default


export const apiKeyUrl = 'https://aireiter.com/keys';

<Note>
  The model name for FLUX 3 Max in AIReiter is `flux_3_max`. Use `type` to select text (`text`), first-and-last frame (`frame`), or keyframes (`keyframes`) mode.
</Note>

## Authorizations

<ParamField header="Authorization" type="string" required>
  All APIs require authentication using a Bearer Token.

  Get an API Key:

  Visit the <a href={apiKeyUrl} target="_blank">API Key management page</a> to get your API Key.

  Add it to the request header when using:

  ```
  Authorization: Bearer YOUR_API_KEY
  ```
</ParamField>

## Body

<ParamField body="model" type="string" required>
  Model name, fixed value:

  * `flux_3_max`
</ParamField>

<ParamField body="params" type="object" required>
  Model parameter object.

  <Expandable title="params Object Properties">
    <ParamField body="prompt" type="string" required>
      Video content description, required for all modes.

      It is recommended to describe the visual scene, actions, camera movements, and audio simultaneously. The model will automatically understand and expand the prompt before generation (see `reasoning_level` for expansion intensity).
    </ParamField>

    <ParamField body="type" type="string" default="text">
      Generation mode:

      * `text` - Text-to-video, default value. Uses only the prompt; passed images will be ignored
      * `frame` - First and last frames. `image_url[0]` is used as the first frame (required), and `image_url[1]` as the last frame (optional)
      * `keyframes` - Keyframes. Pass up to 10 images in order, evenly distributed along the video timeline, with the video transitioning sequentially through each one

      <Warning>
        The `frame` and `keyframes` modes require at least 1 image; if no image is passed, it generates using `text` mode.
      </Warning>
    </ParamField>

    <ParamField body="image_url" type="string | string[]">
      Image URL, must be directly accessible via the public network. Not required for `text` mode.

      * `frame` - 1-2 images: The 1st image is the first frame, and the 2nd image (optional) is the last frame
      * `keyframes` - 1-10 images, evenly placed from the first frame to the last frame in the order of upload

      Image requirements:

      * Format: PNG, JPEG, WEBP
      * Maximum 20 MB per image
    </ParamField>

    <ParamField body="end_image_url" type="string">
      Last frame image URL, valid only for `frame` mode. Can also be passed directly as the 2nd image in `image_url`; if both are passed, `end_image_url` takes precedence.
    </ParamField>

    <ParamField body="video_length" type="integer" default="5">
      Generated video duration, in seconds.

      Supports integers: `5` to `20`.
    </ParamField>

    <ParamField body="resolution" type="string" default="720p">
      Output resolution (24 fps):

      * `720p` - Default value
      * `1080p`
    </ParamField>

    <ParamField body="aspect_ratio" type="string" default="auto">
      Video aspect ratio:

      * `auto` - Default value. 16:9 for `text` mode; follows the 1st image when images are provided
      * `16:9` - Landscape
      * `9:16` - Portrait
      * `1:1` - Square
      * `4:3` - Standard landscape
      * `3:4` - Standard portrait
      * `21:9` - Ultra-widescreen
    </ParamField>

    <ParamField body="reasoning_level" type="string" default="high">
      Prompt reasoning intensity, the degree to which the model understands and expands the prompt before generation:

      * `high` - Default value. More comprehensive expansion, better results, slower generation
      * `low` - Faster

      Both levels have the same price.
    </ParamField>

    <ParamField body="generate_audio" type="boolean" default="true">
      Whether to generate native audio with the video.

      * `true` - Generates video with an audio track, default value
      * `false` - Outputs silent video

      The price is the same whether audio is enabled or disabled.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="out_task_id" type="string" required>
  Caller task ID.

  User-defined task identifier, required. Supports only letters, numbers, underscores, and hyphens, with a length of 1-64 characters. This ID can be used later to query the task status and results.
</ParamField>

## Response

<ResponseField name="out_task_id" type="string">
  Initiator task ID, which can be used to query results.
</ResponseField>

<ResponseField name="status" type="string">
  Initial status, usually `"pending"`.
</ResponseField>

<ResponseField name="created_at" type="string">
  Creation time, ISO format.
</ResponseField>

## Query Task

FLUX 3 Max is an asynchronous video generation model. After submitting a task, please use `out_task_id` to query the task status; querying every 10-15 seconds is recommended.

<ParamField body="out_task_id" type="string" required>
  The initiator task ID passed when submitting the task.
</ParamField>

```bash theme={null}
curl --request POST \
  --url https://aireiter.com/api/openapi/query \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "out_task_id": "flux_3_max_frame_123456"
  }'
```

After the query succeeds and completes, the `output` array in the response will contain the generated video, with elements containing the `video` field.

<RequestExample>
  ```bash cURL (First and Last Frames) theme={null}
  curl --request POST \
    --url https://aireiter.com/api/openapi/submit \
    --header 'Authorization: Bearer <token>' \
    --header 'Content-Type: application/json' \
    --data '{
      "model": "flux_3_max",
      "params": {
        "prompt": "A cowboy riding a horse through a canyon at sunset, hooves kicking up dust, sound of hooves and wind",
        "type": "frame",
        "image_url": ["https://example.com/first-frame.jpg", "https://example.com/last-frame.jpg"],
        "resolution": "720p",
        "video_length": 5,
        "generate_audio": true
      },
      "out_task_id": "flux_3_max_frame_123456"
    }'
  ```

  ```bash cURL (Text to Video) theme={null}
  curl --request POST \
    --url https://aireiter.com/api/openapi/submit \
    --header 'Authorization: Bearer <token>' \
    --header 'Content-Type: application/json' \
    --data '{
      "model": "flux_3_max",
      "params": {
        "prompt": "A red panda walking along a moss-covered log, stopping to sniff the air, morning light filtering through the canopy, birds chirping and leaves rustling",
        "type": "text",
        "resolution": "1080p",
        "aspect_ratio": "16:9",
        "video_length": 8,
        "reasoning_level": "high",
        "generate_audio": true
      },
      "out_task_id": "flux_3_max_text_123456"
    }'
  ```

  ```bash cURL (Keyframes) theme={null}
  curl --request POST \
    --url https://aireiter.com/api/openapi/submit \
    --header 'Authorization: Bearer <token>' \
    --header 'Content-Type: application/json' \
    --data '{
      "model": "flux_3_max",
      "params": {
        "prompt": "The camera follows the character from the street corner into a cafe, eventually sitting by the window, ambient city sounds",
        "type": "keyframes",
        "image_url": [
          "https://example.com/key-1.jpg",
          "https://example.com/key-2.jpg",
          "https://example.com/key-3.jpg"
        ],
        "resolution": "720p",
        "video_length": 10,
        "generate_audio": true
      },
      "out_task_id": "flux_3_max_keyframes_123456"
    }'
  ```

  ```python Python theme={null}
  import requests

  url = "https://aireiter.com/api/openapi/submit"

  payload = {
      "model": "flux_3_max",
      "params": {
          "prompt": "A cowboy riding a horse through a canyon at sunset, hooves kicking up dust, sound of hooves and wind",
          "type": "frame",
          "image_url": ["https://example.com/first-frame.jpg"],
          "resolution": "720p",
          "video_length": 5,
          "generate_audio": True
      },
      "out_task_id": "flux_3_max_frame_123456"
  }

  headers = {
      "Authorization": "Bearer <token>",
      "Content-Type": "application/json"
  }

  response = requests.post(url, json=payload, headers=headers)

  print(response.json())
  ```

  ```javascript JavaScript theme={null}
  const url = "https://aireiter.com/api/openapi/submit";

  const payload = {
    model: "flux_3_max",
    params: {
      prompt: "A cowboy riding a horse through a canyon at sunset, hooves kicking up dust, sound of hooves and wind",
      type: "frame",
      image_url: ["https://example.com/first-frame.jpg"],
      resolution: "720p",
      video_length: 5,
      generate_audio: true
    },
    out_task_id: "flux_3_max_frame_123456"
  };

  const headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
  };

  fetch(url, {
    method: "POST",
    headers: headers,
    body: JSON.stringify(payload)
  })
    .then(response => response.json())
    .then(data => console.log(data))
    .catch(error => console.error('Error:', error));
  ```

  ```go Go theme={null}
  package main

  import (
      "bytes"
      "encoding/json"
      "fmt"
      "io/ioutil"
      "net/http"
  )

  func main() {
      url := "https://aireiter.com/api/openapi/submit"

      payload := map[string]interface{}{
          "model": "flux_3_max",
          "params": map[string]interface{}{
              "prompt": "A cowboy riding a horse through a canyon at sunset, hooves kicking up dust, sound of hooves and wind",
              "type": "frame",
              "image_url": []string{"https://example.com/first-frame.jpg"},
              "resolution": "720p",
              "video_length": 5,
              "generate_audio": true,
          },
          "out_task_id": "flux_3_max_frame_123456",
      }

      jsonData, _ := json.Marshal(payload)

      req, _ := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
      req.Header.Set("Authorization", "Bearer <token>")
      req.Header.Set("Content-Type", "application/json")

      client := &http.Client{}
      resp, err := client.Do(req)
      if err != nil {
          panic(err)
      }
      defer resp.Body.Close()

      body, _ := ioutil.ReadAll(resp.Body)
      fmt.Println(string(body))
  }
  ```

  ```java Java theme={null}
  import java.net.http.HttpClient;
  import java.net.http.HttpRequest;
  import java.net.http.HttpResponse;
  import java.net.URI;

  public class Main {
      public static void main(String[] args) throws Exception {
          String url = "https://aireiter.com/api/openapi/submit";

          String payload = """
              {
                "model": "flux_3_max",
                "params": {
                  "prompt": "A cowboy riding a horse through a canyon at sunset, hooves kicking up dust, sound of hooves and wind",
                  "type": "frame",
                  "image_url": ["https://example.com/first-frame.jpg"],
                  "resolution": "720p",
                  "video_length": 5,
                  "generate_audio": true
                },
                "out_task_id": "flux_3_max_frame_123456"
              }
          """;

          HttpClient client = HttpClient.newHttpClient();
          HttpRequest request = HttpRequest.newBuilder()
              .uri(URI.create(url))
              .header("Authorization", "Bearer <token>")
              .header("Content-Type", "application/json")
              .POST(HttpRequest.BodyPublishers.ofString(payload))
              .build();

          HttpResponse<String> response = client.send(request,
              HttpResponse.BodyHandlers.ofString());

          System.out.println(response.body());
      }
  }
  ```

  ```php PHP theme={null}
  <?php

  $url = "https://aireiter.com/api/openapi/submit";

  $payload = [
      "model" => "flux_3_max",
      "params" => [
          "prompt" => "A cowboy riding a horse through a canyon at sunset, hooves kicking up dust, sound of hooves and wind",
          "type" => "frame",
          "image_url" => ["https://example.com/first-frame.jpg"],
          "resolution" => "720p",
          "video_length" => 5,
          "generate_audio" => true
      ],
      "out_task_id" => "flux_3_max_frame_123456"
  ];

  $ch = curl_init($url);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_POST, true);
  curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
  curl_setopt($ch, CURLOPT_HTTPHEADER, [
      "Authorization: Bearer <token>",
      "Content-Type: application/json"
  ]);

  $response = curl_exec($ch);
  curl_close($ch);

  echo $response;
  ?>
  ```

  ```ruby Ruby theme={null}
  require 'net/http'
  require 'json'
  require 'uri'

  url = URI("https://aireiter.com/api/openapi/submit")

  payload = {
    model: "flux_3_max",
    params: {
      prompt: "A cowboy riding a horse through a canyon at sunset, hooves kicking up dust, sound of hooves and wind",
      type: "frame",
      image_url: ["https://example.com/first-frame.jpg"],
      resolution: "720p",
      video_length: 5,
      generate_audio: true
    },
    out_task_id: "flux_3_max_frame_123456"
  }

  http = Net::HTTP.new(url.host, url.port)
  http.use_ssl = true

  request = Net::HTTP::Post.new(url)
  request["Authorization"] = "Bearer <token>"
  request["Content-Type"] = "application/json"
  request.body = payload.to_json

  response = http.request(request)
  puts response.body
  ```

  ```swift Swift theme={null}
  import Foundation

  let url = URL(string: "https://aireiter.com/api/openapi/submit")!

  let payload: [String: Any] = [
      "model": "flux_3_max",
      "params": [
          "prompt": "A cowboy riding a horse through a canyon at sunset, hooves kicking up dust, sound of hooves and wind",
          "type": "frame",
          "image_url": ["https://example.com/first-frame.jpg"],
          "resolution": "720p",
          "video_length": 5,
          "generate_audio": true
      ],
      "out_task_id": "flux_3_max_frame_123456"
  ]

  var request = URLRequest(url: url)
  request.httpMethod = "POST"
  request.setValue("Bearer <token>", forHTTPHeaderField: "Authorization")
  request.setValue("application/json", forHTTPHeaderField: "Content-Type")
  request.httpBody = try? JSONSerialization.data(withJSONObject: payload)

  let task = URLSession.shared.dataTask(with: request) { data, response, error in
      if let error = error {
          print("Error: \(error)")
          return
      }

      if let data = data, let responseString = String(data: data, encoding: .utf8) {
          print(responseString)
      }
  }

  task.resume()
  ```

  ```csharp C# theme={null}
  using System;
  using System.Net.Http;
  using System.Text;
  using System.Threading.Tasks;

  class Program
  {
      static async Task Main(string[] args)
      {
          var url = "https://aireiter.com/api/openapi/submit";

          var payload = @"
                {
                    ""model"": ""flux_3_max"",
                    ""params"": {
                        ""prompt"": ""A cowboy riding a horse through a canyon at sunset, hooves kicking up dust, sound of hooves and wind"",
                        ""type"": ""frame"",
                        ""image_url"": [""https://example.com/first-frame.jpg""],
                        ""resolution"": ""720p"",
                        ""video_length"": 5,
                        ""generate_audio"": true
                    },
                    ""out_task_id"": ""flux_3_max_frame_123456""
                }";

          using var client = new HttpClient();
          client.DefaultRequestHeaders.Add("Authorization", "Bearer <token>");

          var content = new StringContent(payload, Encoding.UTF8, "application/json");
          var response = await client.PostAsync(url, content);
          var result = await response.Content.ReadAsStringAsync();

          Console.WriteLine(result);
      }
  }
  ```

  ```c C theme={null}
  #include <stdio.h>
  #include <curl/curl.h>

  int main(void) {
      CURL *curl;
      CURLcode res;

      curl_global_init(CURL_GLOBAL_DEFAULT);
      curl = curl_easy_init();

      if(curl) {
          const char *url = "https://aireiter.com/api/openapi/submit";
          const char *payload = "{\"model\":\"flux_3_max\",\"params\":{\"prompt\":\"A cowboy riding a horse through a canyon at sunset, hooves kicking up dust, sound of hooves and wind\",\"type\":\"frame\",\"image_url\":[\"https://example.com/first-frame.jpg\"],\"resolution\":\"720p\",\"video_length\":5,\"generate_audio\":true},\"out_task_id\":\"flux_3_max_frame_123456\"}";

          struct curl_slist *headers = NULL;
          headers = curl_slist_append(headers, "Authorization: Bearer <token>");
          headers = curl_slist_append(headers, "Content-Type: application/json");

          curl_easy_setopt(curl, CURLOPT_URL, url);
          curl_easy_setopt(curl, CURLOPT_POSTFIELDS, payload);
          curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);

          res = curl_easy_perform(curl);

          if(res != CURLE_OK) {
              fprintf(stderr, "curl_easy_perform() failed: %s\n",
                      curl_easy_strerror(res));
          }

          curl_slist_free_all(headers);
          curl_easy_cleanup(curl);
      }

      curl_global_cleanup();
      return 0;
  }
  ```

  ```objectivec Objective-C theme={null}
  #import <Foundation/Foundation.h>

  int main(int argc, const char * argv[]) {
      @autoreleasepool {
          NSURL *url = [NSURL URLWithString:@"https://aireiter.com/api/openapi/submit"];

          NSDictionary *payload = @{
              @"model": @"flux_3_max",
              @"params": @{
                  @"prompt": @"A cowboy riding a horse through a canyon at sunset, hooves kicking up dust, sound of hooves and wind",
                  @"type": @"frame",
                  @"image_url": @[@"https://example.com/first-frame.jpg"],
                  @"resolution": @"720p",
                  @"video_length": @5,
                  @"generate_audio": @YES
              },
              @"out_task_id": @"flux_3_max_frame_123456"
          };

          NSError *error;
          NSData *jsonData = [NSJSONSerialization dataWithJSONObject:payload
                                                            options:0
                                                              error:&error];

          NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
          [request setHTTPMethod:@"POST"];
          [request setValue:@"Bearer <token>" forHTTPHeaderField:@"Authorization"];
          [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
          [request setHTTPBody:jsonData];

          NSURLSessionDataTask *task = [[NSURLSession sharedSession]
              dataTaskWithRequest:request
              completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                  if (error) {
                      NSLog(@"Error: %@", error);
                      return;
                  }
                  NSString *result = [[NSString alloc] initWithData:data
                                                          encoding:NSUTF8StringEncoding];
                  NSLog(@"%@", result);
              }];

          [task resume];
          [[NSRunLoop mainRunLoop] run];
      }
      return 0;
  }
  ```

  ```ocaml OCaml theme={null}
  (* Requires cohttp and yojson libraries *)
  open Lwt
  open Cohttp
  open Cohttp_lwt_unix

  let url = "https://aireiter.com/api/openapi/submit"

  let payload = {|{
    "model": "flux_3_max",
    "params": {
      "prompt": "A cowboy riding a horse through a canyon at sunset, hooves kicking up dust, sound of hooves and wind",
      "type": "frame",
      "image_url": ["https://example.com/first-frame.jpg"],
      "resolution": "720p",
      "video_length": 5,
      "generate_audio": true
    },
    "out_task_id": "flux_3_max_frame_123456"
  }|}

  let () =
    let headers = Header.init ()
      |> fun h -> Header.add h "Authorization" "Bearer <token>"
      |> fun h -> Header.add h "Content-Type" "application/json"
    in
    let body = Cohttp_lwt.Body.of_string payload in

    let response = Client.post ~headers ~body (Uri.of_string url) >>= fun (resp, body) ->
      body |> Cohttp_lwt.Body.to_string >|= fun body_str ->
      print_endline body_str
    in
    Lwt_main.run response
  ```

  ```dart Dart theme={null}
  import 'dart:convert';
  import 'package:http/http.dart' as http;

  void main() async {
    final url = Uri.parse('https://aireiter.com/api/openapi/submit');

    final payload = {
      "model": "flux_3_max",
      "params": {
        "prompt": "A cowboy riding a horse through a canyon at sunset, hooves kicking up dust, sound of hooves and wind",
        "type": "frame",
        "image_url": ["https://example.com/first-frame.jpg"],
        "resolution": "720p",
        "video_length": 5,
        "generate_audio": true
      },
      "out_task_id": "flux_3_max_frame_123456"
    };

    final response = await http.post(
      url,
      headers: {
        'Authorization': 'Bearer <token>',
        'Content-Type': 'application/json'
      },
      body: jsonEncode(payload),
    );

    print(response.body);
  }
  ```

  ```r R theme={null}
  library(httr)
  library(jsonlite)

  url <- "https://aireiter.com/api/openapi/submit"

  payload <- list(
    model = "flux_3_max",
    params = list(
      prompt = "A cowboy riding a horse through a canyon at sunset, hooves kicking up dust, sound of hooves and wind",
      type = "frame",
      image_url = I("https://example.com/first-frame.jpg"),
      resolution = "720p",
      video_length = 5,
      generate_audio = TRUE
    ),
    out_task_id = "flux_3_max_frame_123456"
  )

  response <- POST(
    url,
    add_headers(
      Authorization = "Bearer <token>",
      `Content-Type` = "application/json"
    ),
    body = toJSON(payload, auto_unbox = TRUE),
    encode = "raw"
  )

  cat(content(response, "text"))
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "statusCode": 200,
    "message": "",
    "data": {
        "out_task_id": "flux_3_max_frame_123456",
        "status": "pending",
        "created_at": "2026-10-20T06:00:03.438Z"
    }
  }
  ```

  ```json 400 theme={null}
    {
        "statusCode": 400,
        "message": "Missing required field: prompt",
        "ok": false
    }
  ```

  ```json 401 theme={null}
  {
    "error": {
      "code": 401,
      "message": "Authentication failed. Please check your API key."
    }
  }
  ```

  ```json 433 theme={null}
    {
      "error": {
        "code": 433,
        "message": "Insufficient account balance, please recharge and try again"
      }
    }
  ```

  ```json 500 theme={null}
  {
    "error": {
      "code": 500,
      "message": "Internal server error, please try again later"
    }
  }
  ```
</ResponseExample>

## Mode Notes

<Note>
  `text` generates using only prompts; `frame` fixes the beginning of the video (and optionally the end); `keyframes` uses multiple images to constrain the flow of the entire video, with the images evenly distributed in sequence across the timeline (for example, providing 3 images for a 10-second video places them at seconds 0, 5, and 10). All three modes are priced the same, billed by output duration in seconds and resolution.
</Note>

<Warning>
  `frame` mode uses up to 2 images (first frame + last frame), and any excess will be ignored; `keyframes` mode supports up to 10 images. `text` mode will ignore any provided images.
</Warning>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.