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

# Key & BPM Extraction

> Processes an audio file to extract key changes, dominant key, and BPM (Beats Per Minute).

Extract key and BPM (beats per minute) from an input audio file with optional webhook callback for asynchronous updates.

***

## Endpoint

```http theme={null}
POST /v1/extract_key_bpm
```

This endpoint analyzes an audio file to determine its musical key and BPM. You can upload the audio file or provide a URL. Optionally, supply a `webhook_url` to receive asynchronous results.

***

## Request Parameters

| Parameter     | Type         | Required | Description                                                                               |
| ------------- | ------------ | -------- | ----------------------------------------------------------------------------------------- |
| `audio_url`   | `String`     | Optional | The URL of an audio file to analyze. Either `audio_url` or `audio_file` must be provided. |
| `audio_file`  | `UploadFile` | Optional | Upload the audio file directly. Either `audio_url` or `audio_file` must be provided.      |
| `webhook_url` | `String`     | Optional | Callback URL for async response.                                                          |

> 💡 **Note:** Either `audio_url` or `audio_file` must be provided — one is required.

> **content-type:** multipart/form-data

***

## Sample Request

### cURL

```bash theme={null}
curl -X POST "https://api.musicgpt.com/api/public/v1/KeyBpmExtract" \
-H "accept: application/json" \
-H "Authorization: <api_key>" \
-F "audio_url=https://www.youtube.com/watch?v=jGflUbPQfW8" \
-F "webhook_url=http://webhook.musicgpt.com"
```

### Python

```python theme={null}
import requests

url = "https://api.musicgpt.com/api/public/v1/extract_key_bpm"
headers = {
    "Authorization": "<<<api key>>>"
}

# Option 1: URL
payload = {
    "audio_url": "https://example.com/audio.m4a",
    "webhook_url": ""
}
response = requests.post(url, headers=headers, data=payload)
print(response.json())

# Option 2: File Upload
# payload = {
#     "webhook_url": "https://www.test.requestcatcher.com/test"
# }
# with open("audio.m4a", "rb") as f:
#     files = {"audio_file": f}
#     response = requests.post(url, headers=headers, data=payload, files=files)
# print(response.json())
```

> 🔐 Replace `{path_to_your_audio_file}`, `api_key`, and `webhook_url` before executing.

***

## Sample Response

### Success (200 OK)

```json theme={null}
{
  "success":true,
  "task_id":"69ec90f0-a00a-48f8-bdb3-8728a635e057",
  "conversion_id":"8be8c439-dbc9-4ae6-8fe3-3fcb95f5a60a",
  "eta":-1,
  "credit_estimate":0.48,
  "message":"Successfully Published to Queue",
  "status":"IN_QUEUE"
}
```

***

## Common Errors

* **422 Unprocessable Entity**: Both `audio_url` and `audio_file` cannot be `None`.
* **500 Internal Server Error**: A server error occurred during processing.

***

## Webhook Response

Once key and BPM extraction is completed, the webhook receives:

```json theme={null}
{
  "success": true, 
  "task_id": "69ec90f0-a00a-48f8-bdb3-8728a635e057", 
  "conversion_id": "8be8c439-dbc9-4ae6-8fe3-3fcb95f5a60a", 
  "conversion_path": "files/a4037db1-d163-48b3-b1ba-cb93c2045228.wav", 
  "conversion_duration": "0", 
  "key_changes": {"0-120": ["A# major"], "120-140": ["D# major", "G minor"], "140-220": ["A# major", "A# minor"]}, 
  "dominant_key": "A# major", 
  "bpm": 162, 
  "conversion_type": "Key BPM Extraction"
}
```

***

## Output Fields

* `key_changes`: A mapping of time ranges to identified keys.
* `dominant_key`: The most prominent key throughout the audio.
* `bpm`: Estimated beats per minute.
* `conversion_path`: Path to the original input audio file.
* `conversion_path_wav`: Path to the `.wav` version of the input file.

***

## Payload and Request Formation


## OpenAPI

````yaml POST /v1/extract_key_bpm
openapi: 3.1.0
info:
  title: Musicgpt API
  version: 1.0.0
  description: API for retrieving conversion details by ID.
servers:
  - url: https://api.musicgpt.com/api/public
    description: Production server
security: []
paths:
  /v1/extract_key_bpm:
    post:
      summary: Extract Key, BPM, and Key Changes from Audio
      description: >-
        Processes an audio file to extract key changes, dominant key, and BPM
        (Beats Per Minute).
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                audio_url:
                  type: string
                  description: 'Input audio URL (supported format: YouTube URL).'
                  example: https://www.youtube.com/watch?v=example123
                audio_file:
                  type: string
                  format: binary
                  description: Audio file to upload and process directly.
                webhook_url:
                  type: string
                  description: Callback URL for async processing results.
                  example: http://your-webhook-url.com/callback
              anyOf:
                - required:
                    - audio_url
                - required:
                    - audio_file
      responses:
        '200':
          description: Successfully initiated key/bpm extraction
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  task_id:
                    type: string
                  conversion_id:
                    type: string
                  eta:
                    type: integer
                  credit_estimate:
                    type: number
                    format: float
                  message:
                    type: string
                example:
                  success: true
                  task_id: keybpm789
                  conversion_id: conv456
                  eta: -1
                  credit_estimate: 100.1
                  message: Successfully published to queue
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: false
                  error:
                    type: string
                    example: Either audio_url or audio_file must be provided.
        '500':
          description: Server Error
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: false
                  error:
                    type: string
                    example: Internal Server Error
      security:
        - ApiKeyAuth: []
      x-codeSamples:
        - lang: Python
          source: >-
            import requests


            url = "https://api.musicgpt.com/api/public/v1/extract_key_bpm"


            headers = {
                "Authorization": "<API_KEY>"
            }


            data = {
                "webhook_url": "https://example.com/my-webhook"
            }


            # Option 1: audio_url

            data["audio_url"] = "<YOUR_AUDIO_URL>"

            response = requests.post(url, headers=headers, data=data)


            # Option 2: File Upload

            # with open("song.mp3", "rb") as f:

            #     files = {"audio_file": f}

            #     response = requests.post(url, headers=headers, data=data,
            files=files)


            print(response.json())
components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: Authorization

````