# Designed voices

A designed voice is a voice you describe in words and save to your account, through the API or the console. It speaks on Paxa TTS Flash v2 under its own id, at its own rate, and only for your account.

A designed voice is a voice you describe in words and save to your account, through the API or the console's [Voice design](https://paxalabs.com/app/voice-design) tool. A saved voice has an id that starts with `voice_`. Send that id as `voice` with `model` set to `paxa-tts-flash-v2` on [POST /v1/tts](https://paxalabs.com/docs/api/text-to-speech), the [OpenAI-compatible endpoint](https://paxalabs.com/docs/api/speech), or a [live connection](https://paxalabs.com/docs/live-streaming).

## Design a voice

1. Describe it: Send who the voice is and how it should sound as `description` to [POST /v1/voices/design](https://paxalabs.com/docs/api/voice-design). The answer is one voice with a name, a role, a short description, a line spoken in it as MP3, and a `draft`.
2. Refine it: Send the `draft` back with an `instruction` that asks for a change in words. Each answer carries the changed voice and a new draft.
3. Save it: Send the draft you want to [POST /v1/voices/designed](https://paxalabs.com/docs/api/save-voice), with a `name` if you want a different one. Saving gives the voice its id.

curl:

```bash
curl -X POST https://api.paxalabs.com/v1/voices/design \
  -H "Authorization: Bearer $PAXA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "description": "A calm Bangkok pharmacist in her thirties who explains dosages slowly and kindly, speaking Thai"
  }' \
  -o design.json

jq -r .audio design.json | base64 --decode > line.mp3
```

TypeScript:

```typescript
import { writeFile } from "node:fs/promises";

const headers = {
  Authorization: `Bearer ${process.env.PAXA_API_KEY}`,
  "Content-Type": "application/json",
};

// Design, then refine the draft with an instruction.
let response = await fetch("https://api.paxalabs.com/v1/voices/design", {
  method: "POST",
  headers,
  body: JSON.stringify({
    description: "A calm Bangkok pharmacist in her thirties who explains dosages slowly and kindly, speaking Thai",
  }),
});
if (!response.ok) throw new Error(`Design failed: ${response.status}`);
let turn = await response.json();

response = await fetch("https://api.paxalabs.com/v1/voices/design", {
  method: "POST",
  headers,
  body: JSON.stringify({
    draft: turn.draft,
    instruction: "A little slower, with a softer ending",
  }),
});
if (!response.ok) throw new Error(`Refine failed: ${response.status}`);
turn = await response.json();
await writeFile("line.mp3", Buffer.from(turn.audio, "base64"));
```

Python:

```python
import base64
import os
import requests

URL = "https://api.paxalabs.com/v1/voices/design"
HEADERS = {"Authorization": f"Bearer {os.environ['PAXA_API_KEY']}"}

# Design, then refine the draft with an instruction.
turn = requests.post(
    URL,
    headers=HEADERS,
    json={"description": "A calm Bangkok pharmacist in her thirties who explains dosages slowly and kindly, speaking Thai"},
)
turn.raise_for_status()

turn = requests.post(
    URL,
    headers=HEADERS,
    json={
        "draft": turn.json()["draft"],
        "instruction": "A little slower, with a softer ending",
    },
)
turn.raise_for_status()

with open("line.mp3", "wb") as f:
    f.write(base64.b64decode(turn.json()["audio"]))
```

A design or refine call costs 5 credits, its line included. A call that fails without a voice is refunded, and a call you abandon keeps its charge. The console's Voice design tool runs the same steps without code. It can also read a line of your own of up to 120 characters, billed at the designed voice rate below.

## Use the id

The id works only for the account that saved it, from any of its API keys, and only with `paxa-tts-flash-v2`. Case is ignored. [GET /v1/voices/designed](https://paxalabs.com/docs/api/designed-voices) lists the account's designed voices with their ids, and [GET /v1/voices](https://paxalabs.com/docs/api/voices) lists the catalog only. Another account, another model, or a deleted voice answers [400 unknown_voice](https://paxalabs.com/docs/errors#unknown_voice). A designed voice reads the same [direction tags](https://paxalabs.com/docs/directions) as every Paxa TTS Flash v2 voice.

> Designed voices speak through your own API keys and the console only. Model marketplaces that resell Paxa Labs speech, and the speech demo on this site, serve catalog voices.

## Pricing

Speech in a designed voice bills at 1.25 times the model's per-character rate. The premium adds to the [timestamps](https://paxalabs.com/docs/timestamps) premium. A timed request in a designed voice bills at 1.5 times. A 36-character request costs 0.36 credits in a catalog voice, 0.45 in a designed voice, and 0.54 in a designed voice with timestamps. A live connection bills its cumulative text at the same rates. Rounding and the request minimum work as described in [Credits and billing](https://paxalabs.com/docs/credits).

## Voices per plan

The plan sets how many designed voices an account keeps. At the limit, saving another voice is refused until one is deleted. After a downgrade below the voices already saved, every saved voice keeps speaking and new saves are refused. Today the limits are:

| Plan | Designed voices |
| --- | --- |
| Free | 1 |
| Starter | 3 |
| Standard | 10 |
| Pro | 50 |

## Rename and delete

A saved voice cannot be changed. [Rename](https://paxalabs.com/docs/api/rename-voice) or [delete](https://paxalabs.com/docs/api/delete-voice) it through the API or in the Voice design tool, and design a new voice for a different sound. Renaming keeps the id.

Deleting a voice cannot be undone and frees its place in the plan's limit. Every later request naming its id answers 400 unknown_voice, including a retry under the original [Idempotency-Key](https://paxalabs.com/docs/idempotency), and the original request's charge stands. A live connection that opened with the voice keeps speaking in it until the connection closes.
