# Upload Voice

`POST /api/voices/upload`

Upload a new voice audio file via the API. The voice will be created with `pending` status and must be approved by an admin before it can be used in broadcasts. This endpoint uses `multipart/form-data` encoding for file upload.

## Request Parameters

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| name | string | Yes | Unique name for the voice (1-255 chars). Names are case-insensitive and must be unique per account. |
| audio | file | Yes | Audio file (max 10MB). Supported formats: mp3, wav, ogg, m4a, aac, webm, flac. |

:::caution[Important]
This endpoint requires `Content-Type: multipart/form-data`. Do **not** set the Content-Type header manually when using browser Fetch or axios — the library will set it automatically with the correct boundary.
:::

## Request Example

```bash
curl -X POST https://api.awajdigital.com/api/voices/upload \
  -H "Authorization: Bearer your_api_token_here" \
  -H "Accept: application/json" \
  -F "name=my_voice_name" \
  -F "audio=@/path/to/your/audio.mp3"
```

```javascript
// Browser JavaScript (Fetch API)
const formData = new FormData();
formData.append('name', 'my_voice_name');
formData.append('audio', fileInput.files[0]); // from an <input type="file">

const response = await fetch('https://api.awajdigital.com/api/voices/upload', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer your_api_token_here',
    'Accept': 'application/json'
  },
  body: formData
});

const data = await response.json();
console.log(data);
```

```javascript
// Node.js with axios and form-data
const axios = require('axios');
const FormData = require('form-data');
const fs = require('fs');

async function uploadVoice() {
  try {
    const form = new FormData();
    form.append('name', 'my_voice_name');
    form.append('audio', fs.createReadStream('/path/to/your/audio.mp3'));

    const response = await axios.post('https://api.awajdigital.com/api/voices/upload', form, {
      headers: {
        'Authorization': 'Bearer your_api_token_here',
        'Accept': 'application/json',
        ...form.getHeaders()
      }
    });

    console.log(response.data);
  } catch (error) {
    console.error('Error:', error.response?.data || error.message);
  }
}

uploadVoice();
```

```python
# Python with requests
import requests

def upload_voice():
    url = 'https://api.awajdigital.com/api/voices/upload'
    headers = {
        'Authorization': 'Bearer your_api_token_here',
        'Accept': 'application/json'
    }
    files = {
        'audio': ('audio.mp3', open('/path/to/your/audio.mp3', 'rb'), 'audio/mpeg')
    }
    data = {
        'name': 'my_voice_name'
    }

    try:
        response = requests.post(url, headers=headers, files=files, data=data)
        print(response.json())
    except requests.exceptions.RequestException as e:
        print(f'Error: {e}')

upload_voice()
```

```php
<?php
// PHP with cURL
$url = 'https://api.awajdigital.com/api/voices/upload';
$token = 'your_api_token_here';

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Bearer ' . $token,
    'Accept: application/json'
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, [
    'name' => 'my_voice_name',
    'audio' => new CURLFile('/path/to/your/audio.mp3', 'audio/mpeg', 'audio.mp3')
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);
curl_close($ch);

$result = json_decode($response, true);
print_r($result);
?>
```

## Success Response (201 Created)

```json
{
  "id": 4,
  "name": "my_voice_name",
  "status": "pending"
}
```

:::note[Voice Approval]
Uploaded voices are created with `pending` status. An admin will review and approve or reject the voice. Only approved voices can be used in broadcasts. Use the [List Voices](/api-docs/voices/list) endpoint to check the approval status of your voices.
:::

## 409 Conflict - Duplicate Voice Name

A voice with the same name already exists in your account:

```json
{
  "message": "A voice with this name already exists"
}
```

## 413 Payload Too Large

Audio file exceeds the 10MB size limit:

```json
{
  "message": "File size too large. Maximum allowed size is 10MB"
}
```

## 415 Unsupported Media Type

Audio file format not supported:

```json
{
  "message": "Invalid file extension. Allowed extensions: mp3, wav, ogg, m4a, aac, webm, flac"
}
```