> ## Documentation Index
> Fetch the complete documentation index at: https://docs.whisul.com/llms.txt
> Use this file to discover all available pages before exploring further.

# POST /generate

> POST /generate accepts a text prompt and queues a music generation job. Returns a job_id and poll_url so you can track and retrieve the result.

The `POST /generate` endpoint accepts a text prompt describing the music you want and enqueues a generation job. Because music generation is asynchronous, the response does not include the finished song — it returns a `job_id` and a `poll_url` you use to check progress. When the job completes, the result contains a `song_url`, cover art, BPM, duration, and descriptive tags.

**Base URL:** `https://whisul.com/api`

## Request

```text theme={null}
POST /generate
```

### Authentication

Every request must include your API key as a Bearer token in the `Authorization` header.

```text theme={null}
Authorization: Bearer <your_api_key>
```

### Request body

Send a JSON body with the following field:

<ParamField body="prompt" type="string" required>
  A plain-language description of the song you want to generate. Describe the genre, mood, instruments, tempo, or any other characteristics — for example, `"an upbeat trap beat with 808s and a dark synth melody"`.
</ParamField>

### Example request

```bash theme={null}
curl --request POST \
  --url https://whisul.com/api/generate \
  --header 'Authorization: Bearer <your_api_key>' \
  --header 'Content-Type: application/json' \
  --data '{"prompt": "an upbeat trap beat with 808s and a dark synth melody"}'
```

## Response

### 202 Accepted

The request was accepted and the generation job is queued. The response body contains the job identifier and a polling URL.

```json theme={null}
{
  "message": "Composition task received.",
  "job_id": "81fa5ff7-6197-4c24-8062-c0ff8b62d58d",
  "poll_url": "/jobs/81fa5ff7-6197-4c24-8062-c0ff8b62d58d"
}
```

<ResponseField name="message" type="string">
  A human-readable confirmation that the task was received.
</ResponseField>

<ResponseField name="job_id" type="string">
  The unique identifier for this generation job. Store this value — you need it to poll for status and retrieve the result.
</ResponseField>

<ResponseField name="poll_url" type="string">
  The relative path to the job status endpoint for this job. Append this to the base URL to construct the full polling URL: `https://whisul.com/api` + `poll_url`.
</ResponseField>

## Error codes

| Status                  | Meaning                                                                                      | What to do                                                                                            |
| ----------------------- | -------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
| `400 Bad Request`       | The request body is missing or invalid — for example, the `prompt` field is absent or empty. | Check your request body and ensure `prompt` is a non-empty string.                                    |
| `401 Unauthorized`      | The `Authorization` header is missing or the API key is invalid.                             | Verify your API key and confirm the header is formatted as `Bearer <your_api_key>`.                   |
| `429 Too Many Requests` | You have exceeded your rate limit.                                                           | Wait before retrying. See the [error codes reference](/api-reference/error-codes) for retry guidance. |

<Tip>
  After you receive a `job_id`, use `GET /jobs/{job_id}` to poll for the result. See the [polling guide](/guides/polling-jobs) for recommended polling intervals and best practices.
</Tip>
