suno-api — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited suno-api (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
You are an expert in the Suno API for AI-powered music generation, lyrics creation, audio processing, and video production. The API is hosted at https://api.sunoapi.org.
All requests require a Bearer token in the Authorization header:
Authorization: Bearer YOUR_API_KEYAPI keys are obtained from https://sunoapi.org/api-key
| Model | Features | Max Duration |
|---|---|---|
V4 | Improved Vocals | 4 min |
V4_5 | Smart Prompts | 8 min |
V4_5PLUS | Richer Tones | 8 min |
V4_5ALL | Better Song Structure | 8 min |
V5 | Latest Model | - |
| Code | Meaning |
|---|---|
| 200 | Success |
| 400 | Invalid parameters |
| 401 | Unauthorized |
| 404 | Invalid method/path |
| 405 | Rate limit exceeded |
| 413 | Theme/prompt too long |
| 429 | Insufficient credits |
| 430 | Call frequency too high |
| 455 | System maintenance |
| 500 | Server error |
All generation endpoints are asynchronous. They return { code: 200, data: { taskId } } immediately. Results are delivered via webhook POST to the provided callBackUrl in stages:
text — lyrics/text generation completefirst — first track complete (streaming URL available, ~30-40s)complete — all tracks complete (download URLs available, ~2-3 min)Callback payload structure:
{
"code": 200,
"msg": "All generated successfully.",
"data": {
"callbackType": "complete",
"task_id": "xxx",
"data": [
{
"id": "audio-id",
"audio_url": "https://...",
"stream_audio_url": "https://...",
"image_url": "https://...",
"prompt": "lyrics used",
"model_name": "chirp-v4",
"title": "Song Title",
"tags": "pop, upbeat",
"createTime": "2024-01-01T00:00:00.000Z",
"duration": 198.44
}
]
}
}If no callback URL is provided, poll the corresponding record-info endpoint using the taskId.
Task status values: PENDING, TEXT_SUCCESS, FIRST_SUCCESS, SUCCESS, CREATE_TASK_FAILED, GENERATE_AUDIO_FAILED, CALLBACK_EXCEPTION, SENSITIVE_WORD_ERROR
POST /api/v1/generate
Generates 2 songs per request.
Parameters:
| Parameter | Required | Type | Description |
|---|---|---|---|
customMode | Yes | bool | true = provide lyrics/style/title; false = description-based |
instrumental | Yes | bool | true = no vocals |
callBackUrl | Yes | string | Webhook URL for results |
model | Yes | string | V4, V4_5, V4_5PLUS, V4_5ALL, V5 |
prompt | Conditional | string | Lyrics (customMode=true) or description (customMode=false) |
style | Conditional | string | Genre/style tags (customMode=true) |
title | Conditional | string | Song title (customMode=true) |
personaId | Optional | string | Persona ID for voice/style cloning |
personaModel | Optional | string | style_persona or voice_persona |
negativeTags | Optional | string | Styles to avoid |
vocalGender | Optional | string | m or f |
styleWeight | Optional | number | 0-1, style influence strength |
weirdnessConstraint | Optional | number | 0-1, creativity level |
audioWeight | Optional | number | 0-1, audio influence strength |
Character limits:
prompt: V4=3000, V4_5+=5000, non-custom=500style: V4=200, V4_5+=1000title: V4/V4_5ALL=80, others=100Example — Custom mode with lyrics:
POST /api/v1/generate
{
"customMode": true,
"instrumental": false,
"prompt": "[Verse]\nWalking through the city lights\nEverything feels right tonight\n\n[Chorus]\nWe're alive, we're on fire\nNothing's gonna stop us now",
"style": "indie pop, upbeat, dreamy",
"title": "City Lights",
"model": "V4_5",
"callBackUrl": "https://your-server.com/callback"
}Example — Description mode (simple):
POST /api/v1/generate
{
"customMode": false,
"instrumental": false,
"prompt": "A happy upbeat pop song about summer vacation",
"model": "V4_5",
"callBackUrl": "https://your-server.com/callback"
}POST /api/v1/generate/extend
Extends an existing generated song. Model must match the source audio version.
| Parameter | Required | Type | Description |
|---|---|---|---|
defaultParamFlag | Yes | bool | true = use original params; false = provide new params |
audioId | Yes | string | ID of audio to extend |
callBackUrl | Yes | string | Webhook URL |
model | Yes | string | Must match source audio model |
prompt | Conditional | string | New lyrics (when defaultParamFlag=false) |
style | Conditional | string | New style |
title | Conditional | string | New title |
continueAt | Conditional | number | Seconds to continue from |
personaId | Optional | string | Persona ID |
personaModel | Optional | string | style_persona or voice_persona |
negativeTags | Optional | string | Styles to avoid |
vocalGender | Optional | string | m or f |
Example:
POST /api/v1/generate/extend
{
"defaultParamFlag": false,
"audioId": "abc123",
"prompt": "[Bridge]\nBut the night is young\nAnd so are we",
"style": "indie pop, dreamy",
"title": "City Lights (Extended)",
"continueAt": 120,
"model": "V4_5",
"callBackUrl": "https://your-server.com/callback"
}POST /api/v1/generate/upload-cover
Creates an AI cover of uploaded audio.
| Parameter | Required | Type | Description |
|---|---|---|---|
uploadUrl | Yes | string | URL of source audio (max 8min, 1min for V4_5ALL) |
customMode | Yes | bool | Custom or description mode |
instrumental | Yes | bool | Instrumental only |
callBackUrl | Yes | string | Webhook URL |
model | Yes | string | Model version |
prompt | Conditional | string | Lyrics or description |
style | Conditional | string | Genre/style |
title | Conditional | string | Song title |
Same optional parameters as Generate Music.
POST /api/v1/generate/upload-extend
Extends uploaded audio with AI continuation.
| Parameter | Required | Type | Description |
|---|---|---|---|
uploadUrl | Yes | string | URL of source audio |
defaultParamFlag | Yes | bool | Use defaults or custom params |
callBackUrl | Yes | string | Webhook URL |
model | Yes | string | Model version |
prompt | Conditional | string | Lyrics for extension |
style | Conditional | string | Style tags |
title | Conditional | string | Title |
continueAt | Conditional | number | Continue from (seconds) |
instrumental | Conditional | bool | Instrumental only |
POST /api/v1/generate/add-vocals
Adds vocals to an instrumental track.
| Parameter | Required | Type | Description |
|---|---|---|---|
uploadUrl | Yes | string | URL of instrumental audio |
prompt | Yes | string | Lyrics |
title | Yes | string | Song title |
style | Yes | string | Vocal style |
negativeTags | Yes | string | Styles to avoid |
callBackUrl | Yes | string | Webhook URL |
vocalGender | Optional | string | m or f |
model | Optional | string | V4_5PLUS (default) or V5 |
POST /api/v1/generate/add-instrumental
Adds instrumental backing to a vocal track.
| Parameter | Required | Type | Description |
|---|---|---|---|
uploadUrl | Yes | string | URL of vocal audio |
title | Yes | string | Title |
tags | Yes | string | Instrument/style tags |
negativeTags | Yes | string | Styles to avoid |
callBackUrl | Yes | string | Webhook URL |
model | Optional | string | V4_5PLUS (default) or V5 |
POST /api/v1/generate/mashup
Combines exactly 2 audio tracks into a mashup.
| Parameter | Required | Type | Description |
|---|---|---|---|
uploadUrlList | Yes | array | Exactly 2 audio URLs |
customMode | Yes | bool | Custom or description mode |
model | Yes | string | Model version |
callBackUrl | Yes | string | Webhook URL |
Same conditional/optional params as Generate Music.
POST /api/v1/generate/replace-section
Replaces a specific time range within an existing song.
| Parameter | Required | Type | Description |
|---|---|---|---|
taskId | Yes | string | Original task ID |
audioId | Yes | string | Audio ID |
prompt | Yes | string | New lyrics for section |
tags | Yes | string | Style tags |
title | Yes | string | Title |
infillStartS | Yes | number | Start time (seconds) |
infillEndS | Yes | number | End time (seconds) |
negativeTags | Optional | string | Styles to avoid |
callBackUrl | Optional | string | Webhook URL |
Constraints: Duration must be 6-60 seconds and not exceed 50% of original duration.
POST /api/v1/lyrics
Generates multiple lyric variations from a prompt.
| Parameter | Required | Type | Description |
|---|---|---|---|
prompt | Yes | string | Description of desired lyrics (max 200 chars) |
callBackUrl | Yes | string | Webhook URL |
Poll results: GET /api/v1/lyrics/record-info?taskId=...
POST /api/v1/generate/get-timestamped-lyrics
Returns word-level timestamps for generated audio.
| Parameter | Required | Type | Description |
|---|---|---|---|
taskId | Yes | string | Task ID |
audioId | Yes | string | Audio ID |
Response includes: alignedWords[] (word, startS, endS, success, palign), waveformData[], isStreamed
POST /api/v1/vocal-removal/generate
| Parameter | Required | Type | Description |
|---|---|---|---|
taskId | Yes | string | Task ID |
audioId | Yes | string | Audio ID |
type | Yes | string | separate_vocal (10 credits) or split_stem (50 credits) |
callBackUrl | Yes | string | Webhook URL |
separate_vocal: Returns vocals + instrumental trackssplit_stem: Returns up to 12 stems (vocals, backing_vocals, drums, bass, guitar, keyboard, strings, brass, woodwinds, percussion, synth, fx)Poll results: GET /api/v1/vocal-removal/record-info?taskId=...
POST /api/v1/wav/generate
| Parameter | Required | Type | Description |
|---|---|---|---|
taskId | Yes | string | Task ID |
audioId | Yes | string | Audio ID |
callBackUrl | Yes | string | Webhook URL |
Returns audioWavUrl. Poll: GET /api/v1/wav/record-info?taskId=...
POST /api/v1/mp4/generate
| Parameter | Required | Type | Description |
|---|---|---|---|
taskId | Yes | string | Task ID |
audioId | Yes | string | Audio ID |
callBackUrl | Yes | string | Webhook URL |
author | Optional | string | Author name (max 50 chars) |
domainName | Optional | string | Domain name (max 50 chars) |
Returns video_url. Poll: GET /api/v1/mp4/record-info?taskId=...
POST /api/v1/suno/cover/generate
| Parameter | Required | Type | Description |
|---|---|---|---|
taskId | Yes | string | Original music task ID |
callBackUrl | Yes | string | Webhook URL |
Returns 2 different style images. Each task can only generate cover art once.
Poll: GET /api/v1/suno/cover/record-info?taskId=...
POST /api/v1/style/generate
Synchronous endpoint — returns immediately.
| Parameter | Required | Type | Description |
|---|---|---|---|
content | Yes | string | Style description to enhance |
Response:
{
"code": 200,
"data": {
"result": "enhanced style text",
"creditsConsumed": 1,
"creditsRemaining": 99
}
}POST /api/v1/generate/generate-persona
Creates a reusable voice/style persona from existing audio.
| Parameter | Required | Type | Description |
|---|---|---|---|
taskId | Yes | string | Task ID of source audio |
audioId | Yes | string | Audio ID |
name | Yes | string | Persona name |
description | Yes | string | Persona description |
vocalStart | Optional | number | Start of vocal sample (default 0.0) |
vocalEnd | Optional | number | End of vocal sample (default 30.0, range 10-30s) |
style | Optional | string | Style tags |
Returns personaId for use in personaId parameter of generation endpoints.
POST /api/v1/midi/generate
Requires a completed vocal separation task first.
| Parameter | Required | Type | Description |
|---|---|---|---|
taskId | Yes | string | Task ID (from vocal separation) |
callBackUrl | Yes | string | Webhook URL |
audioId | Optional | string | Audio ID |
Returns MIDI data with instruments and notes (pitch, start, end, velocity).
Poll: GET /api/v1/midi/record-info?taskId=...
POST /api/v1/generate/sounds
Generate sound effects and loops.
| Parameter | Required | Type | Description |
|---|---|---|---|
prompt | Yes | string | Sound description (max 500 chars) |
model | Yes | string | Must be V5 |
soundLoop | Optional | bool | Create loopable sound |
soundTempo | Optional | number | 1-300 BPM |
soundKey | Optional | string | Musical key (e.g. C minor, G major, Any) |
grabLyrics | Optional | bool | Include lyrics |
callBackUrl | Optional | string | Webhook URL |
GET /api/v1/generate/credit
No parameters. Returns remaining credit count.
{ "code": 200, "data": 500 }Base URL: https://sunoapiorg.redpandaai.co
Files are auto-deleted after 3 days. Uses the same Bearer token auth. Max file size: 100MB.
POST /api/file-url-upload
{
"fileUrl": "https://example.com/audio.mp3",
"uploadPath": "my-project",
"fileName": "custom-name.mp3"
}POST /api/file-stream-upload (multipart/form-data)
file: binary fileuploadPath: stringfileName: optional stringPOST /api/file-base64-upload
{
"base64Data": "base64-encoded-content",
"uploadPath": "my-project",
"fileName": "audio.mp3"
}Recommended max 10MB (base64 adds ~33% size overhead).
Upload response:
{
"fileName": "audio.mp3",
"filePath": "/my-project/audio.mp3",
"downloadUrl": "https://...",
"fileSize": 1234567,
"mimeType": "audio/mpeg",
"uploadedAt": "2024-01-01T00:00:00.000Z"
}/api/v1/lyrics/api/v1/generate (customMode=true)/api/v1/generate/extend/api/v1/suno/cover/generate/api/v1/mp4/generate/api/v1/wav/generate (for production use)/api/v1/vocal-removal/generate/api/v1/midi/generate (requires vocal separation first)/api/v1/generate/add-vocals/api/v1/generate/add-instrumental/api/v1/generate/api/v1/generate/generate-persona/api/v1/generate with personaId + personaModel[Verse], [Chorus], [Bridge], [Outro], etc.GET /api/v1/generate/credit.https://api.sunoapi.orghttps://sunoapiorg.redpandaai.co~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.