@runapi.ai/suno 0.2.1 → 0.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +178 -41
- package/dist/index.d.ts +178 -41
- package/dist/index.js +128 -14
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +114 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -20
- package/skills/suno/README.md +36 -6
- package/skills/suno/SKILL.md +63 -211
package/skills/suno/README.md
CHANGED
|
@@ -1,6 +1,27 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<a href="https://github.com/runapi-ai/suno">
|
|
3
|
+
<h3 align="center">Suno AI API Skill for RunAPI</h3>
|
|
4
|
+
</a>
|
|
5
|
+
</p>
|
|
2
6
|
|
|
3
|
-
|
|
7
|
+
<p align="center">
|
|
8
|
+
Install this agent skill, inspect Suno fields, then run jobs through the RunAPI CLI.
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
<p align="center">
|
|
12
|
+
<a href="https://runapi.ai/models/suno"><strong>Model Reference</strong></a> · <a href="https://github.com/runapi-ai/cli"><strong>CLI</strong></a> · <a href="https://github.com/runapi-ai/suno-sdk"><strong>SDK</strong></a>
|
|
13
|
+
</p>
|
|
14
|
+
|
|
15
|
+
<div align="center">
|
|
16
|
+
|
|
17
|
+
[](https://www.skills.sh/runapi-ai/suno/suno)
|
|
18
|
+
[](https://clawhub.ai/runapi-ai/runapi-suno)
|
|
19
|
+
[](https://github.com/runapi-ai/suno/blob/main/LICENSE)
|
|
20
|
+
|
|
21
|
+
</div>
|
|
22
|
+
<br/>
|
|
23
|
+
|
|
24
|
+
Generate music, lyrics, stems, covers, music videos, voice validation phrases, and reusable custom voices with the Suno SDK. This skill helps Claude Code, Codex, Gemini CLI, Cursor, and 50+ agents integrate Suno through RunAPI.
|
|
4
25
|
|
|
5
26
|
The canonical agent file is `skills/suno/SKILL.md`.
|
|
6
27
|
|
|
@@ -10,7 +31,18 @@ The canonical agent file is `skills/suno/SKILL.md`.
|
|
|
10
31
|
npx skills add runapi-ai/suno -g
|
|
11
32
|
```
|
|
12
33
|
|
|
13
|
-
Or
|
|
34
|
+
Or paste this prompt to your AI agent:
|
|
35
|
+
|
|
36
|
+
```text
|
|
37
|
+
Install the suno skill for me:
|
|
38
|
+
|
|
39
|
+
1. Clone https://github.com/runapi-ai/suno
|
|
40
|
+
2. Copy the skills/suno/ directory into your
|
|
41
|
+
user-level skills directory (e.g. ~/.claude/skills/
|
|
42
|
+
for Claude Code, ~/.codex/skills/ for Codex).
|
|
43
|
+
3. Verify that SKILL.md is present.
|
|
44
|
+
4. Confirm the install path when done.
|
|
45
|
+
```
|
|
14
46
|
|
|
15
47
|
## Quick example
|
|
16
48
|
|
|
@@ -19,10 +51,8 @@ import { SunoClient } from '@runapi.ai/suno';
|
|
|
19
51
|
|
|
20
52
|
const client = new SunoClient();
|
|
21
53
|
const result = await client.textToMusic.run({
|
|
22
|
-
custom_mode: false,
|
|
23
|
-
instrumental: false,
|
|
24
54
|
prompt: 'A chill lo-fi beat with soft vocals',
|
|
25
|
-
model: '
|
|
55
|
+
model: 'suno-v5',
|
|
26
56
|
});
|
|
27
57
|
const audioUrl = result.audios[0].audio_url;
|
|
28
58
|
```
|
package/skills/suno/SKILL.md
CHANGED
|
@@ -1,238 +1,90 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: suno
|
|
3
|
-
description: Generate music
|
|
4
|
-
documentation: https://runapi.ai/models/suno
|
|
5
|
-
provider_page: https://runapi.ai/providers/suno
|
|
6
|
-
catalog: https://runapi.ai/models
|
|
3
|
+
description: Generate and transform music with Suno through RunAPI. Use when the user asks an agent to create, extend, transform music/audio, prepare voice validation phrases, or create reusable custom voices with Suno. Default to the RunAPI CLI for one-off generation; use SDKs only when the user is integrating RunAPI into an app or backend.
|
|
4
|
+
documentation: https://runapi.ai/models/suno.md
|
|
5
|
+
provider_page: https://runapi.ai/providers/suno.md
|
|
6
|
+
catalog: https://runapi.ai/models.md
|
|
7
|
+
metadata:
|
|
8
|
+
openclaw:
|
|
9
|
+
homepage: https://runapi.ai/models/suno
|
|
10
|
+
requires:
|
|
11
|
+
bins:
|
|
12
|
+
- runapi
|
|
13
|
+
install:
|
|
14
|
+
- kind: brew
|
|
15
|
+
formula: runapi-ai/tap/runapi
|
|
16
|
+
bins:
|
|
17
|
+
- runapi
|
|
18
|
+
envVars:
|
|
19
|
+
- name: RUNAPI_API_KEY
|
|
20
|
+
required: false
|
|
21
|
+
description: Optional RunAPI API key; agents should prefer environment auth or saved CLI config. Browser login is interactive fallback only.
|
|
7
22
|
---
|
|
8
23
|
|
|
9
|
-
#
|
|
24
|
+
# Suno on RunAPI
|
|
10
25
|
|
|
11
|
-
|
|
26
|
+
Generate and transform music with Suno through RunAPI, including voice validation phrase and custom voice workflows. The default path for one-off agent tasks is the `runapi` CLI; SDKs are for application integration.
|
|
12
27
|
|
|
13
|
-
##
|
|
28
|
+
## Routing decision
|
|
14
29
|
|
|
15
|
-
|
|
30
|
+
- One-off generation, editing, or transformation for the user → use the **CLI path** with the `runapi` binary.
|
|
31
|
+
- Building an app, backend, worker, library, or production codebase → use the **SDK integration path**.
|
|
16
32
|
|
|
17
|
-
|
|
18
|
-
npm install @runapi.ai/suno
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
Set your API key in the environment:
|
|
33
|
+
## CLI path
|
|
22
34
|
|
|
23
|
-
|
|
24
|
-
# .env
|
|
25
|
-
RUNAPI_API_KEY=runapi_xxx # get one at https://runapi.ai/settings/api_keys
|
|
26
|
-
```
|
|
35
|
+
The `runapi` binary is the runtime dependency. Run `runapi auth status` first. For agents and headless runs, prefer `RUNAPI_API_KEY` or import it into saved config with `printf '%s' "$RUNAPI_API_KEY" | runapi auth import-token --token -`. Use `runapi login` only when the user explicitly wants interactive browser auth.
|
|
27
36
|
|
|
28
|
-
|
|
29
|
-
import { SunoClient } from '@runapi.ai/suno';
|
|
37
|
+
Inspect the available commands and request fields with CLI help:
|
|
30
38
|
|
|
31
|
-
|
|
32
|
-
|
|
39
|
+
```shell
|
|
40
|
+
runapi suno --help
|
|
41
|
+
runapi suno text-to-music --help
|
|
42
|
+
runapi suno voice-to-validation-phrase --help
|
|
43
|
+
runapi suno regenerate-validation-phrase --help
|
|
44
|
+
runapi suno generate-voice --help
|
|
45
|
+
runapi suno check-voice --help
|
|
33
46
|
```
|
|
34
47
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
## Core recipe — music generation
|
|
38
|
-
|
|
39
|
-
Two modes share one endpoint. Use `custom_mode: false` for quick results; `custom_mode: true` when you want control over style, title, and persona.
|
|
48
|
+
Run a one-off task (synchronous — polls until the task completes):
|
|
40
49
|
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
prompt: 'A chill lo-fi beat with soft vocals',
|
|
47
|
-
model: 'V5',
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
const audioUrl = result.audios[0].audio_url;
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
```ts
|
|
54
|
-
// Custom mode — style, title, and prompt are all required.
|
|
55
|
-
await client.textToMusic.run({
|
|
56
|
-
custom_mode: true,
|
|
57
|
-
instrumental: false,
|
|
58
|
-
style: 'Jazz, Bossa Nova',
|
|
59
|
-
title: 'Midnight Blues',
|
|
60
|
-
prompt: 'Soft vocals over a walking bassline...',
|
|
61
|
-
model: 'V5',
|
|
62
|
-
});
|
|
50
|
+
```shell
|
|
51
|
+
runapi suno text-to-music --input-file request.json
|
|
52
|
+
runapi suno voice-to-validation-phrase --input-file voice-phrase.json
|
|
53
|
+
runapi suno generate-voice --input-file generate-voice.json
|
|
54
|
+
runapi suno check-voice --input-file check-voice.json
|
|
63
55
|
```
|
|
64
56
|
|
|
65
|
-
|
|
57
|
+
Submit asynchronously and poll separately:
|
|
66
58
|
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
const status = await client.textToMusic.get(id);
|
|
71
|
-
if (status.status === 'completed') { /* ... */ }
|
|
59
|
+
```shell
|
|
60
|
+
runapi suno text-to-music --async --input-file request.json
|
|
61
|
+
runapi wait <task-id> --service suno --action text-to-music
|
|
72
62
|
```
|
|
73
63
|
|
|
74
|
-
`
|
|
75
|
-
|
|
76
|
-
```ts
|
|
77
|
-
await client.textToMusic.run(params, { maxWaitMs: 30 * 60_000, pollIntervalMs: 5_000 });
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
If `TaskTimeoutError` fires, the task is still running server-side — resume with `textToMusic.get(id)` or finish via webhook.
|
|
81
|
-
|
|
82
|
-
## Other resources
|
|
83
|
-
|
|
84
|
-
`SunoClient` exposes these resources; each has the same `create / get / run` shape:
|
|
85
|
-
|
|
86
|
-
| Resource | Purpose |
|
|
87
|
-
|---|---|
|
|
88
|
-
| `textToMusic` | Core text-to-music |
|
|
89
|
-
| `extendMusic` | Extend an existing generated track |
|
|
90
|
-
| `extendMusic` | Extend an uploaded audio file |
|
|
91
|
-
| `generateArtwork` | Generate cover images for an existing track |
|
|
92
|
-
| `coverAudio` | Restyle an uploaded track |
|
|
93
|
-
| `addInstrumental` | Add instrumental backing to a vocal upload (V4_5PLUS / V5) |
|
|
94
|
-
| `addVocals` | Add vocals to an instrumental upload (V4_5PLUS / V5) |
|
|
95
|
-
| `separateAudioStems` | Split vocals from instrumentals (or up to 12 stems) |
|
|
96
|
-
| `generateMidi` | Extract MIDI from a completed `split_stem` audio stem separation |
|
|
97
|
-
| `convertAudio` | Convert a generated audio to WAV |
|
|
98
|
-
| `visualizeMusic` | Render a music video for a generated audio |
|
|
99
|
-
| `generateLyrics` / `getTimestampedLyrics` | Generate lyrics / word-level timing |
|
|
100
|
-
| `replaceSection` | Regenerate a time range of an existing track |
|
|
101
|
-
| `createMashup` | Blend two uploaded tracks |
|
|
102
|
-
| `generatePersona` / `boostStyle` | Create reusable vocal personas / style descriptors |
|
|
103
|
-
|
|
104
|
-
### Upload-and-cover — restyle an external track
|
|
105
|
-
|
|
106
|
-
```ts
|
|
107
|
-
const restyled = await client.coverAudio.run({
|
|
108
|
-
upload_url: 'https://cdn.example.com/song.mp3',
|
|
109
|
-
custom_mode: false,
|
|
110
|
-
instrumental: false,
|
|
111
|
-
prompt: 'Transform into a jazz cover',
|
|
112
|
-
model: 'V4_5PLUS',
|
|
113
|
-
});
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
### Extension — continue a generated track
|
|
117
|
-
|
|
118
|
-
```ts
|
|
119
|
-
const base = await client.textToMusic.run({ custom_mode: false, instrumental: false, prompt: '...', model: 'V5' });
|
|
120
|
-
await client.extendMusic.run({
|
|
121
|
-
audio_id: base.audios[0].id,
|
|
122
|
-
default_param_flag: false,
|
|
123
|
-
model: 'V5',
|
|
124
|
-
prompt: 'Continue with an uplifting chorus',
|
|
125
|
-
});
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
### Vocal removal — separate stems
|
|
129
|
-
|
|
130
|
-
```ts
|
|
131
|
-
const gen = await client.textToMusic.run({ custom_mode: false, instrumental: false, prompt: '...', model: 'V5' });
|
|
132
|
-
const sep = await client.separateAudioStems.run({
|
|
133
|
-
task_id: gen.id,
|
|
134
|
-
audio_id: gen.audios[0].id,
|
|
135
|
-
type: 'split_stem', // or 'separate_vocal' for just vocals + instrumental
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
console.log(sep.separated_audios.vocal_url);
|
|
139
|
-
```
|
|
64
|
+
Available commands: `text-to-music`, `extend-music`, `generate-artwork`, `cover-audio`, `add-instrumental`, `add-vocals`, `separate-audio-stems`, `generate-midi`, `convert-audio`, `visualize-music`, `generate-lyrics`, `get-timestamped-lyrics`, `replace-section`, `create-mashup`, `text-to-sound`, `voice-to-validation-phrase`, `regenerate-validation-phrase`, `generate-voice`, `check-voice`, `generate-persona`, `boost-style`.
|
|
140
65
|
|
|
141
|
-
|
|
66
|
+
For custom voice workflows: generate or regenerate a validation phrase, create a custom voice with `generate-voice`, then use the completed `voice_id` as `persona_id` with `persona_type: "voice"` on supported Suno v5 music generation endpoints. Use `check-voice` to confirm availability before depending on that voice in a generation request.
|
|
142
67
|
|
|
143
|
-
|
|
144
|
-
|---|---|
|
|
145
|
-
| `V5` | Latest model; best musical expression. |
|
|
146
|
-
| `V4_5PLUS` | Rich sound, max 8 min. |
|
|
147
|
-
| `V4_5ALL` | All features, max 8 min (audio upload max 1 min). |
|
|
148
|
-
| `V4_5` | Balanced quality and speed. |
|
|
149
|
-
| `V4` | Stable, max 4 min. |
|
|
150
|
-
| `V3_5` | Legacy. |
|
|
68
|
+
## SDK integration path
|
|
151
69
|
|
|
152
|
-
|
|
70
|
+
When integrating Suno into an app, backend, worker, or library — not for one-off tasks — use a RunAPI SDK package:
|
|
153
71
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
```ts
|
|
159
|
-
await client.textToMusic.create({
|
|
160
|
-
custom_mode: false,
|
|
161
|
-
instrumental: false,
|
|
162
|
-
prompt: '...',
|
|
163
|
-
model: 'V5',
|
|
164
|
-
callback_url: 'https://your.app/webhooks/runapi/suno',
|
|
165
|
-
});
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
Suno fires the callback at multiple stages — `generation_stage` tells you which:
|
|
169
|
-
|
|
170
|
-
```ts
|
|
171
|
-
{
|
|
172
|
-
id: string;
|
|
173
|
-
status: 'processing' | 'completed' | 'failed';
|
|
174
|
-
generation_stage: 'text_generated' | 'first_audio_ready' | 'all_audios_ready' | 'failed';
|
|
175
|
-
audios?: Audio[];
|
|
176
|
-
error?: string;
|
|
177
|
-
}
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
Treat `all_audios_ready` as the terminal success stage. **Always verify the signature before trusting the body.** RunAPI signs every callback with your account's Callback Secret (rotate at `/accounts/callback_secret`). Headers:
|
|
181
|
-
|
|
182
|
-
- `X-Callback-Id` — UUID, store to make handler idempotent
|
|
183
|
-
- `X-Callback-Timestamp` — unix seconds, reject if `|now - ts| > 300`
|
|
184
|
-
- `X-Callback-Signature` — base64 HMAC-SHA256 over `` `${id}.${ts}.${rawBody}` `` using the base64-decoded secret
|
|
185
|
-
|
|
186
|
-
```ts
|
|
187
|
-
import crypto from 'node:crypto';
|
|
188
|
-
|
|
189
|
-
function verify(raw: string, id: string, ts: string, sig: string, secret: string) {
|
|
190
|
-
const key = Buffer.from(secret, 'base64');
|
|
191
|
-
const mac = crypto.createHmac('sha256', key)
|
|
192
|
-
.update(`${id}.${ts}.${raw}`)
|
|
193
|
-
.digest('base64');
|
|
194
|
-
return crypto.timingSafeEqual(Buffer.from(mac), Buffer.from(sig));
|
|
195
|
-
}
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
Reply `2xx` within 10s; any non-2xx triggers retries.
|
|
199
|
-
|
|
200
|
-
## Errors
|
|
201
|
-
|
|
202
|
-
All errors are re-exported from `@runapi.ai/core`. Always `instanceof` — never string-match messages.
|
|
203
|
-
|
|
204
|
-
| Error | Status | Action |
|
|
205
|
-
|---|---|---|
|
|
206
|
-
| `AuthenticationError` | 401 | abort; surface "reconnect your API key" |
|
|
207
|
-
| `InsufficientCreditsError` | 402 | prompt user to top up at runapi.ai/billing |
|
|
208
|
-
| `ValidationError` | 400 / 422 | fix params; do not retry |
|
|
209
|
-
| `RateLimitError` | 429 | sleep `err.retryAfterMs`, then retry |
|
|
210
|
-
| `ServiceUnavailableError` | 503 / 455 | retry with backoff; transient service issue |
|
|
211
|
-
| `TaskFailedError` | — | show `err.details` to user; do not auto-retry |
|
|
212
|
-
| `TaskTimeoutError` | — | re-poll with `<resource>.get(id)` |
|
|
213
|
-
|
|
214
|
-
```ts
|
|
215
|
-
import { InsufficientCreditsError, TaskFailedError } from '@runapi.ai/suno';
|
|
216
|
-
|
|
217
|
-
try {
|
|
218
|
-
await client.textToMusic.run({ custom_mode: false, instrumental: false, prompt: '...', model: 'V5' });
|
|
219
|
-
} catch (err) {
|
|
220
|
-
if (err instanceof InsufficientCreditsError) { /* surface top-up CTA */ }
|
|
221
|
-
else if (err instanceof TaskFailedError) { /* show err.details */ }
|
|
222
|
-
else throw err;
|
|
223
|
-
}
|
|
224
|
-
```
|
|
72
|
+
- JavaScript / TypeScript: `@runapi.ai/suno`
|
|
73
|
+
- Ruby: `runapi-suno`
|
|
74
|
+
- Go: `github.com/runapi-ai/suno-sdk/go`
|
|
225
75
|
|
|
226
|
-
##
|
|
76
|
+
## References
|
|
227
77
|
|
|
228
|
-
-
|
|
229
|
-
-
|
|
230
|
-
-
|
|
231
|
-
- `generateMidi.run()` requires a completed `separateAudioStems` task created with `type: 'split_stem'` — `separate_vocal` does not produce MIDI.
|
|
232
|
-
- `replaceSection` replacement duration should not exceed 50% of the total track.
|
|
233
|
-
- Callbacks fire multiple times; the `all_audios_ready` stage is the final one. Handle every stage idempotently using `X-Callback-Id`.
|
|
234
|
-
- `callback_url` must be reachable from the public internet. `localhost` / `127.0.0.1` URLs will never fire — use a tunnel (cloudflared, ngrok, tailscale funnel) when developing locally.
|
|
78
|
+
- Model overview, pricing, and rate limits: https://runapi.ai/models/suno.md
|
|
79
|
+
- Provider comparison: https://runapi.ai/providers/suno.md
|
|
80
|
+
- Full model catalog: https://runapi.ai/models.md
|
|
235
81
|
|
|
236
|
-
##
|
|
82
|
+
## Variants
|
|
237
83
|
|
|
238
|
-
|
|
84
|
+
- [v3.5](https://runapi.ai/models/suno/v3.5.md)
|
|
85
|
+
- [v4](https://runapi.ai/models/suno/v4.md)
|
|
86
|
+
- [v4.5](https://runapi.ai/models/suno/v4.5.md)
|
|
87
|
+
- [v4.5 all](https://runapi.ai/models/suno/v4.5-all.md)
|
|
88
|
+
- [v4.5 plus](https://runapi.ai/models/suno/v4.5-plus.md)
|
|
89
|
+
- [v5](https://runapi.ai/models/suno/v5.md)
|
|
90
|
+
- [v5.5](https://runapi.ai/models/suno/v5.5.md)
|