<!-- Gard Suno AI — Markdown export aligned with /docs/suno-ai (errors, auth, endpoints, callbacks). -->

# Suno AI API

_Public reference export — aligned with [**docs/suno-ai**](https://gard-api.org/docs/suno-ai) on the Gard site (API base below is the public API origin for requests)._

## Introduction

Music generation, extend, stems, WAV, MIDI, video — all in one place on Gard. Every route lives under **`/api/v1/suno`**.

**Models** — use Custom mode and set **`model`** to one of: **V4**, **V4_5**, **V4_5PLUS**, **V4_5ALL**, **V5**, **V5_5**.

**Task ids** — async jobs return a **`taskId`** with a short prefix (`gs_` generate, `gse_` extend, `gsl_` lyrics, …). Poll **`GET …/generate/record-info`** with that value (same role as upstream Suno poll — not **`feed`** / **`query`**).

## Errors and response envelope

JSON bodies use **`code`**, **`msg`**, and **`data`**. Some logical failures still return HTTP 200 with a non‑200 **`code`** inside the JSON — always read the envelope.

### Typical HTTP status codes

- **401** — missing or invalid API key.
- **402** — not enough Gard credits for this call.
- **422** — validation error (wrong or missing fields).
- **500** — server-side error.

#### Example — invalid API key

```json
{
  "code": 401,
  "msg": "Invalid API key",
  "data": null
}
```

#### Example — insufficient credits

```json
{
  "code": 402,
  "msg": "Insufficient credits. Please purchase more.",
  "data": null
}
```

#### Example — validation

```json
{
  "code": 422,
  "msg": "...",
  "data": null
}
```

## Authentication

Create an API key in the dashboard, then send it on every request as **`X-API-Key: gard_…`**.

**Base URL:** `https://back.gard-api.org`  
**Suno base:** `https://back.gard-api.org/api/v1/suno`  

```bash
curl https://back.gard-api.org/api/v1/suno/generate \
  -H "X-API-Key: gard_..." \
  -H "Content-Type: application/json" \
  -d '{"customMode":true,"instrumental":false,"model":"V5","prompt":"ambient piano","style":"ambient","title":"Demo"}'
```

## Endpoints

_Unless noted, send JSON bodies with `Content-Type: application/json`. Multipart routes describe form fields in the request example._

### Index

| Method | Path | Summary |
| --- | --- | --- |
| POST | `/api/v1/suno/generate` | Create a new track. Custom mode: **`customMode`: true**, choose **`model`** **V4–V5_5**, lyrics or idea in **`prompt`**, style tags in **`style`**. |
| GET | `/api/v1/suno/generate/record-info` | **Task status and clips** (primary polling). Gard `GET /api/v1/suno/generate/record-info` — parsing and shape match upstream after proxying. |
| POST | `/api/v1/suno/generate/extend` | Continue an existing clip from **`continueAt`** (seconds). |
| POST | `/api/v1/suno/generate/upload-cover` | Cover / remake from an uploaded file or audio URL. |
| POST | `/api/v1/suno/generate/upload-extend` | Upload audio and extend it. |
| POST | `/api/v1/suno/generate/replace-section` | Replace a segment (infill) between **`infillStartS`** and **`infillEndS`**. |
| POST | `/api/v1/suno/generate/add-instrumental` | Add instrumental bed under vocals (underpaint). |
| POST | `/api/v1/suno/generate/add-vocals` | Add vocals on top of an instrumental (overpaint). |
| POST | `/api/v1/suno/generate/generate-persona` | Create a persona from a clip. |
| GET | `/api/v1/suno/generate/persona-status` | Persona creation status. |
| POST | `/api/v1/suno/style/generate` | Boost style tags derived from free-text descriptors. |
| POST | `/api/v1/suno/lyrics` | Generate lyrics from a prompt. |
| GET | `/api/v1/suno/lyrics/record-info` | Lyrics generation result. |
| POST | `/api/v1/suno/generate/get-timestamped-lyrics` | Line-level timestamps for a clip. |
| POST | `/api/v1/suno/suno/cover/generate` | Album art image for a track. |
| GET | `/api/v1/suno/suno/cover/record-info` | Cover generation status. |
| POST | `/api/v1/suno/wav/generate` | Export WAV. |
| GET | `/api/v1/suno/wav/record-info` | Finished WAV download info. |
| POST | `/api/v1/suno/vocal-removal/generate` | Stem separation / vocal isolation. |
| POST | `/api/v1/suno/generate/upload-vocal-removal` | Stems from an uploaded file (multipart). |
| GET | `/api/v1/suno/vocal-removal/record-info` | Stem separation result. |
| POST | `/api/v1/suno/midi/generate` | MIDI from audio. |
| GET | `/api/v1/suno/midi/record-info` | MIDI job result. |
| POST | `/api/v1/suno/generate/sounds` | Sound effects. |
| POST | `/api/v1/suno/generate/mashup` | Mashup two sources. |
| POST | `/api/v1/suno/generate/mp4` | Video from audio (simplified multipart flow). |
| GET | `/api/v1/suno/generate/waveform` | Waveform points for visualization. |

---

## POST `/api/v1/suno/generate`

Create a new track. Custom mode: **`customMode`: true**, choose **`model`** **V4–V5_5**, lyrics or idea in **`prompt`**, style tags in **`style`**.

**Polling:** `GET /api/v1/suno/generate/record-info?taskId=<taskId from response>`. Wait until `data.status` is `SUCCESS`; finished clips live in `data.response.sunoData[]` (`audioUrl`; duplicates may appear as `audio_url`). Same semantics as upstream **`record-info`**, with Gard public **`taskId`** prefixes. **Do not confuse** with **`feed`** / **`query`** — those query clips by UUID only.

### Request fields

| Field | Type | Required | Description | Options |
| --- | --- | --- | --- | --- |
| customMode | boolean |  | Must be **`true`** when using **`model`** below. |  |
| instrumental | boolean |  | **true** — instrumental only (no vocals). |  |
| model | string | yes | Engine version. | V4 · V4_5 · V4_5PLUS · V4_5ALL · V5 · V5_5 |
| prompt | string |  | Lyrics text or creative brief. |  |
| style | string |  | Genres / style tags. |  |
| title | string |  | Track title. |  |
| callBackUrl | string |  | HTTPS URL for completion webhook. |  |

#### Example request

```json
{
  "customMode": true,
  "instrumental": false,
  "model": "V5",
  "prompt": "Verse about the sea at dawn, hopeful mood",
  "style": "indie folk, acoustic guitar, soft drums",
  "title": "Dawn Tide",
  "vocalGender": "f",
  "styleWeight": 0.75,
  "weirdnessConstraint": 0.35,
  "callBackUrl": "https://your-app.com/webhooks/gard-suno"
}
```

#### Example response

```json
{
  "code": 200,
  "msg": "success",
  "data": { "taskId": "gs_xxxxxxxxxxxxxxxx" }
}
```


## GET `/api/v1/suno/generate/record-info`

**Task status and clips** (primary polling). Gard `GET /api/v1/suno/generate/record-info` — parsing and shape match upstream after proxying.

Poll until `SUCCESS`. MP3 URLs: **`audioUrl`** in `sunoData[]` (also check **`streamAudioUrl`** when needed).

#### Example request

```text
GET /api/v1/suno/generate/record-info?taskId=gs_xxxxxxxxxxxxxxxx
```

#### Example response

```json
{
  "code": 200,
  "msg": "success",
  "data": {
    "taskId": "gs_xxxxxxxxxxxxxxxx",
    "status": "SUCCESS",
    "type": "GENERATE",
    "response": {
      "taskId": "gs_xxxxxxxxxxxxxxxx",
      "sunoData": [
        {
          "id": "clip-uuid-from-suno",
          "audioUrl": "https://…/….mp3",
          "title": "Dawn Tide",
          "tags": "indie folk",
          "duration": 198
        }
      ]
    },
    "errorCode": null,
    "errorMessage": null
  }
}
```


## POST `/api/v1/suno/generate/extend`

Continue an existing clip from **`continueAt`** (seconds).

Task id prefix: **`gse_`**.

### Request fields

| Field | Type | Required | Description | Options |
| --- | --- | --- | --- | --- |
| audioId | string | yes | Clip id from **`record-info`** / **`feed`**. |  |
| model | string |  | **V4** … **V5_5**. |  |

#### Example request

```json
{
  "audioId": "clip_from_previous_job",
  "model": "V5",
  "prompt": "extend with an outro, same energy",
  "style": "indie folk, acoustic",
  "title": "Dawn Tide (extended)",
  "continueAt": 48.0,
  "defaultParamFlag": true,
  "callBackUrl": "https://your-app.com/webhooks/gard-suno"
}
```

#### Example response

```json
{ "code": 200, "msg": "success", "data": { "taskId": "gse_xxxxxxxxxxxxxxxx" } }
```


## POST `/api/v1/suno/generate/upload-cover`

Cover / remake from an uploaded file or audio URL.

### Request fields

| Field | Type | Required | Description | Options |
| --- | --- | --- | --- | --- |
| file OR uploadUrl | file \| string |  | Either **`file`** or **`uploadUrl`** is required. |  |

#### Example request

```text
// JSON variant (no file):

{
  "uploadUrl": "https://your-cdn.com/reference.mp3",
  "customMode": true,
  "instrumental": false,
  "model": "V5",
  "title": "My Cover",
  "prompt": "same vibe, new arrangement",
  "tags": "synthwave, dreamy",
  "callBackUrl": "https://your-app.com/webhooks/gard-suno"
}

// Multipart: field file + the same text fields as form entries.
```

#### Example response

```json
{ "code": 200, "msg": "success", "data": { "taskId": "gsuc_xxxxxxxxxxxxxxxx" } }
```


## POST `/api/v1/suno/generate/upload-extend`

Upload audio and extend it.

#### Example request

```json
{
  "uploadUrl": "https://your-cdn.com/stem.wav",
  "continueAt": 0,
  "model": "V5",
  "prompt": "continue the groove",
  "title": "Extended jam",
  "tags": "funk, bass",
  "callBackUrl": "https://your-app.com/webhooks/gard-suno"
}

// Or multipart: file + the fields above as form fields.
```

#### Example response

```json
{ "code": 200, "msg": "success", "data": { "taskId": "gsue_xxxxxxxxxxxxxxxx" } }
```


## POST `/api/v1/suno/generate/replace-section`

Replace a segment (infill) between **`infillStartS`** and **`infillEndS`**.

### Request fields

| Field | Type | Required | Description | Options |
| --- | --- | --- | --- | --- |
| taskId | string | yes | Parent task **`gs_…`**. |  |
| audioId | string | yes | Clip to edit. |  |

#### Example request

```json
{
  "taskId": "gs_parent_task_id",
  "audioId": "clip_to_edit",
  "prompt": "new lyrics for this section only",
  "tags": "pop, bright",
  "title": "My Track (edit)",
  "infillStartS": 12.5,
  "infillEndS": 28.0,
  "fullLyrics": null,
  "negativeTags": "metal",
  "callBackUrl": "https://your-app.com/webhooks/gard-suno"
}
```

#### Example response

```json
{ "code": 200, "msg": "success", "data": { "taskId": "gsrs_xxxxxxxxxxxxxxxx" } }
```


## POST `/api/v1/suno/generate/add-instrumental`

Add instrumental bed under vocals (underpaint).

### Request fields

| Field | Type | Required | Description | Options |
| --- | --- | --- | --- | --- |
| audioId | string | yes | Clip that contains vocals. |  |

#### Example request

```json
{
  "audioId": "vocals_only_clip_id",
  "prompt": "soft piano and brush drums",
  "title": "With bed",
  "style": "lo-fi, warm",
  "model": "V5",
  "negativeTags": "distortion",
  "callBackUrl": "https://your-app.com/webhooks/gard-suno"
}
```

#### Example response

```json
{ "code": 200, "msg": "success", "data": { "taskId": "gsai_xxxxxxxxxxxxxxxx" } }
```


## POST `/api/v1/suno/generate/add-vocals`

Add vocals on top of an instrumental (overpaint).

### Request fields

| Field | Type | Required | Description | Options |
| --- | --- | --- | --- | --- |
| audioId | string | yes | Instrumental clip. |  |
| prompt | string | yes | Vocal lyrics / brief. |  |

#### Example request

```json
{
  "audioId": "instrumental_clip_id",
  "prompt": "Verse 1:\nLine one...\nLine two...",
  "title": "With vocals",
  "style": "pop soul",
  "model": "V5",
  "callBackUrl": "https://your-app.com/webhooks/gard-suno"
}
```

#### Example response

```json
{ "code": 200, "msg": "success", "data": { "taskId": "gsav_xxxxxxxxxxxxxxxx" } }
```


## POST `/api/v1/suno/generate/generate-persona`

Create a persona from a clip.

#### Example request

```json
{
  "audioId": "clip_id",
  "name": "Studio Persona A",
  "taskId": "gs_optional_parent_task",
  "description": "warm baritone ad-libs",
  "isPublic": true,
  "personaType": "vox",
  "vocalStart": 10.0,
  "vocalEnd": 45.0,
  "style": "neo-soul",
  "callBackUrl": "https://your-app.com/webhooks/gard-suno"
}
```

#### Example response

```json
{
  "code": 200,
  "msg": "success",
  "data": { "personaId": "gsp_xxxxxxxxxxxxxxxx", "name": "Studio Persona A", "description": "…" }
}
```


## GET `/api/v1/suno/generate/persona-status`

Persona creation status.

#### Example request

```text
(query only)

GET /api/v1/suno/generate/persona-status?personaId=gsp_xxxxxxxxxxxxxxxx
```

#### Example response

```json
{ "code": 200, "msg": "success", "data": { "status": "…" } }
```


## POST `/api/v1/suno/style/generate`

Boost style tags derived from free-text descriptors.

Body must include **`content`** — comma-separated tags (e.g. **`"Pop, Mysterious"`**). Gard forwards this shape upstream. The JSON **`data`** object typically mirrors the upstream task envelope (**`taskId`**, **`param`**, **`result`**, **`successFlag`**, **`errorCode`**, **`errorMessage`**, **`createTime`**).

#### Example request

```json
{
  "content": "Pop, Mysterious"
}
```

#### Example response

```json
{
  "code": 200,
  "msg": "success",
  "data": {
    "taskId": "<string>",
    "param": "<string>",
    "result": "<string>",
    "successFlag": "<string>",
    "errorCode": 123,
    "errorMessage": "<string>",
    "createTime": "<string>"
  }
}
```


## POST `/api/v1/suno/lyrics`

Generate lyrics from a prompt.

### Request fields

| Field | Type | Required | Description | Options |
| --- | --- | --- | --- | --- |
| prompt | string | yes | Topic or brief. |  |

#### Example request

```json
{
  "prompt": "Upbeat lyrics about Friday night city lights, no profanity",
  "callBackUrl": "https://your-app.com/webhooks/gard-suno"
}
```

#### Example response

```json
{ "code": 200, "msg": "success", "data": { "taskId": "gsl_xxxxxxxxxxxxxxxx" } }
```


## GET `/api/v1/suno/lyrics/record-info`

Lyrics generation result.

#### Example request

```text
GET /api/v1/suno/lyrics/record-info?taskId=gsl_xxxxxxxxxxxxxxxx
```

#### Example response

```json
{
  "code": 200,
  "msg": "success",
  "data": { "id": "lyrics_row", "text": "…", "status": "complete" }
}
```


## POST `/api/v1/suno/generate/get-timestamped-lyrics`

Line-level timestamps for a clip.

#### Example request

```json
{
  "audioId": "clip_id",
  "taskId": "gs_optional_parent_task"
}
```

#### Example response

```json
{
  "code": 200,
  "msg": "success",
  "data": { "lines": [{ "time": 0.0, "text": "First line" }, { "time": 3.2, "text": "Second line" }] }
}
```


## POST `/api/v1/suno/suno/cover/generate`

Album art image for a track.

#### Example request

```json
{
  "taskId": "gs_finished_generation_task",
  "callBackUrl": "https://your-app.com/webhooks/gard-suno"
}

// Or without taskId — audio URL only:
{
  "audioUrl": "https://your-cdn.com/track.mp3",
  "callBackUrl": "https://your-app.com/webhooks/gard-suno"
}
```

#### Example response

```json
{
  "code": 200,
  "msg": "success",
  "data": { "taskId": "gsco_xxxxxxxxxxxxxxxx", "images": ["https://…"] }
}
```


## GET `/api/v1/suno/suno/cover/record-info`

Cover generation status.

#### Example request

```text
GET /api/v1/suno/suno/cover/record-info?taskId=gsco_xxxxxxxxxxxxxxxx
```

#### Example response

```json
{ "code": 200, "msg": "success", "data": { "status": "complete", "images": ["https://…"] } }
```


## POST `/api/v1/suno/wav/generate`

Export WAV.

#### Example request

```json
{
  "audioId": "clip_id",
  "taskId": "gs_parent_task_optional",
  "callBackUrl": "https://your-app.com/webhooks/gard-suno"
}
```

#### Example response

```json
{ "code": 200, "msg": "success", "data": { "taskId": "gswv_xxxxxxxxxxxxxxxx" } }
```


## GET `/api/v1/suno/wav/record-info`

Finished WAV download info.

#### Example request

```text
GET /api/v1/suno/wav/record-info?taskId=gswv_xxxxxxxxxxxxxxxx
```

#### Example response

```json
{
  "code": 200,
  "msg": "success",
  "data": { "audio_wav_url": "https://…", "task_id": "gswv_xxxxxxxxxxxxxxxx" }
}
```


## POST `/api/v1/suno/vocal-removal/generate`

Stem separation / vocal isolation.

Set **`type`** in JSON: **`separate_vocal`** (default) — 2 stems (vocals + instrumental), quick vocal removal / karaoke — **4.5 credits**. **`split_stem`** — up to 12 stems (vocals, backing vocals, drums, bass, guitar, keyboard, strings, brass, woodwinds, percussion, synth, FX/other) for advanced mixing — **23 credits**.

#### Example request

```json
{
  "taskId": "gs_parent_task",
  "audioId": "clip_id",
  "type": "separate_vocal",
  "callBackUrl": "https://your-app.com/webhooks/gard-suno"
}
```

#### Example response

```json
{ "code": 200, "msg": "success", "data": { "taskId": "gsvr_xxxxxxxxxxxxxxxx" } }
```


## POST `/api/v1/suno/generate/upload-vocal-removal`

Stems from an uploaded file (multipart).

Same pricing as **`POST /vocal-removal/generate`**: multipart field **`type`** — **`separate_vocal`** (default) **4.5 credits**, **`split_stem`** **23 credits**.

#### Example request

```text
multipart/form-data:

  file = @mix.wav
  (+ optional taskId, callBackUrl as plain form fields)
```

#### Example response

```json
{ "code": 200, "msg": "success", "data": { "taskId": "gsuv_xxxxxxxxxxxxxxxx" } }
```


## GET `/api/v1/suno/vocal-removal/record-info`

Stem separation result.

#### Example request

```text
GET /api/v1/suno/vocal-removal/record-info?taskId=gsvr_xxxxxxxxxxxxxxxx
```

#### Example response

```json
{
  "code": 200,
  "msg": "success",
  "data": {
    "task_id": "gsvr_xxxxxxxxxxxxxxxx",
    "vocal_separation_info": {
      "stems": [
        { "stem_type": "vocals", "audio_url": "https://…" },
        { "stem_type": "instrumental", "audio_url": "https://…" }
      ]
    }
  }
}
```


## POST `/api/v1/suno/midi/generate`

MIDI from audio.

#### Example request

```json
{
  "audioId": "clip_id",
  "callBackUrl": "https://your-app.com/webhooks/gard-suno"
}
```

#### Example response

```json
{ "code": 200, "msg": "success", "data": { "taskId": "gsmi_xxxxxxxxxxxxxxxx" } }
```


## GET `/api/v1/suno/midi/record-info`

MIDI job result.

#### Example request

```text
GET /api/v1/suno/midi/record-info?taskId=gsmi_xxxxxxxxxxxxxxxx
```

#### Example response

```json
{
  "code": 200,
  "msg": "success",
  "data": { "taskId": "gsmi_xxxxxxxxxxxxxxxx", "state": "complete", "instruments": [] }
}
```


## POST `/api/v1/suno/generate/sounds`

Sound effects.

#### Example request

```json
{
  "prompt": "Short riser for podcast intro, 3 seconds",
  "model": "V5",
  "soundLoop": false,
  "soundTempo": 120,
  "soundKey": "C minor",
  "grabLyrics": false,
  "callBackUrl": "https://your-app.com/webhooks/gard-suno"
}
```

#### Example response

```json
{ "code": 200, "msg": "success", "data": { "taskId": "gssf_xxxxxxxxxxxxxxxx" } }
```


## POST `/api/v1/suno/generate/mashup`

Mashup two sources.

#### Example request

```json
{
  "audioId_1": "first_clip_id",
  "audioId_2": "second_clip_id",
  "customMode": true,
  "instrumental": false,
  "model": "V5",
  "prompt": "blend into one chorus",
  "style": "electronic, house",
  "title": "Mash 01",
  "callBackUrl": "https://your-app.com/webhooks/gard-suno"
}

// Alternative:
// "uploadUrlList": ["https://…/a.mp3", "https://…/b.mp3"]
```

#### Example response

```json
{ "code": 200, "msg": "success", "data": { "taskId": "gsmu_xxxxxxxxxxxxxxxx" } }
```


## POST `/api/v1/suno/generate/mp4`

Video from audio (simplified multipart flow).

**Billing:** 0 Gard credits. After **`POST`** you receive **`taskId`** in **`data`**. Poll **`GET /api/v1/suno/generate/record-info?taskId=<taskId>`** (same envelope as music generation) until status completes, or use **`callBackUrl`** webhooks.

#### Example request

```text
multipart/form-data:

  audioId = clip_id
  callBackUrl = https://your-app.com/webhooks/gard-suno
```

#### Example response

```json
{ "code": 200, "msg": "success", "data": { "taskId": "gsvi_xxxxxxxxxxxxxxxx" } }
```


## GET `/api/v1/suno/generate/waveform`

Waveform points for visualization.

#### Example request

```text
GET /api/v1/suno/generate/waveform?audioId=clip_id
```

#### Example response

```json
{ "code": 200, "msg": "success", "data": { "waveformData": [0.12, 0.34, …] } }
```


---

## Callbacks (webhooks)

Optional: set **`callBackUrl`** on async requests to receive a POST when the job finishes.

If you pass **`callBackUrl`** (HTTPS) in the request body, we POST a JSON payload there when the job completes. The shape uses **`code`**, **`msg`**, and **`data`**; inside **`data`** you will see fields such as **`callbackType`** (`complete`, `error`, and sometimes intermediate states for long jobs), **`task_id`**, and clip rows with URLs and metadata.

### Sample payload

```
POST https://your-app.com/suno/callback
Content-Type: application/json

{
  "code": 200,
  "msg": "All generated successfully.",
  "data": {
    "callbackType": "complete",
    "task_id": "gs_xxxxxxxx",
    "data": [
      {
        "id": "…",
        "audio_url": "https://…",
        "title": "My Song",
        "model_name": "V5",
        "tags": "pop"
      }
    ]
  }
}
```
