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

# Python REST Guide

> Call the Audixa Text-to-Speech API with Python requests

Audixa does not require or publish a Python SDK package. This guide uses the
general-purpose `requests` library against the documented REST endpoints.

## Requirements

* Python 3.
* An Audixa API key created in [Developers](https://audixa.ai/app/developers#api-keys).
* A minimum \$10 top-up or an active subscription.

## Installation

```bash theme={null}
python -m pip install requests
```

Set your API key outside the source file:

```bash theme={null}
export AUDIXA_API_KEY="YOUR_API_KEY"
```

## Quick Start

```python theme={null}
import os
import time
import requests

API_URL = "https://api.audixa.ai/v3/tts"
API_KEY = os.environ["AUDIXA_API_KEY"]
HEADERS = {"X-API-Key": API_KEY}


def start_tts(payload):
    response = requests.post(
        API_URL,
        headers=HEADERS,
        json=payload,
        timeout=30,
    )
    response.raise_for_status()
    return response.json()


def get_status(generation_id):
    response = requests.get(
        API_URL,
        headers=HEADERS,
        params={"generation_id": generation_id},
        timeout=30,
    )
    response.raise_for_status()
    return response.json()


def generate_tts(payload, poll_interval=2):
    generation = start_tts(payload)

    while generation["status"] not in {"COMPLETED", "FAILED"}:
        time.sleep(poll_interval)
        generation = get_status(generation["generation_id"])

    if generation["status"] == "FAILED":
        raise RuntimeError(generation.get("error_message") or "Generation failed")
    return generation


result = generate_tts({
    "text": "Hello from Audixa. This request is long enough to generate speech.",
    "voice_id": "am_ethan",
    "model": "base",
    "audio_format": "mp3",
})

print(result["audio_url"])
```

## Request Contract

| Parameter | Type | Required | Description |
| - | - | - | - |
| `text` | `str` | Yes | At least 1 character; minimum charge is 30 characters (8 tokens); maximum length depends on the active plan |
| `voice_id` | `str` | Yes | Accessible voice compatible with the selected model |
| `model` | `str` | No | `base` or `advanced`; defaults to `base` |
| `audio_format` | `str` | No | `wav` or `mp3`; defaults to `wav` |
| `speed` | `float` | No | Delivery multiplier from 0.5 to 2.0 |
| `cfg_weight` | `float` | No | Advanced model guidance from 1.0 to 5.0 |
| `exaggeration` | `float` | No | Advanced model expressiveness from 0.0 to 1.0 |
| `language_code` | `str` | No | Model-specific language code |

## Model Controls

The selected voice must be compatible with the requested model. Query
`GET /v3/voices?model=base` or `GET /v3/voices?model=advanced` before selecting
a voice ID.

```python Base request theme={null}
payload = {
    "text": "This Base model request demonstrates the optional speed control.",
    "voice_id": "am_ethan",
    "model": "base",
    "speed": 1.1,
    "audio_format": "wav",
    "language_code": "a",
}
```

```python Advanced request theme={null}
payload = {
    "text": "This Advanced model request demonstrates its guidance controls.",
    "voice_id": "YOUR_ADVANCED_VOICE_ID",
    "model": "advanced",
    "cfg_weight": 3.5,
    "exaggeration": 0.7,
    "audio_format": "mp3",
    "language_code": "en",
}
```

## Language Codes

The two models use different language-code schemes:

<Tabs>
  <Tab title="Base model codes">
    | Code | Language |
    | - | - |
    | `a` | American English |
    | `b` | British English |
    | `j` | Japanese |
    | `z` | Mandarin Chinese |
    | `e` | Spanish |
    | `f` | French |
    | `h` | Hindi |
    | `i` | Italian |
    | `p` | Brazilian Portuguese |
  </Tab>

  <Tab title="Advanced model codes">
    `en`, `ar`, `da`, `de`, `el`, `es`, `fi`, `fr`, `he`, `hi`, `it`, `ja`,
    `ko`, `ms`, `nl`, `no`, `pl`, `pt`, `ru`, `sv`, `sw`, `tr`, `zh`
  </Tab>
</Tabs>

If `language_code` is omitted, the model uses its default language. A code from
the wrong scheme can produce incorrect pronunciation.

## List Compatible Voices

```python theme={null}
response = requests.get(
    "https://api.audixa.ai/v3/voices",
    headers=HEADERS,
    params={"model": "base", "limit": 50},
    timeout=30,
)
response.raise_for_status()

for voice in response.json()["voices"]:
    print(voice["voice_id"], voice["name"], voice["model"])
```

## Download Completed Audio

Only download after the generation status becomes `COMPLETED`:

```python theme={null}
audio_response = requests.get(result["audio_url"], timeout=60)
audio_response.raise_for_status()

with open("output.mp3", "wb") as audio_file:
    audio_file.write(audio_response.content)
```

## Error Handling

```python theme={null}
try:
    result = generate_tts({
        "text": "This request contains enough text for backend validation.",
        "voice_id": "am_ethan",
        "model": "base",
        "audio_format": "mp3",
    })
except requests.HTTPError as error:
    response = error.response
    detail = response.json().get("detail", response.text)
    if response.status_code == 402:
        print("Add funds or start a subscription:", detail)
    else:
        print(f"Audixa HTTP error {response.status_code}: {detail}")
except RuntimeError as error:
    print("Generation reached FAILED status:", error)
```

| HTTP status | Meaning |
| - | - |
| `400` or `422` | Invalid text, voice, model, or parameter value |
| `401` | Missing or invalid API key |
| `402` | Available balance cannot cover the request |
| `403` | The active plan cannot access the requested voice or model |
| `429` | Request or concurrency limit reached |
| `500+` | Server-side failure |

## Authentication Safety

Keep `AUDIXA_API_KEY` in a secret manager or server environment. Do not commit
it, print it, include it in exception reports, or expose it to browser code.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.