Skip to main content
Create a personalized music model trained on your own audio. The process requires three steps: prepare (create session) → upload (upload training audio, at least 6) → create (submit for training).

Workflow

 ① customModel/prepare
      │  Select account, create session
      │  Returns: { sessionId }


 ② customModel/upload  ×N (at least 6)
      │  Upload audio files one by one (async)
      │  Returns: { taskId }
      │  Poll: GET /suno/v2/status?taskId=xxx
      │  Result contains clip info (including id)

      │  Can upload in parallel, each polled independently


 ③ customModel/create
      │  Submit clipIds + model name → Start training
      │  Returns: { taskId } (taskId = sessionId)
      │  Poll: GET /suno/v2/status?taskId=xxx
      │  Training takes ~2-3 minutes
      │  Result contains custom model details (including model ID)

    Done → Use model ID in /generate

Step 1: Prepare — Create Session

Create a session and bind an account. All subsequent upload and create calls use the same account automatically.

Request

POST /suno/v2/customModel/prepare
No request body required.

Response

{
  "sessionId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
The sessionId is the unique identifier for the entire workflow. Keep it for subsequent steps.
See Prepare API Reference →

Step 2: Upload — Upload Training Audio

Upload audio files one at a time. Each call is async and returns a taskId. You need to poll until the task succeeds to get the clipId from the result. Minimum 6 audio files are required before you can proceed to the create step. Multiple uploads can run in parallel.

Request

POST /suno/v2/customModel/upload
FieldTypeRequiredDescription
sessionIdstring (UUID)YesSession ID from prepare step
audioUrlstring (URL)YesPublicly downloadable audio URL

Task Result

On success, the result contains clip info including an id field — this is the clipId needed for the create step. See Upload API Reference →

Step 3: Create — Submit for Training

After collecting at least 6 clipIds from successful uploads, submit the training request. This costs 100 credits and takes approximately 2-3 minutes.

Request

POST /suno/v2/customModel/create
FieldTypeRequiredDescription
sessionIdstring (UUID)YesSession ID from prepare step
clipIdsstring[]YesClip IDs from upload results (at least 6)
namestringYesCustom model name
The returned taskId equals the sessionId. You can poll using either one.
On success, the result contains the custom model details. The model ID format is chirp-custom:<uuid>. See Create API Reference →

Using Your Custom Model

Once training is complete, use the model ID directly in the Generate endpoint:
{
  "task": "create",
  "model": "chirp-custom:3b285ad7-b09c-48fe-99e6-ec8a109f0650",
  "prompt": "[Verse]\nA catchy pop melody...",
  "tags": "Pop, Upbeat"
}
The system automatically uses the same account that created the custom model for generation.

Complete Example

const API_BASE = 'https://api.mountsea.ai';
const headers = {
  'Content-Type': 'application/json',
  'Authorization': 'Bearer your-api-key'
};

async function pollTask(taskId) {
  while (true) {
    const res = await fetch(`${API_BASE}/suno/v2/status?taskId=${taskId}`, { headers });
    const task = await res.json();
    if (task.status === 'success') return task.data;
    if (task.status === 'failed') throw new Error(task.failReason);
    await new Promise(r => setTimeout(r, 3000));
  }
}

// Step 1: Prepare session
const prepareRes = await fetch(`${API_BASE}/suno/v2/customModel/prepare`, {
  method: 'POST',
  headers
});
const { sessionId } = await prepareRes.json();
console.log('Session ID:', sessionId);

// Step 2: Upload audio files (at least 6, can run in parallel)
const audioUrls = [
  'https://example.com/song1.mp3',
  'https://example.com/song2.mp3',
  'https://example.com/song3.mp3',
  'https://example.com/song4.mp3',
  'https://example.com/song5.mp3',
  'https://example.com/song6.mp3',
];

const uploadPromises = audioUrls.map(async (audioUrl) => {
  const res = await fetch(`${API_BASE}/suno/v2/customModel/upload`, {
    method: 'POST',
    headers,
    body: JSON.stringify({ sessionId, audioUrl })
  });
  const { taskId } = await res.json();
  const result = await pollTask(taskId);
  return result.id; // clipId
});

const clipIds = await Promise.all(uploadPromises);
console.log('Uploaded clips:', clipIds);

// Step 3: Create custom model
const createRes = await fetch(`${API_BASE}/suno/v2/customModel/create`, {
  method: 'POST',
  headers,
  body: JSON.stringify({
    sessionId,
    clipIds,
    name: 'My Custom Model'
  })
});
const { taskId: createTaskId } = await createRes.json();
const model = await pollTask(createTaskId);
console.log('Custom model created:', model);
// Use model.id (e.g. "chirp-custom:xxx") in /generate

Failure Recovery

  • Upload fails: Retry with the same sessionId — no need to re-prepare.
  • Create fails (e.g. parameter error): Retry with the same sessionId and corrected parameters. The system automatically resets the session state.
  • Prepare rarely fails since it only creates a session and binds an account.

Important Notes

The create step costs 100 credits. Make sure all uploaded clips are correct before submitting.
  • Same account guarantee: prepare / upload / create automatically use the same Suno account — no manual specification needed.
  • Credits: The create step costs 100 credits. Upload steps also have minor credit costs based on task pricing configuration.
  • ClipId validation: All clipIds in the create request must come from uploads within the current session, otherwise a 400 error is returned.
  • Parallel uploads: Multiple upload requests can be sent concurrently without conflicts.
  • Model limits: Each custom account has a maximum number of models it can create, configured by the administrator.