# Generate Music

Source: https://recoupable.dev/docs/api-reference/music/generate

Generate music

## POST /api/music

Full OpenAPI specification: https://recoupable.dev/docs/spec/content.json

## Authentication

This operation requires one of the security alternatives in the specification below. Security scheme definitions are included where present in the published specification.

[Authentication guide](https://recoupable.dev/docs/authentication)

## Operation and referenced schemas

```json
{
  "openapi": "3.1.0",
  "info": {
    "title": "Recoup API - Content",
    "description": "API documentation for the Recoup platform - an AI agent platform for the music industry",
    "license": {
      "name": "MIT"
    },
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "https://api.recoupable.dev"
    }
  ],
  "paths": {
    "/api/music": {
      "post": {
        "summary": "Generate music",
        "description": "Start a song generation with MiniMax Music 3. Generation runs in the background and takes roughly one to two minutes, so this returns **202** immediately with a `pending` generation. Poll [Get Music Generation](/api-reference/music/get) until `status` is `completed` or `failed`; `audio_url` is populated on completion. Credits are checked before the model is called and deducted only when a generation completes, so a failed generation is never charged.",
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MusicGenerationRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Generation accepted and queued.",
            "headers": {
              "Location": {
                "schema": {
                  "type": "string"
                },
                "description": "URL of the created generation."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MusicGenerationCreateResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed. `missing_fields` names the first offending field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MusicGenerationErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized. Provide exactly one of `x-api-key` or `Authorization: Bearer`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MusicGenerationErrorResponse"
                }
              }
            }
          },
          "402": {
            "description": "Insufficient credits. No generation is created and the model is not called.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MusicGenerationErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Access denied to the specified `account_id` or `organization_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MusicGenerationErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MusicGenerationErrorResponse"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "MusicGenerationRequest": {
        "type": "object",
        "required": [
          "prompt",
          "lyrics"
        ],
        "properties": {
          "prompt": {
            "type": "string",
            "description": "Music description: style, mood, vocals, instrumentation and arrangement.",
            "example": "Genre: acoustic pop. BPM: 96. Key: C major. Warm and intimate, building gently into the chorus."
          },
          "lyrics": {
            "type": "string",
            "description": "The lyrics to sing. Structure tags such as `[intro]`, `[verse]`, `[chorus]` and `[outro]` must each be on their own line; text on the same line as a leading tag is dropped by the model.",
            "example": "[verse]\nMorning light filtering through the pine\n[chorus]\nSoftly the world begins to breathe"
          },
          "duration": {
            "type": "number",
            "minimum": 10,
            "maximum": 300,
            "default": 60,
            "description": "Upper bound on the generated audio length in seconds. The model may stop earlier; the actual length comes back as `duration_seconds`."
          },
          "seed": {
            "type": "integer",
            "description": "Seed for reproducibility. Omit for a random seed."
          },
          "num_inference_steps": {
            "type": "integer",
            "minimum": 1,
            "maximum": 100,
            "default": 30,
            "description": "Flow-matching steps per denoising chunk. More steps improve quality at the cost of speed."
          },
          "guidance_scale": {
            "type": "number",
            "minimum": 0,
            "maximum": 20,
            "default": 1.7,
            "description": "Classifier-free guidance scale of the flow-matching stage."
          },
          "account_id": {
            "type": "string",
            "format": "uuid",
            "description": "Optional. Generate on behalf of another account you can access (self, shared organization, or admin). Defaults to the calling account. Organizations are accounts, so this is also how an organization generation is scoped: send the organization's account id."
          }
        }
      },
      "MusicGenerationCreateResponse": {
        "type": "object",
        "description": "The accepted generation. Poll it until `status` is terminal.",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "success"
            ],
            "description": "Status of the request"
          },
          "generation": {
            "$ref": "#/components/schemas/MusicGeneration"
          }
        }
      },
      "MusicGenerationErrorResponse": {
        "type": "object",
        "required": [
          "status",
          "error"
        ],
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "error"
            ],
            "description": "Always `error`"
          },
          "missing_fields": {
            "type": "array",
            "description": "JSON path segments to the first field that failed validation, e.g. `[\"lyrics\"]`",
            "items": {
              "oneOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            }
          },
          "error": {
            "type": "string",
            "description": "Human-readable error message"
          }
        }
      },
      "MusicGeneration": {
        "type": "object",
        "description": "One music generation.",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "The generation's id. Poll [Get Music Generation](/api-reference/music/get) with this."
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "processing",
              "completed",
              "failed"
            ],
            "description": "Lifecycle phase. `pending` until the workflow picks it up, `processing` while fal is rendering, then `completed` or `failed`."
          },
          "prompt": {
            "type": "string",
            "description": "The music description the song was generated from."
          },
          "lyrics": {
            "type": "string",
            "description": "The lyrics the song was generated from."
          },
          "model": {
            "type": "string",
            "description": "The generating model.",
            "example": "minimax/music-3"
          },
          "duration_seconds": {
            "type": [
              "number",
              "null"
            ],
            "description": "Actual length of the generated audio. Null until completed; may be shorter than requested."
          },
          "audio_url": {
            "type": [
              "string",
              "null"
            ],
            "description": "Playable audio URL. Null until the generation completes."
          },
          "error_message": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why the generation failed. Null unless `status` is `failed`."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the generation was created."
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the generation last changed."
          }
        }
      }
    },
    "securitySchemes": {
      "apiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "Your Recoup API key. [Learn more](/quickstart#api-keys)."
      },
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer"
      }
    }
  }
}
```
