POST /v1/generations
Create a new music generation
Start generating an AI music track with the specified parameters. Deducts one credit and submits to the generation queue.
Want vocal-free instrumentals without specifying BPM, key, or scale? See POST /v1/instrumental.
Request
POST https://pub.finetuning.ai/v1/generationsHeaders
| Header | Type | Required | Description |
|---|---|---|---|
X-API-Key | string | Yes | Your API key |
Content-Type | string | Yes | application/json |
Body parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
tags | string | Yes | — | Music description (max 700 chars) |
lyrics | string | No | — | Lyrics text (max 2000 chars) |
duration | number | No | 60 | Track duration in seconds (5–210; free tier capped at 120) |
bpm | number | No | 120 | Beats per minute (60–200) |
language | string | No | — | Language code (en, ja, de, fr, es, zh, ko, pt, it, ru) |
key | string | No | auto | Musical key (C, C#, D, ... B) |
scale | string | No | auto | Scale type (major, minor) |
timesignature | string | No | "4" | Time signature (2–7) |
seed | number | No | — | Seed for reproducibility |
webhook | string | No | — | HTTPS URL we'll POST the completed (or failed) track to. Skips polling. Max 2048 chars. Identified by User-Agent: finetuning-webhook/1.0. See the Webhooks guide for payload shape and how to secure your endpoint. |
Example request
curl -X POST https://pub.finetuning.ai/v1/generations \
-H "X-API-Key: ft_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"tags": "lofi chill piano night",
"duration": 120,
"bpm": 85,
"key": "C",
"scale": "minor",
"language": "en",
"timesignature": "4",
"seed": 1234567,
"webhook": "https://your-app.com/finetuning-callback?token=YOUR_SECRET"
}'Response
{
"data": {
"id": "gen_xyz789",
"status": "processing",
"prompt": "lofi chill piano night",
"parameters": {
"bpm": 85,
"duration": 120,
"timesignature": "4",
"language": "en",
"keyscale": "C minor",
"seed": 1234567
},
"webhook": "https://your-app.com/finetuning-callback?token=YOUR_SECRET",
"creditsRemaining": 1952,
"createdAt": "2025-01-15T10:30:00Z"
}
}If webhook was not provided, the field is returned as null.
Response fields
| Field | Type | Description |
|---|---|---|
data.id | string | Unique generation ID |
data.status | string | processing, pending, completed, failed |
data.prompt | string | The tags/prompt used |
data.parameters.bpm | number | BPM of the track |
data.parameters.duration | number | Requested duration in seconds |
data.parameters.timesignature | string | Time signature |
data.parameters.language | string | Language code |
data.parameters.keyscale | string | Combined key and scale (e.g., "C minor") |
data.parameters.seed | number | Seed used for generation |
data.webhook | string | null | Echo of the webhook URL we accepted, or null if not provided |
data.creditsRemaining | number | Credits remaining after this generation |
data.createdAt | string | ISO 8601 timestamp |
Errors
| Code | Status | Description |
|---|---|---|
VALIDATION_ERROR | 400 | Invalid parameters (check message field for details) |
MISSING_API_KEY | 401 | X-API-Key header was not provided |
INVALID_API_KEY | 401 | API key is malformed, revoked, or does not exist |
MONTHLY_LIMIT_REACHED | 402 | No generations remaining this month |
PRO_PLAN_REQUIRED | 403 | Your subscription does not include API access |
RATE_LIMITED | 429 | Too many requests on a read endpoint — wait and retry (60/min/user) |
GENERATION_RATE_LIMITED | 429 | Too many POST /v1/generations calls — wait and retry (10/min/user) |
QUEUE_FULL | 429 | Too many generations in progress |
GENERATION_FAILED | 500 | Generation queue submission failed |