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

# Inworld TTS 2

## 1. Overview

This document describes how to use speech synthesis and voice cloning through the Inworld TTS native protocol. Both endpoints are synchronous: a POST request returns the result directly, with no need to create a task and poll for the result.

### 1.1 Endpoints

| Capability | Method and path |
| - | - |
| Speech synthesis | `POST /v3/inworld-tts-2/tts/v1/voice` |
| Voice cloning | `POST /v3/inworld-tts-2/voices/v1/voices:clone` |

The full address in the examples in this document is `https://api.novita.ai` plus the endpoint path in the table above, where `https://api.novita.ai` is the API domain you use.

### 1.2 Authentication

All requests must carry the platform API Key and specify the JSON content type:

```text theme={"system"}
Authorization: Bearer <YOUR_API_KEY>
Content-Type: application/json
```

### 1.3 Response Structure

Both endpoints return JSON on success:

* In the JSON returned by a successful speech synthesis request, `audioContent` is Base64-encoded audio data that must be decoded to obtain the raw audio bytes.
* In the JSON returned by a successful voice cloning request, `voice.voiceId` is the ID of the newly cloned voice, which can be used directly as the `voiceId` field of the speech synthesis endpoint.

## 2. Speech Synthesis

Official parameter reference: [Synthesize Speech](https://docs.inworld.ai/api-reference/ttsAPI/texttospeech/synthesize-speech)

### 2.1 Endpoint

```text theme={"system"}
POST https://api.novita.ai/v3/inworld-tts-2/tts/v1/voice
```

Common request fields:

| Field | Type | Required | Description |
| - | - | - | - |
| `text` | string | Yes | Text to synthesize, up to 2000 UTF-16 code units. |
| `voiceId` | string | Yes (either this or `voiceDesign`) | Voice ID to use. You can use a built-in voice (such as `Ashley`) or a `voiceId` produced by the voice cloning endpoint. |
| `modelId` | string | Yes | Model to use, fixed to `inworld-tts-2`. |
| `language` | string | No | BCP-47 language tag (such as `en-US`). If omitted, the language is detected automatically. |
| `deliveryMode` | string | No | Defaults to `DELIVERY_MODE_UNSPECIFIED`. Options are `STABLE`/`BALANCED`/`CREATIVE`. Takes effect only on `inworld-tts-2` and controls how much the output varies. |
| `temperature` | number | No | Defaults to 1, range `(0, 2]`. This field is ignored on the `inworld-tts-2` model. |
| `timestampType` | string | No | Defaults to `TIMESTAMP_TYPE_UNSPECIFIED`. Options are `WORD`/`CHARACTER`, returning timestamp metadata at the corresponding granularity. |
| `applyTextNormalization` | string | No | Defaults to `APPLY_TEXT_NORMALIZATION_UNSPECIFIED`. Options are `ON`/`OFF`, controlling whether numbers, dates, and abbreviations are expanded before synthesis. |
| `enhanceGeneration` | boolean | No | Defaults to `false`. When enabled, noise reduction is applied to the output. |
| `audioConfig.audioEncoding` | string | No | Defaults to `MP3`. Options are `LINEAR16`/`MP3`/`OGG_OPUS`/`ALAW`/`MULAW`/`FLAC`/`PCM`/`WAV`. |
| `audioConfig.bitRate` | integer | No | Takes effect only for compressed formats. Defaults to 128000 (in bit/s). |
| `audioConfig.sampleRateHertz` | integer | No | Range 8000–48000. |
| `audioConfig.speakingRate` | number | No | Defaults to 1.0, range 0.5–1.5. Controls the speaking rate. |

`voiceId` and `voiceDesign` (instant voice design, out of scope of this document) are mutually exclusive; do not provide both.

### 2.2 Example

```bash theme={"system"}
curl -X POST 'https://api.novita.ai/v3/inworld-tts-2/tts/v1/voice' \
  -H 'Authorization: Bearer <YOUR_API_KEY>' \
  -H 'Content-Type: application/json' \
  -d '{
    "text": "Hello world",
    "voiceId": "Ashley",
    "modelId": "inworld-tts-2"
  }'
```

### 2.3 Response

On success, the endpoint returns (HTTP 200):

```json theme={"system"}
{
  "audioContent": "<base64-encoded-audio>"
}
```

| Field | Type | Description |
| - | - | - |
| `audioContent` | string | Base64-encoded audio data, up to 16MB after decoding. The default encoding is `MP3` and can be changed with `audioConfig.audioEncoding`. |
| `usage.processedCharactersCount` | integer | Number of characters processed by this request (usage information). |
| `usage.modelId` | string | Model used for this synthesis. |
| `timestampInfo.wordAlignment` | object | Returned when the request sets `timestampType=WORD`, containing the start and end time of each word. |
| `timestampInfo.characterAlignment` | object | Returned when the request sets `timestampType=CHARACTER`, containing the start and end time of each character. |

Verified in practice: this endpoint has been validated with real requests in all three platform environments and returns real `audioContent`.

### 2.4 Billing

```text theme={"system"}
Request cost = unit price (per million characters) × number of characters in text / 1000000
```

The character count is calculated from the `text` field. Chinese characters count as 2 characters, and other characters (including English letters, digits, spaces, and punctuation) count as 1 character. The exact unit price depends on the pricing page of the service you use.

## 3. Voice Cloning

Official parameter reference: [Clone a Voice](https://docs.inworld.ai/api-reference/voiceAPI/voiceservice/clone-voice)

### 3.1 Endpoint

```text theme={"system"}
POST https://api.novita.ai/v3/inworld-tts-2/voices/v1/voices:clone
```

The request body is JSON. Common fields:

| Field | Type | Required | Description |
| - | - | - | - |
| `displayName` | string | Yes | Display name of the cloned voice. |
| `voiceSamples` | array | Yes | List of audio samples used for cloning. |
| `voiceSamples[].audioData` | string | Yes | Base64-encoded WAV or MP3 audio. 10–30 seconds is recommended; anything longer than 30 seconds is truncated. |
| `voiceSamples[].transcription` | string | No | Transcription of the sample. Generated automatically if omitted. |
| `langCode` | string | No | Language (legacy uppercase underscore format, such as `EN_US`). Mutually exclusive with `languageCode`; do not provide both. `AUTO` means automatic detection. |
| `languageCode` | string | No | Language (standard format, such as `en-US`). The language is detected automatically when omitted or set to `"auto"`. |
| `description` | string | No | Description of the voice's tone, accent, or purpose, to make it easier to find. |
| `tags` | array | No | Free-form tags used for filtering and grouping. Gender and age cannot be set through this field; values passed in are silently ignored. |
| `audioProcessingConfig.removeBackgroundNoise` | boolean | No | Whether to separate background noise from the sample. If the original audio is already clean, enabling this may reduce quality instead. |

<Note>
  `gender`/`ageGroup`/`categories` cannot be set during cloning. Call UpdateVoice separately after cloning is complete to set them.
</Note>

### 3.2 Example

```bash theme={"system"}
curl -X POST 'https://api.novita.ai/v3/inworld-tts-2/voices/v1/voices:clone' \
  -H 'Authorization: Bearer <YOUR_API_KEY>' \
  -H 'Content-Type: application/json' \
  -d '{
    "displayName": "my-cloned-voice",
    "voiceSamples": [
      {
        "audioData": "<base64-encoded-audio>"
      }
    ]
  }'
```

### 3.3 Response

On success, the endpoint returns (HTTP 200):

```json theme={"system"}
{
  "voice": {
    "voiceId": "<workspace_id>__my-cloned-voice",
    "displayName": "my-cloned-voice",
    "source": "IVC"
  },
  "audioSamplesValidated": [
    {
      "langCode": "EN_US",
      "transcription": "...",
      "warnings": [],
      "errors": []
    }
  ]
}
```

| Field | Type | Description |
| - | - | - |
| `voice.voiceId` | string | ID of the cloned voice, used directly as the `voiceId` field of the speech synthesis endpoint. The format is `{workspace}__{voice name}`. |
| `voice.displayName` | string | Echoes the display name from the request. |
| `voice.source` | string | Fixed to `IVC` for instant cloning. |
| `audioSamplesValidated[].langCode` | string | Language of the sample, either detected or specified. |
| `audioSamplesValidated[].transcription` | string | Transcription of the sample. |
| `audioSamplesValidated[].warnings`/`.errors` | array | Lists of non-fatal/fatal issues encountered while processing the sample. |

Verified in practice: the full "clone → synthesize with the cloned voiceId" path has been validated with real requests in all three platform environments.

### 3.4 Billing

The voice cloning endpoint is always free of charge and generates no cost.

## 4. Common Errors and Notes

Endpoint errors use the following structure:

```json theme={"system"}
{
  "code": "<error code>",
  "message": "<error message>"
}
```

| HTTP | Common scenario | Suggested handling |
| - | - | - |
| 400 | Invalid request parameters, such as missing fields, wrong format, or `text` too long. | Fix the request based on the error message. |
| 401 | API Key missing or invalid. | Check the `Authorization` request header. |
| 404 | The `voiceId` used does not exist or is not accessible. | Check the value of the `voiceId` field. |
| 429 | Too many requests (voice cloning is rate limited more strictly than speech synthesis). | Reduce the request rate and use exponential backoff. |
| 500 | Temporary service error. | Retry later. If the failure persists, contact technical support. |

Other notes:

* A `voiceId` created by voice cloning is shared among all callers under the current API Key, and the system does not record which caller cloned which voice. Manage voice ownership and visibility in your own business layer, and do not assume the platform isolates voices between callers.
* Supported audio formats for the voice cloning endpoint are `wav`/`mp3`/`webm`, with a maximum of 12MB per file.


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