> ## 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.

# GET /jobs/{job_id}

> GET /jobs/{job_id} returns the current status of a generation job. When completed, the response includes song URL, cover art, BPM, duration, and tags.

The `GET /jobs/{job_id}` endpoint returns the current state of a music generation job. Poll this endpoint after calling `POST /generate` to determine when your song is ready. While the job is running, the `result` field is `null`. When the job completes, `result` contains the audio URL, cover artwork, BPM, duration, and descriptive tags.

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

## Request

```text theme={null}
GET /jobs/{job_id}
```

### Authentication

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

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

### Path parameters

<ParamField path="job_id" type="string" required>
  The UUID of the generation job returned by `POST /compose`. Example: `81fa5ff7-6197-4c24-8062-c0ff8b62d58d`.
</ParamField>

### Example request

```bash theme={null}
curl --request GET \
  --url https://whisul.com/api/jobs/81fa5ff7-6197-4c24-8062-c0ff8b62d58d \
  --header 'Authorization: Bearer <your_api_key>'
```

## Response

### 200 OK

Returned for both running and completed jobs.

#### Job is running

When the job is still being processed, `result` is `null` and `finished_at` is not present.

```json theme={null}
{
  "status": "running",
  "prompt": "a trap song",
  "result": null,
  "error": null,
  "started_at": "2026-02-17 15:39:34"
}
```

#### Job is completed

When generation finishes, `status` becomes `"completed"` and the `result` object is populated.

```json theme={null}
{
  "status": "completed",
  "prompt": "a trap song",
  "result": {
    "title": "Midnight Grid",
    "bpm": 140,
    "duration": "2:47",
    "song_url": "https://cdn.whisul.com/audio/81fa5ff7.mp3",
    "image_url": "https://cdn.whisul.com/covers/81fa5ff7.jpg",
    "tags": "trap, dark, 808s, synth, bass"
  },
  "error": null,
  "started_at": "2026-02-17 15:39:34",
  "finished_at": "2026-02-17 15:41:58"
}
```

### Response fields

<ResponseField name="status" type="string">
  The current state of the job. One of `running`, `completed`, or `failed`. See the [job status lifecycle](/api-reference/job-status) for details.
</ResponseField>

<ResponseField name="prompt" type="string">
  The original prompt string submitted with `POST /compose`.
</ResponseField>

<ResponseField name="result" type="object">
  `null` while the job is running or if the job failed. Populated when `status` is `"completed"`.

  <Expandable title="result properties">
    <ResponseField name="title" type="string">
      The AI-generated title for the song.
    </ResponseField>

    <ResponseField name="bpm" type="number">
      The tempo of the generated song in beats per minute.
    </ResponseField>

    <ResponseField name="duration" type="string">
      The length of the song in `m:ss` format — for example, `"2:47"`.
    </ResponseField>

    <ResponseField name="song_url" type="string">
      A URL to the generated audio file.
    </ResponseField>

    <ResponseField name="image_url" type="string">
      A URL to the AI-generated cover artwork for the song.
    </ResponseField>

    <ResponseField name="tags" type="string">
      A comma-separated string of descriptive tags characterizing the song's style, genre, and instrumentation.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="error" type="string | null">
  `null` for running and completed jobs. May contain an error message when `status` is `"failed"`.
</ResponseField>

<ResponseField name="started_at" type="string">
  The timestamp when the job began processing, in `YYYY-MM-DD HH:MM:SS` format (UTC).
</ResponseField>

<ResponseField name="finished_at" type="string">
  The timestamp when the job finished, in `YYYY-MM-DD HH:MM:SS` format (UTC). Only present when `status` is `"completed"` or `"failed"`.
</ResponseField>

## Error codes

| Status                      | Meaning                                                                                | What to do                                                                                   |
| --------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
| `200 OK`                    | The request succeeded. The job may be running or completed — check the `status` field. | Read the `status` field to determine next steps.                                             |
| `404 Not Found`             | No job exists with the provided `job_id`.                                              | Confirm you are using the correct `job_id` returned by `POST /compose`.                      |
| `500 Internal Server Error` | An unexpected server-side error occurred.                                              | Wait briefly and retry. If the issue persists, contact [Whisul support](https://whisul.com). |
