> ## 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.

# Suno Music Generation

> - Suno text-to-music generation, returning two original songs at once
- Asynchronous processing mode, returns a task ID for subsequent queries
- Supports simple mode and custom mode, and can generate vocals or instrumental music
- Supports V4 / V4.5 / V4.5+ / V4.5 All / V5 / V5.5


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

<Note>
  Suno's model name in AIReiter is `suno`. Please use `suno_lyrics`, `suno_extend`, and `suno_cover` for lyrics, continuation, and cover versions, respectively.
</Note>

## Authorizations

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

  Get the API Key:

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

  When using it, add the following to the request header:

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

## Body

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

  * `suno`
</ParamField>

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

  <Expandable title="params Object Properties">
    <ParamField body="prompt" type="string" required>
      Song description. You can include the theme, mood, instruments, and rhythm.

      When custom mode is turned off, the model will automatically write the title, style, and lyrics based on this. When custom mode is on and it is not instrumental music, the prompt will be treated as lyrics.

      The V5 / V5.5 / V4.5 series supports up to 5,000 characters.
    </ParamField>

    <ParamField body="suno_model" type="string" default="V5">
      Suno version:

      * `V4`
      * `V4_5`
      * `V4_5PLUS`
      * `V4_5ALL`
      * `V5` - Default Value
      * `V5_5`
    </ParamField>

    <ParamField body="custom_mode" type="boolean" default="false">
      Whether to enable custom mode.

      * `false` - Simple mode. Only fill in the prompt; the title, style, and lyrics are generated by the model
      * `true` - Custom mode. You must specify `title` and `style`; when vocals are present, `prompt` is used as lyrics
    </ParamField>

    <ParamField body="instrumental" type="boolean" default="false">
      Whether to generate instrumental music.

      * `false` - Generate a song with vocals
      * `true` - Output only the accompaniment, with no vocals or lyrics
    </ParamField>

    <ParamField body="vocal_gender" type="string" default="m">
      Preferred vocal gender. Ignored for instrumental music.

      * `m` - Male vocals, default value
      * `f` - Female vocals
    </ParamField>

    <ParamField body="title" type="string">
      Song title. Only valid in custom mode, up to 100 characters. Required when `custom_mode` is enabled.
    </ParamField>

    <ParamField body="style" type="string">
      Genre and production direction, such as indie folk, lo-fi hip hop, or 80s synthwave. Only valid in custom mode, up to 1,000 characters. Required when `custom_mode` is enabled.
    </ParamField>
  </Expandable>
</ParamField>

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

  User-defined task identifier, required. Only letters, numbers, underscores, and hyphens are supported, with a length of 1-64 characters. You can use this ID to query task status and results later.
</ParamField>

## Response

<ResponseField name="out_task_id" type="string">
  The initiator's task ID, which can be used to query the result.
</ResponseField>

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

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

## Query Task

Suno is an asynchronous music generation model. After submitting a task, use `out_task_id` to query the task status. Once completed, `output` usually contains 2 songs, each including `audio` (audio URL), `url` (cover image), `title`, and `text` (lyrics).

<ParamField body="out_task_id" type="string" required>
  The originating 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": "suno_gen_123456"
  }'
