---
title: "Start a music generation"
method: POST
path: "/api/v1/music-generations"
tags: ["Music"]
---

# Start a music generation

`POST /api/v1/music-generations`

## Request

- Base URL: `https://your-deployment.example.com`
- URL: `https://your-deployment.example.com/api/v1/music-generations`
- Auth: one of:
  - HTTP bearer
  - API key in header `x-api-key`

Queues a song and returns `202` with the job. Poll `GET /api/v1/music-generations/{id}` until `state` is `succeeded`, `failed`, `blocked` or `cancelled`. A finished song is saved to your Files with the `generated` tag (if that save fails it is kept outside Files and `output.file_id` is null). On success, `output.availability` says whether it can be downloaded: `ready` means `output.url` is a signed download URL valid for 15 minutes (re-fetch the job for a fresh one); `pending_scan` means the saved file is still being scanned, so keep re-fetching the job (self-hosted installs can stay here for up to ~30 minutes); `unavailable` means the file was blocked or deleted and `output.url` will never be set, so stop polling. Credits for the model's price are reserved up front and settled on completion; a failed or cancelled job is not charged. A `blocked` job is not charged either, unless the provider generated the song before rejecting it and billed it: then the price is charged and `credits.settled` shows it. Send an `Idempotency-Key` header (1-255 printable ASCII characters) to make retries safe: a repeat with the same key and body returns the original job, and the same key with a different body is a 422 `idempotency_key_reused`. Omitted fields take the model defaults from `GET /api/v1/music-models`. Set `organization_id` to bill an organization you belong to, or `null` to bill your personal credits; omitted, the job bills your home organization (or your personal credits if you have none). Keys are scoped to the billed account, so the same key sent for a different `organization_id` starts a new job. An organization-billed API key always bills its own organization (see `organization_id`).

## Request body

- CreateMusicGenerationRequest
  - `model` string, required: A model id from GET /api/v1/music-models.
  - `prompt` string, required: The style, mood and subject of the song.
  - `lyrics` string: Lyrics to sing. Only for models whose `lyrics` is not null, within that model's limits.
  - `instrumental` boolean: true for no vocals. Defaults to false, or to true for an instrumental-only model.
  - `duration_seconds` integer: Whole seconds. Defaults to the model's default; see the model's `duration` for how it is honoured.
  - `organization_id` string, nullable: The organization to bill: one you belong to, or null for your personal credits. Omitted bills your home organization, or your personal credits if you have none. An organization-billed API key always bills its own organization: omit this or set it to the key's organization; any other value, null included, is rejected with a 403 (`errorCode: billing_organization_mismatch`).

## Response `202`

Accepted; the job is queued (or replayed for a repeated Idempotency-Key).

- CreateMusicGenerationResponse202
  - `id` string, required
  - `object` 'music_generation', required
  - `state` 'pending' | 'running' | 'storing' | 'succeeded' | 'failed' | 'blocked' | 'cancelled', required
  - `model` string, required
  - `prompt` string, required
  - `lyrics` string, nullable, required: The lyrics you sent, or null.
  - `instrumental` boolean, required
  - `duration_seconds` number, required: The length requested (the model default when omitted).
  - `source` 'api' | 'studio' | 'agent', required
  - `error` object, nullable, required
    - `code` 'content_blocked' | 'provider_timeout' | 'provider_error' | 'region_unavailable' | 'output_too_large' | 'cancelled', required
    - `message` string, required
  - `output` object, nullable, required
    - `availability` 'ready' | 'pending_scan' | 'unavailable', required: `ready`: url is set. `pending_scan`: the saved file is still being scanned; re-fetch the job until it changes (self-hosted installs can stay here for up to ~30 minutes). `unavailable`: the file was blocked by the scan or deleted and url will never be set; stop polling.
    - `url` string, nullable, required: Signed download URL, valid until expires_at; re-fetch the job for a fresh one. Set only when availability is `ready`, otherwise null.
    - `expires_at` string, nullable, required: ISO 8601. When url stops working; null whenever url is.
    - `content_type` string, required
    - `duration_seconds` number, required: The length of the song produced, which can differ from the request.
    - `lyrics` string, nullable, required: What the model sang, as plain lines; null for instrumental output or when the provider does not report it.
    - `file_id` string, nullable, required: The Files entry, or null when the song was stored outside Files.
  - `credits` object, required
    - `reserved` number, nullable, required
    - `settled` number, nullable, required
  - `created_at` string, required
  - `updated_at` string, required

## Other responses

- `400`: Your Files storage has no room for the song (`storage_limit_exceeded`, as on the Files upload routes). The body carries `used_bytes`, `limit_bytes`, `requested_bytes` and `owner`, always together; `requested_bytes` here is the most the song can take at the requested length, not its final size. This endpoint checks only the user quota, so `org_storage_limit_exceeded` is never returned here. An organization-billed API key bills an organization that no longer exists, or one its owner is no longer a member of; re-mint the key.
- `401`: Missing or invalid credentials.
- `403`: The API key lacks the `ai:generate` scope, or the billing organization names one you do not belong to (or is not a valid id), or an organization-billed API key names any organization but its own (`errorCode: billing_organization_mismatch`).
- `404`: A nonexistent `organization_id`, for an admin caller; for anyone else it is `403`.
- `405`: The path does not serve this HTTP method.
- `422`: The request cannot run: a malformed body, a capability violation (`errorCode` names it, e.g. `unsupported_duration` or `lyrics_too_long`), an unknown or unavailable model (`model_unavailable`), a model your administrator disabled (`model_disabled`), too few credits (`insufficient_credits`), or an Idempotency-Key problem (`invalid_idempotency_key`, `idempotency_key_reused`).
- `429`: Per-user rate limit exceeded.

---

[API](https://skmtc.dev/bike4mind/apis/bike4mind-api.md) · [All operations](https://skmtc.dev/bike4mind/apis/bike4mind-api/llms.txt) · [OpenAPI document](https://skmtc.dev/bike4mind/apis/bike4mind-api/revisions/d437aaac22ac?raw)
