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

# Suno Common Conventions & Task Query

>  - Common notes for the Suno music API: authentication, async task lifecycle, model / version, source track references
- Task query: GET /v1/music/tasks/:task_id, poll until completed / failed 

<Info>
  This page covers the common conventions shared by all Suno music APIs and is meant to be used alongside the individual documentation for each endpoint. All generation / editing APIs are **asynchronous tasks**: submit to get a `task_id`, then poll the query API on this page to retrieve results.
</Info>

## Authentication

All requests must include the following in the request headers:

```
Authorization: Bearer <Your API Key>
Content-Type: application/json
```

Visit the [API Key management page](https://gccai.heqingsong.uk/keys) to obtain an API Key.

## Task Lifecycle (all APIs are asynchronous)

<Steps>
  <Step title="Submit">
    `POST /v1/music/generations/<operation>` → immediately returns our `task_id`:

    ```json theme={null}
    { "code": 200, "data": [ { "status": "submitted", "task_id": "task_xxx" } ] }
    ```
  </Step>

  <Step title="Poll">
    `GET /v1/music/tasks/:task_id` until `status` is `completed` or `failed`. While generating, `status` is `pending` and `progress` goes queued `10` → ready `50` → done `100`. A polling interval of 3–5s is recommended; music generation usually takes 30–120s.
  </Step>

  <Step title="Retrieve results">
    On completion, take `audio_url` / `image_url` / `video_url`, etc. from `data.result.music[]`.
  </Step>
</Steps>

Task status transitions: `submitted` → `pending` → `completed` / `failed`. **On failure, `data.error.message` gives the reason and the pre-deducted quota is automatically refunded.**

## Version

`v3.5` / `v4` / `v4.5` / `v4.5+` / `v4.5-all` / `v5` / `v5.5`, affecting audio quality and billing; the default is used if omitted. Availability and defaults vary per endpoint — some support only a subset, and some have no version dimension at all; see each endpoint's own documentation.

## Referencing a Source Track: task\_id + audio\_index

Operations based on an existing song (extend / cover / stem separation / add vocals / trim…) **do not** require you to remember any upstream id; you only pass:

* `task_id`: our `task_id` for the task that produced the source track
* `audio_index`: which track in that task's result `music[]` (1-based, defaults to `1`; a single generation usually produces 2 tracks: 1 and 2)

<Warning>
  If the source cannot be resolved (task not complete / index out of range / `task_id` not found), a `400` is returned at submission time.
</Warning>

## Query Task: GET /v1/music/tasks/:task\_id

<ParamField path="task_id" type="string" required>
  Our `task_id` returned by the submit API.
</ParamField>

Poll this API until `status` is `completed` or `failed`. Once completed, retrieve the products from `data.result.music[]`.

## Response

<ResponseField name="task_id" type="string">
  Unique task identifier
</ResponseField>

<ResponseField name="status" type="string">
  Task status: `submitted` / `pending` / `completed` / `failed`
</ResponseField>

<ResponseField name="progress" type="integer">
  Progress: queued `10` → ready `50` → done `100`
</ResponseField>

<ResponseField name="data" type="object">
  Result data

  <Expandable title="Properties">
    <ResponseField name="result" type="object">
      Present when `status` is `completed`

      <Expandable title="result properties">
        <ResponseField name="music" type="array">
          List of products (a single generation usually produces 2 tracks)

          <Expandable title="music[] properties">
            <ResponseField name="audio_id" type="string">
              Track id, used with `audio_index` to locate it for subsequent operations
            </ResponseField>

            <ResponseField name="title" type="string">
              Title
            </ResponseField>

            <ResponseField name="duration" type="number">
              Duration (seconds)
            </ResponseField>

            <ResponseField name="lyrics" type="string">
              Lyrics
            </ResponseField>

            <ResponseField name="tags" type="string">
              Style tags
            </ResponseField>

            <ResponseField name="audio_url" type="string">
              Audio file URL
            </ResponseField>

            <ResponseField name="image_url" type="string">
              Cover image URL
            </ResponseField>

            <ResponseField name="image_large_url" type="string">
              Large cover image URL
            </ResponseField>

            <ResponseField name="video_url" type="string">
              MV video URL (if already generated)
            </ResponseField>
          </Expandable>
        </ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="error" type="object">
      Present when `status` is `failed`

      <Expandable title="error properties">
        <ResponseField name="message" type="string">
          Failure reason (the pre-deducted quota is automatically refunded)
        </ResponseField>
      </Expandable>
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseExample>
  ```json completed theme={null}
  {
    "task_id": "task_01ABC...",
    "status": "completed",
    "progress": 100,
    "data": {
      "result": {
        "music": [
          {
            "audio_id": "<track id, used with audio_index to locate it for subsequent operations>",
            "title": "Summer Breeze",
            "duration": 128.5,
            "lyrics": "……",
            "tags": "electronic, upbeat",
            "audio_url": "https://.../xxx.mp3",
            "image_url": "https://.../cover.png",
            "image_large_url": "https://.../cover_large.png",
            "video_url": "https://.../mv.mp4"
          }
        ]
      }
    }
  }
  ```

  ```json failed theme={null}
  {
    "task_id": "task_01ABC...",
    "status": "failed",
    "progress": 100,
    "data": {
      "error": {
        "message": "generation failed"
      }
    }
  }
  ```
</ResponseExample>