```

After a successful query and completion, example `output`:

```json theme={null}
{
  "statusCode": 200,
  "message": "",
  "data": {
    "out_task_id": "suno_gen_123456",
    "status": "completed",
    "created_at": "2026-08-26T10:12:11.000Z",
    "completed_at": "2026-08-26T10:14:41.000Z",
    "output": [
      {
        "audio": "https://s1.pxz.ai/upload/audio-generator/20260826/suno-audio-0.mp3",
        "url": "https://s1.pxz.ai/upload/audio-generator/20260826/suno-cover-0.jpeg",
        "title": "Morning Coffee",
        "text": "[Verse]\\nA warm acoustic morning..."
      },
      {
        "audio": "https://s1.pxz.ai/upload/audio-generator/20260826/suno-audio-1.mp3",
        "url": "https://s1.pxz.ai/upload/audio-generator/20260826/suno-cover-1.jpeg",
        "title": "Morning Coffee",
        "text": "[Verse]\\nSunlight on the kitchen table..."
      }
    ]
  }
}
```

## Request Examples

<RequestExample>
  ```bash cURL (Simple Mode) theme={null}
  curl --request POST \
    --url https://aireiter.com/api/openapi/submit \
    --header 'Authorization: Bearer <token>' \
    --header 'Content-Type: application/json' \
    --data '{
      "model": "suno",
      "params": {
        "prompt": "A warm acoustic folk song about morning coffee, with soft female vocals, guitar, and light drums",
        "suno_model": "V5",
        "custom_mode": false,
        "instrumental": false
      },
      "out_task_id": "suno_gen_123456"
    }'
  ```

  ```bash cURL (Custom Mode) theme={null}
  curl --request POST \
    --url https://aireiter.com/api/openapi/submit \
    --header 'Authorization: Bearer <token>' \
    --header 'Content-Type: application/json' \
    --data '{
      "model": "suno",
      "params": {
        "prompt": "[Verse]\\nThere is a cup of hot coffee on the morning windowsill\\n[Chorus]\\nLet this song slowly wake up",
        "suno_model": "V5",
        "custom_mode": true,
        "instrumental": false,
        "title": "Morning Coffee",
        "style": "indie folk, warm female vocals, acoustic guitar",
        "vocal_gender": "f"
      },
      "out_task_id": "suno_custom_123456"
    }'
  ```

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

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

  payload = {
      "model": "suno",
      "params": {
          "prompt": "A warm acoustic folk song about morning coffee, with soft female vocals, guitar, and light drums",
          "suno_model": "V5",
          "custom_mode": False,
          "instrumental": False
      },
      "out_task_id": "suno_gen_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: "suno",
    params: {
      prompt: "A warm acoustic folk song about morning coffee, with soft female vocals, guitar, and light drums",
      suno_model: "V5",
      custom_mode: false,
      instrumental: false
    },
    out_task_id: "suno_gen_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": "suno",
          "params": map[string]interface{}{
              "prompt": "A warm acoustic folk song about morning coffee, with soft female vocals, guitar, and light drums",
              "suno_model": "V5",
              "custom_mode": false,
              "instrumental": false,
          },
          "out_task_id": "suno_gen_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": "suno",
                "params": {
                  "prompt": "A warm acoustic folk song about morning coffee, with soft female vocals, guitar, and light drums",
                  "suno_model": "V5",
                  "custom_mode": false,
                  "instrumental": false
                },
                "out_task_id": "suno_gen_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" => "suno",
      "params" => [
          "prompt" => "A warm acoustic folk song about morning coffee, with soft female vocals, guitar, and light drums",
          "suno_model" => "V5",
          "custom_mode" => false,
          "instrumental" => false
      ],
      "out_task_id" => "suno_gen_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: "suno",
    params: {
      prompt: "A warm acoustic folk song about morning coffee, with soft female vocals, guitar, and light drums",
      suno_model: "V5",
      custom_mode: false,
      instrumental: false
    },
    out_task_id: "suno_gen_123456"
  }

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

  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": "suno",
      "params": [
          "prompt": "A warm acoustic folk song about morning coffee, with soft female vocals, guitar, and light drums",
          "suno_model": "V5",
          "custom_mode": false,
          "instrumental": false
      ],
      "out_task_id": "suno_gen_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": "suno",
                      "params": {
                        "prompt": "A warm acoustic folk song about morning coffee, with soft female vocals, guitar, and light drums",
                        "suno_model": "V5",
                        "custom_mode": false,
                        "instrumental": false
                      },
                      "out_task_id": "suno_gen_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\":\"suno\",\"params\":{\"prompt\":\"A warm acoustic folk song about morning coffee, with soft female vocals, guitar, and light drums\",\"suno_model\":\"V5\",\"custom_mode\":false,\"instrumental\":false},\"out_task_id\":\"suno_gen_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": @"suno",
              @"params": @{
                  @"prompt": @"A warm acoustic folk song about morning coffee, with soft female vocals, guitar, and light drums",
                  @"suno_model": @"V5",
                  @"custom_mode": @NO,
                  @"instrumental": @NO
              },
              @"out_task_id": @"suno_gen_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": "suno",
  "params": {
    "prompt": "A warm acoustic folk song about morning coffee, with soft female vocals, guitar, and light drums",
    "suno_model": "V5",
    "custom_mode": false,
    "instrumental": false
  },
  "out_task_id": "suno_gen_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: "suno",
      params: {
        prompt: "A warm acoustic folk song about morning coffee, with soft female vocals, guitar, and light drums",
        suno_model: "V5",
        custom_mode: false,
        instrumental: false
      },
      out_task_id: "suno_gen_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 = "suno",
    params = list(
      prompt = "A warm acoustic folk song about morning coffee, with soft female vocals, guitar, and light drums",
      suno_model = "V5",
      custom_mode = FALSE,
      instrumental = FALSE
    ),
    out_task_id = "suno_gen_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": "suno_gen_123456",
        "status": "pending",
        "created_at": "2026-08-26T10:12:11.000Z"
    }
  }
  ```

  ```json 400 theme={null}
    {
        "statusCode": 400,
        "message": "Invalid request parameters",
        "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 top up and try again"
      }
    }
  ```

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

## Mode Notes

<Note>
  Simple mode only requires `prompt`. For custom mode, pass both `title` and `style`; if there are vocals, put the lyrics in `prompt`.
</Note>

<Warning>
  `vocal_gender` only takes effect when `instrumental` is `false`. A single request usually returns two candidate songs.
</Warning>


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