Skip to main content

Complete Workflow

This guide walks through the full flow of generating music with sunor: authenticate, create a task, poll until it completes, and use the audio output.

Prerequisites

  • A sunor account with an API key
  • Credits in your account (music costs 10 credits)

Step 1: Create a task

Submit a music generation request:
import requests

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://sunor.cc/api/v1"

response = requests.post(
    f"{BASE_URL}/task",
    headers={
        "Content-Type": "application/json",
        "x-api-key": API_KEY,
    },
    json={
        "model": "suno",
        "task_type": "music",
        "input": {
            "gpt_description_prompt": "A chill lo-fi beat for studying, soft piano and vinyl crackle",
            "make_instrumental": True,
        },
    },
)

task = response.json()["data"]
task_id = task["task_id"]
print(f"Task created: {task_id} (status: {task['status']})")
The response returns a task_id with status "pending". Credits are frozen immediately.

Step 2: Poll for results

Tasks take 30 seconds to 5 minutes to complete. Poll every 5-10 seconds until the status is terminal (success, failure, or timeout).
import time

def wait_for_task(api_key, task_id, interval=5):
    """Poll until the task completes. Returns the task data."""
    while True:
        response = requests.get(
            f"{BASE_URL}/task/{task_id}",
            headers={"x-api-key": api_key},
        )
        data = response.json()["data"]
        status = data["status"]
        print(f"  Status: {status}")

        if status in ("success", "failure", "timeout"):
            return data

        time.sleep(interval)

result = wait_for_task(API_KEY, task_id)

Step 3: Use the output

On success, the output.result contains an array of generated clips:
if result["status"] == "success":
    clips = result["output"]["result"]
    for clip in clips:
        print(f"Title: {clip['title']}")
        print(f"Audio: {clip['audio_url']}")
        print(f"Cover: {clip['image_url']}")
        print()
else:
    print(f"Task failed: {result['error']}")

Downloading the audio

Audio URLs point to MP3 files hosted on Suno’s CDN. You can download them directly:
import urllib.request

clip = clips[0]
filename = f"{clip['title']}.mp3"
urllib.request.urlretrieve(clip["audio_url"], filename)
print(f"Downloaded: {filename}")

Full example

Putting it all together:
import requests
import time

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://sunor.cc/api/v1"

# 1. Create task
print("Creating music task...")
response = requests.post(
    f"{BASE_URL}/task",
    headers={
        "Content-Type": "application/json",
        "x-api-key": API_KEY,
    },
    json={
        "model": "suno",
        "task_type": "music",
        "input": {
            "gpt_description_prompt": "A chill lo-fi beat for studying",
            "make_instrumental": True,
        },
    },
)
task_id = response.json()["data"]["task_id"]
print(f"Task ID: {task_id}")

# 2. Poll for results
print("Waiting for completion...")
while True:
    response = requests.get(
        f"{BASE_URL}/task/{task_id}",
        headers={"x-api-key": API_KEY},
    )
    data = response.json()["data"]

    if data["status"] in ("success", "failure", "timeout"):
        break
    time.sleep(5)

# 3. Use the output
if data["status"] == "success":
    for clip in data["output"]["result"]:
        print(f"  {clip['title']}: {clip['audio_url']}")
else:
    print(f"Failed: {data['error']}")

Next steps

Music generation modes

Learn about inspiration, custom, and continuation modes.

Error handling

Handle errors and implement retries.

Rate limits

Stay within rate limits with smart polling.

API Reference

Full endpoint documentation.