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

# Batch Upload Session

> Upload multiple audio files on the same Suno account

When you upload several files with the single [Upload Audio](/api-reference/suno/upload) endpoint, each call may land on a **different Suno account**. That breaks flows that require clips on one account — [Inspiration](/api-reference/suno/inspiration), [Create Persona](/api-reference/suno/persona), and similar.

**Batch Upload Session** binds one account at prepare time; every item in that session uploads to the **same account**.

## Workflow

```
Step 1: POST /suno/v2/audio/upload/session
        → sessionId (account selected synchronously)

Step 2: POST /suno/v2/audio/upload/session/item  (×N, can run in parallel)
        → taskId per file (async)

Step 3: GET /suno/v2/status?taskId={sessionId}
        → aggregated audioIds[]
```

| Step | Endpoint                                  | Type      | Purpose                          |
| ---- | ----------------------------------------- | --------- | -------------------------------- |
| 1    | `POST /suno/v2/audio/upload/session`      | Sync      | Pick account, return `sessionId` |
| 2    | `POST /suno/v2/audio/upload/session/item` | Async × N | Upload one file on bound account |
| 3    | `GET /suno/v2/status?taskId={sessionId}`  | Query     | All clip IDs in `data.audioIds`  |

<Info>
  Existing `POST /suno/v2/upload` is unchanged. Use the session flow only when you need **multiple clips on one account**.
</Info>

***

## Step 1 — Create session

[Prepare Upload Session](/api-reference/suno/uploadSessionPrepare) — no request body.

**Response:**

```json theme={null}
{
  "sessionId": "f259907e-32dd-468d-95f9-e3c0baf4f01c"
}
```

* Synchronous — returns immediately
* A random available upload account is selected and stored on the session
* Session task status is `success`; `result.audioIds` starts as `[]`

***

## Step 2 — Upload items (concurrent OK)

[Upload Session Item](/api-reference/suno/uploadSessionItem) — one call per file.

```json theme={null}
{
  "sessionId": "f259907e-32dd-468d-95f9-e3c0baf4f01c",
  "audioUrl": "https://example.com/audio.mp3"
}
```

**Response:**

```json theme={null}
{
  "taskId": "833c3d28-7948-42b8-9d4c-4c145bddfbf5"
}
```

* Async — poll `GET /suno/v2/status?taskId={itemTaskId}` for clip details
* Submit many items with the same `sessionId` in parallel; all use the **same account**
* On each success, the clip ID is appended to the session's `audioIds`
* Credits per item match a normal upload

***

## Step 3 — Poll progress & aggregated IDs

### Per-item status

```
GET /suno/v2/status?taskId={itemTaskId}
```

**Success example:**

```json theme={null}
{
  "taskId": "833c3d28-...",
  "status": "success",
  "data": {
    "id": "e9fe2c0e-189d-4a0a-9f4d-354b1c47b99c",
    "status": "complete",
    "audio_url": "https://cdn1.suno.ai/....mp3",
    "image_url": "https://cdn2.suno.ai/....jpeg",
    "has_vocal": true,
    "display_tags": "indie pop, electronic pop, male vocals"
  }
}
```

### Session aggregate (all clip IDs)

```
GET /suno/v2/status?taskId={sessionId}
```

```json theme={null}
{
  "taskId": "f259907e-...",
  "status": "success",
  "data": {
    "audioIds": [
      "e9fe2c0e-189d-4a0a-9f4d-354b1c47b99c",
      "4595e4da-af12-4c24-a013-9cfd11db7d50"
    ]
  }
}
```

`audioIds` grows as each item completes. In-flight uploads are not listed yet.

***

## Same-account guarantee

```
prepare  →  Random account pick → session.accountId = 500046

item create  →  task.accountId = session.accountId (fixed at creation)

item execute  →  pickAccount(ById, 500046) with row lock — never switches account
```

***

## vs Custom Model upload session

|                              | Custom Model upload            | Batch Upload Session                            |
| ---------------------------- | ------------------------------ | ----------------------------------------------- |
| Account                      | Dedicated custom-model account | Random available upload account                 |
| Next step                    | `customModelCreate` (training) | None — `audioIds` ready to use                  |
| Use case                     | Train `chirp-custom:<uuid>`    | Persona, Inspiration, any same-account workflow |
| Session status after prepare | `READY` (waits for create)     | `success` (prepare is terminal)                 |

***

## Full example

<CodeGroup>
  ```bash Step 1 — Create session theme={null}
  curl -X POST https://api.mountsea.ai/suno/v2/audio/upload/session \
    -H "Authorization: Bearer your-api-key"
  ```

  ```bash Step 2 — Upload (repeat for each file) theme={null}
  curl -X POST https://api.mountsea.ai/suno/v2/audio/upload/session/item \
    -H "Authorization: Bearer your-api-key" \
    -H "Content-Type: application/json" \
    -d '{
      "sessionId": "f259907e-32dd-468d-95f9-e3c0baf4f01c",
      "audioUrl": "https://example.com/a.mp3"
    }'
  ```

  ```bash Step 3 — Session aggregate theme={null}
  curl "https://api.mountsea.ai/suno/v2/status?taskId=f259907e-32dd-468d-95f9-e3c0baf4f01c" \
    -H "Authorization: Bearer your-api-key"
  ```
</CodeGroup>

<Tip>
  Use returned `audioIds` directly in [Inspiration](/api-reference/suno/inspiration) `clip_ids`, or for persona / generate tasks that require one account.
</Tip>
