ace-music
Generate AI music using ACE-Step 1.5 via ACE Music's free API. Use when the user asks to create, generate, or compose music, songs, beats, instrumentals, or audio tracks. Supports lyrics, style prompts, covers, and repainting. Free API, no cost.
Packaged view
This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.
Install command
npx @skill-hub/cli install openclaw-skills-ace-music
Repository
Skill path: skills/fspecii/ace-music
Generate AI music using ACE-Step 1.5 via ACE Music's free API. Use when the user asks to create, generate, or compose music, songs, beats, instrumentals, or audio tracks. Supports lyrics, style prompts, covers, and repainting. Free API, no cost.
Open repositoryBest for
Primary workflow: Analyze Data & AI.
Technical facets: Full Stack, Backend, Data / AI.
Target audience: everyone.
License: Unknown.
Original source
Catalog source: SkillHub Club.
Repository owner: openclaw.
This is still a mirrored public skill entry. Review the repository before installing into production workflows.
What it helps with
- Install ace-music into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
- Review https://github.com/openclaw/skills before adding ace-music to shared team environments
- Use ace-music for development workflows
Works across
Favorites: 0.
Sub-skills: 0.
Aggregator: No.
Original source / Raw SKILL.md
---
name: ace-music
description: Generate AI music using ACE-Step 1.5 via ACE Music's free API. Use when the user asks to create, generate, or compose music, songs, beats, instrumentals, or audio tracks. Supports lyrics, style prompts, covers, and repainting. Free API, no cost.
---
# ACE Music - AI Music Generation
Generate music via ACE Music's free hosted API (ACE-Step 1.5 model).
## Setup
**API Key** is stored in env `ACE_MUSIC_API_KEY`. If not set:
1. Open https://acemusic.ai/playground/api-key in the browser for the user
2. Ask them to sign up (free) and paste the API key
3. Store it: `export ACE_MUSIC_API_KEY=<key>` or add to TOOLS.md
## Quick Generation
Use `scripts/generate.sh` for one-shot generation:
```bash
# Simple prompt (AI decides everything)
scripts/generate.sh "upbeat pop song about summer" --duration 30 --output summer.mp3
# With lyrics
scripts/generate.sh "gentle acoustic ballad, female vocal" \
--lyrics "[Verse 1]\nSunlight through the window\n\n[Chorus]\nWe are the dreamers" \
--duration 60 --output ballad.mp3
# Instrumental only
scripts/generate.sh "lo-fi hip hop beats, chill, rainy day" --instrumental --duration 120 --output lofi.mp3
# Natural language (AI writes everything)
scripts/generate.sh "write me a jazz song about coffee" --sample-mode --output jazz.mp3
# Specific settings
scripts/generate.sh "rock anthem" --bpm 140 --key "E minor" --language en --seed 42 --output rock.mp3
# Multiple variations
scripts/generate.sh "electronic dance track" --batch 3 --output edm.mp3
```
Script outputs file path(s) to stdout. Send the file to the user.
## Advanced Usage (curl/direct API)
For covers, repainting, or audio input β see `references/api-docs.md` for full API spec.
Key task types:
- `text2music` (default) β generate from text/lyrics
- `cover` β cover an existing song (requires audio input)
- `repaint` β modify a section of existing audio
## Parameters Guide
| Want | Use |
|------|-----|
| Specific style | Describe in prompt: "jazz, saxophone solo, smoky bar" |
| Custom lyrics | `--lyrics "[Verse]...[Chorus]..."` |
| AI writes everything | `--sample-mode` |
| No vocals | `--instrumental` |
| Longer songs | `--duration 120` (seconds) |
| Specific tempo | `--bpm 120` |
| Specific key | `--key "C major"` |
| Multiple outputs | `--batch 3` |
| Reproducible | `--seed 42` |
| Non-English vocals | `--language ja` (zh, en, ja, ko, etc.) |
## Notes
- API is **free forever** (confirmed by ACE Music team)
- Base URL: `https://api.acemusic.ai`
- Audio returned as base64 MP3, decoded automatically by the script
- Duration: if omitted, AI decides based on content
- For best results, use tagged mode (prompt + lyrics separated)
---
## Referenced Files
> The following files are referenced in this skill and included for context.
### scripts/generate.sh
```bash
#!/usr/bin/env bash
# ACE-Step Music Generation via API
# Usage: generate.sh <prompt> [options]
# Options: --lyrics "..." --duration 30 --language en --instrumental --output file.mp3
# --bpm 120 --key "C major" --seed 42 --sample-mode --batch 2
set -euo pipefail
# Config
API_KEY="${ACE_MUSIC_API_KEY:-}"
BASE_URL="${ACE_MUSIC_BASE_URL:-https://api.acemusic.ai}"
OUTPUT="output_$(date +%s).mp3"
# Defaults
DURATION=""
LANGUAGE="en"
INSTRUMENTAL="null"
BPM=""
KEY_SCALE=""
SEED=""
SAMPLE_MODE="false"
BATCH_SIZE=1
LYRICS=""
PROMPT=""
FORMAT="mp3"
# Parse args
while [[ $# -gt 0 ]]; do
case "$1" in
--lyrics) LYRICS="$2"; shift 2 ;;
--duration) DURATION="$2"; shift 2 ;;
--language) LANGUAGE="$2"; shift 2 ;;
--instrumental) INSTRUMENTAL="true"; shift ;;
--output|-o) OUTPUT="$2"; shift 2 ;;
--bpm) BPM="$2"; shift 2 ;;
--key) KEY_SCALE="$2"; shift 2 ;;
--seed) SEED="$2"; shift 2 ;;
--sample-mode) SAMPLE_MODE="true"; shift ;;
--batch) BATCH_SIZE="$2"; shift 2 ;;
--format) FORMAT="$2"; shift 2 ;;
*) PROMPT="$1"; shift ;;
esac
done
if [[ -z "$API_KEY" ]]; then
echo "ERROR: ACE_MUSIC_API_KEY not set." >&2
echo "Get your free API key at: https://acemusic.ai/playground/api-key" >&2
exit 1
fi
if [[ -z "$PROMPT" && "$SAMPLE_MODE" == "false" ]]; then
echo "Usage: generate.sh <prompt> [--lyrics '...'] [--duration 30] [--language en] [--instrumental] [--output file.mp3]" >&2
exit 1
fi
# Build audio_config
AUDIO_CONFIG="{\"vocal_language\":\"$LANGUAGE\",\"format\":\"$FORMAT\""
[[ -n "$DURATION" ]] && AUDIO_CONFIG="$AUDIO_CONFIG,\"duration\":$DURATION"
[[ -n "$BPM" ]] && AUDIO_CONFIG="$AUDIO_CONFIG,\"bpm\":$BPM"
[[ "$INSTRUMENTAL" != "null" ]] && AUDIO_CONFIG="$AUDIO_CONFIG,\"instrumental\":$INSTRUMENTAL"
[[ -n "$KEY_SCALE" ]] && AUDIO_CONFIG="$AUDIO_CONFIG,\"key_scale\":\"$KEY_SCALE\""
AUDIO_CONFIG="$AUDIO_CONFIG}"
# Build message content
if [[ -n "$LYRICS" && -n "$PROMPT" ]]; then
# Tagged mode
CONTENT="<prompt>${PROMPT}</prompt>\n<lyrics>${LYRICS}</lyrics>"
elif [[ -n "$LYRICS" ]]; then
CONTENT="$LYRICS"
else
CONTENT="$PROMPT"
fi
# Escape for JSON
CONTENT_ESCAPED=$(echo -n "$CONTENT" | python3 -c "import sys,json; print(json.dumps(sys.stdin.read()))" | sed 's/^"//;s/"$//')
# Build request body
BODY="{\"messages\":[{\"role\":\"user\",\"content\":\"$CONTENT_ESCAPED\"}],\"audio_config\":$AUDIO_CONFIG,\"stream\":false"
[[ -n "$LYRICS" && -n "$PROMPT" ]] || true # tagged mode handled via content
[[ "$SAMPLE_MODE" == "true" ]] && BODY="$BODY,\"sample_mode\":true"
[[ -n "$SEED" ]] && BODY="$BODY,\"seed\":$SEED"
[[ "$BATCH_SIZE" -gt 1 ]] && BODY="$BODY,\"batch_size\":$BATCH_SIZE"
BODY="$BODY}"
echo "π΅ Generating music..." >&2
echo " Prompt: ${PROMPT:-[lyrics/sample mode]}" >&2
[[ -n "$DURATION" ]] && echo " Duration: ${DURATION}s" >&2
echo " Language: $LANGUAGE" >&2
# API call
RESPONSE=$(curl -s -X POST "${BASE_URL}/v1/chat/completions" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d "$BODY")
# Check for errors
if echo "$RESPONSE" | python3 -c "import sys,json; d=json.load(sys.stdin); exit(0 if 'choices' in d else 1)" 2>/dev/null; then
# Extract metadata
METADATA=$(echo "$RESPONSE" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['choices'][0]['message'].get('content',''))" 2>/dev/null || echo "")
# Extract and save audio(s)
COUNT=$(echo "$RESPONSE" | python3 -c "
import sys,json
d=json.load(sys.stdin)
audios=d['choices'][0]['message'].get('audio',[])
print(len(audios))
" 2>/dev/null || echo "0")
if [[ "$COUNT" -eq 0 ]]; then
echo "ERROR: No audio in response" >&2
echo "$RESPONSE" >&2
exit 1
fi
echo "$RESPONSE" | python3 -c "
import sys, json, base64
d = json.load(sys.stdin)
audios = d['choices'][0]['message'].get('audio', [])
output = '$OUTPUT'
for i, a in enumerate(audios):
url = a['audio_url']['url']
b64 = url.split(',', 1)[1]
fname = output if len(audios) == 1 else output.rsplit('.', 1)[0] + f'_{i+1}.' + output.rsplit('.', 1)[1]
with open(fname, 'wb') as f:
f.write(base64.b64decode(b64))
print(f'Saved: {fname}', file=sys.stderr)
print(fname)
"
if [[ -n "$METADATA" ]]; then
echo "" >&2
echo "π Metadata:" >&2
echo "$METADATA" >&2
fi
else
echo "ERROR: API request failed" >&2
echo "$RESPONSE" >&2
exit 1
fi
```
### references/api-docs.md
```markdown
# ACE-Step OpenRouter API Reference
**Base URL:** `https://api.acemusic.ai`
**Auth:** `Authorization: Bearer <api-key>`
**Get API Key:** https://acemusic.ai/playground/api-key
## Generate Music
**POST** `/v1/chat/completions`
### Request Parameters
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| `model` | string | No | auto | Model ID |
| `messages` | array | **Yes** | - | Chat message list |
| `stream` | boolean | No | false | Enable streaming |
| `audio_config` | object | No | null | Audio config (see below) |
| `temperature` | float | No | 0.85 | LM sampling temperature |
| `top_p` | float | No | 0.9 | Nucleus sampling |
| `seed` | int/string | No | null | Random seed |
| `lyrics` | string | No | "" | Lyrics (takes priority over messages) |
| `sample_mode` | boolean | No | false | LLM auto-generates prompt/lyrics |
| `thinking` | boolean | No | false | LLM thinking mode |
| `use_format` | boolean | No | false | Enhance prompt/lyrics via LLM |
| `use_cot_caption` | boolean | No | true | Rewrite music description via CoT |
| `use_cot_language` | boolean | No | true | Auto-detect language via CoT |
| `guidance_scale` | float | No | 7.0 | Classifier-free guidance |
| `batch_size` | int | No | 1 | Number of samples |
| `task_type` | string | No | "text2music" | Task: text2music, cover, repaint |
| `repainting_start` | float | No | 0.0 | Repaint start (seconds) |
| `repainting_end` | float | No | null | Repaint end (seconds) |
| `audio_cover_strength` | float | No | 1.0 | Cover strength (0.0-1.0) |
### audio_config Object
| Field | Type | Default | Description |
|---|---|---|---|
| `duration` | float | null | Duration in seconds |
| `bpm` | integer | null | Beats per minute |
| `vocal_language` | string | "en" | Language code (en, zh, ja, etc.) |
| `instrumental` | boolean | null | Instrumental only (no vocals) |
| `format` | string | "mp3" | Output format |
| `key_scale` | string | null | Musical key (e.g. "C major") |
| `time_signature` | string | null | Time signature (e.g. "4/4") |
## Input Modes
### Mode 1: Tagged (Recommended)
```json
{
"messages": [{"role": "user", "content": "<prompt>A gentle acoustic ballad, female vocal</prompt>\n<lyrics>[Verse 1]\nSunlight through the window\n\n[Chorus]\nWe are the dreamers</lyrics>"}],
"audio_config": {"duration": 30, "vocal_language": "en"}
}
```
### Mode 2: Natural Language (sample_mode)
```json
{
"messages": [{"role": "user", "content": "Generate an upbeat pop song about summer"}],
"sample_mode": true,
"audio_config": {"vocal_language": "en"}
}
```
### Mode 3: Lyrics Only
```json
{
"messages": [{"role": "user", "content": "[Verse 1]\nWalking down the street\n\n[Chorus]\nDance with me tonight"}],
"audio_config": {"duration": 30}
}
```
### Mode 4: Separate lyrics + prompt
Use `lyrics` field for lyrics, `messages` text becomes the prompt.
## Audio Input (for covers/repainting)
Multimodal messages with base64 audio:
```json
{
"messages": [{"role": "user", "content": [
{"type": "text", "text": "Cover this song in jazz style"},
{"type": "input_audio", "input_audio": {"data": "<base64>", "format": "mp3"}}
]}],
"task_type": "cover"
}
```
## Response
Audio is returned as base64 data URL in `choices[0].message.audio[0].audio_url.url`:
- Format: `data:audio/mpeg;base64,<base64_data>`
- Metadata in `choices[0].message.content` (caption, BPM, duration, key, lyrics)
## List Models
**GET** `/v1/models` β returns available models
## Health Check
**GET** `/health` β returns `{"status": "ok"}`
```
---
## Skill Companion Files
> Additional files collected from the skill directory layout.
### _meta.json
```json
{
"owner": "fspecii",
"slug": "ace-music",
"displayName": "ACE Music - Free Suno Alternative Generate unlimited AI music for free using ACE-Step 1.5. Full songs with vocals, lyrics, any genre, any language. No subscription, no credits, no limits. The open-source Suno alternative, powered by ACE Music's free API.",
"latest": {
"version": "1.0.0",
"publishedAt": 1771464200986,
"commit": "https://github.com/openclaw/skills/commit/c0a510771e56fb26aa12cecc444ad3d6f5b963a1"
},
"history": []
}
```