> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.formantai.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.formantai.com/_mcp/server.

# Submit a text-to-speech batch

POST https://api.voice.formantai.com/v1/tts/batch
Content-Type: application/json

Queues up to 50 texts to be voiced, one clip per text, with one provider, model and voice. Returns as soon as the batch is accepted and its exact charge is held — poll `GET /v1/tts/batch/{job_id}` for the audio. Billed per 1,000 characters at your workspace's text-to-speech rate; clips that fail to render are refunded.

Reference: https://docs.formantai.com/api-reference/formant-ai-voice-api/text-to-speech/submit-tts-batch

## Authentication

- `Authorization` header (bearer token, required) — Bearer authentication of the form `Bearer <token>`, where token is your auth token.

## Servers

- `https://api.voice.formantai.com` (Global production, default)
- `https://api.in.voice.formantai.com` (India production)

## Request

### Body (application/json)

This endpoint expects a TtsBatchRequest.

- `texts` (list of string, required) — Texts to voice, one clip each, in order. Each is up to 5,000 characters; a longer one is rejected with 400 naming its index.
- `tts_provider` (enum, required) — Provider that voices every clip. Resolved to your own workspace's connection server-side; a provider your workspace has no connection to is rejected with 400.
  - Allowed values: `sarvam`, `smallest`, `vakyam`, `elevenlabs`
- `voice_id` (string, required) — Voice of the chosen provider, passed through unchanged: an ElevenLabs voice id (`21m00Tcm4TlvDq8ikWAM`), a Sarvam `bulbul:v3` speaker (`priya`) or `bulbul:v4-flash` persona (`ritu_hi_customer`) matching `tts_model`, a Smallest `lightning_v3.1_pro` voice (`mandar`) or a Vakyam voice name (`Archana`). Not checked at submit — a wrong voice fails each clip with the provider's message.
- `tts_model` (enum, optional) — Must be selectable for `tts_provider`: `eleven_multilingual_v2` (default), `eleven_flash_v2_5`, `eleven_turbo_v2_5`, `eleven_v4` or `eleven_v4_turbo` for `elevenlabs`; `bulbul:v3` (default) or `bulbul:v4-flash` for `sarvam`; `lightning_v3.1_pro` for `smallest`; `raaga-v1` for `vakyam`. Omit it for the provider's default.
  - Allowed values: `bulbul:v3`, `bulbul:v4-flash`, `lightning_v3.1_pro`, `raaga-v1`, `eleven_multilingual_v2`, `eleven_flash_v2_5`, `eleven_turbo_v2_5`, `eleven_v4`, `eleven_v4_turbo`
- `language` (string, optional, nullable) — Language name (`Hindi`, `english`) or locale code (`hi-IN`, `en-IN`), any case, normalized to a locale code. Omitted, Sarvam speaks `en-IN`, Smallest `en` and Vakyam `hi-IN`; ElevenLabs is not sent a language and speaks the language the text is written in. Text is spoken as written, not translated.

## Response

### 200

Batch accepted and rendering

- `id` (string, required) — Batch id, 32 lowercase hex characters. Poll it to collect the audio.
- `status` (enum, required) — Always `pending` on submit — rendering runs asynchronously.
  - Allowed values: `pending`

## Errors

### 400 Bad Request Error

Invalid request

- `error` (ErrorResponseError, optional)

### 401 Unauthorized Error

Invalid or missing API key

- `error` (ErrorResponseError, optional)

### 402 Payment Required Error

The workspace balance cannot cover the operation

- `error` (ErrorResponseError, optional)

### 422 Unprocessable Entity Error

A form field is missing or cannot be parsed. Uses FastAPI's validation envelope, not the standard error envelope.

- `detail` (list of ValidationErrorResponseDetailItems, optional)

### 429 Too Many Requests Error

Rate limit exceeded

- `error` (ErrorResponseError, optional)

### 503 Service Unavailable Error

Transcription is temporarily unavailable — safe to retry with backoff

- `error` (ErrorResponseError, optional)

## Types

### ErrorResponseError

- `message` (string, optional)
- `type` (string, optional)

### ValidationErrorResponseDetailItems

- `type` (string, optional)
- `loc` (list of string, optional)
- `msg` (string, optional)

## Examples

### Sarvam bulbul:v3

**Request**

```json
{
  "texts": [
    "Namaste! Aapka order ship ho gaya hai.",
    "Your order will arrive by Friday."
  ],
  "tts_provider": "sarvam",
  "voice_id": "priya",
  "tts_model": "bulbul:v3",
  "language": "hi-IN"
}
```

**Response**

```json
{
  "id": "01b5ebec0fd34bcba12451ca79f27ab4",
  "status": "pending"
}
```

**SDK Code**

```python Sarvam bulbul:v3
import requests

url = "https://api.voice.formantai.com/v1/tts/batch"

payload = {
    "texts": ["Namaste! Aapka order ship ho gaya hai.", "Your order will arrive by Friday."],
    "tts_provider": "sarvam",
    "voice_id": "priya",
    "tts_model": "bulbul:v3",
    "language": "hi-IN"
}
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript Sarvam bulbul:v3
const url = 'https://api.voice.formantai.com/v1/tts/batch';
const options = {
  method: 'POST',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"texts":["Namaste! Aapka order ship ho gaya hai.","Your order will arrive by Friday."],"tts_provider":"sarvam","voice_id":"priya","tts_model":"bulbul:v3","language":"hi-IN"}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Sarvam bulbul:v3
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.voice.formantai.com/v1/tts/batch"

	payload := strings.NewReader("{\n  \"texts\": [\n    \"Namaste! Aapka order ship ho gaya hai.\",\n    \"Your order will arrive by Friday.\"\n  ],\n  \"tts_provider\": \"sarvam\",\n  \"voice_id\": \"priya\",\n  \"tts_model\": \"bulbul:v3\",\n  \"language\": \"hi-IN\"\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Sarvam bulbul:v3
require 'uri'
require 'net/http'

url = URI("https://api.voice.formantai.com/v1/tts/batch")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"texts\": [\n    \"Namaste! Aapka order ship ho gaya hai.\",\n    \"Your order will arrive by Friday.\"\n  ],\n  \"tts_provider\": \"sarvam\",\n  \"voice_id\": \"priya\",\n  \"tts_model\": \"bulbul:v3\",\n  \"language\": \"hi-IN\"\n}"

response = http.request(request)
puts response.read_body
```

```java Sarvam bulbul:v3
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.voice.formantai.com/v1/tts/batch")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"texts\": [\n    \"Namaste! Aapka order ship ho gaya hai.\",\n    \"Your order will arrive by Friday.\"\n  ],\n  \"tts_provider\": \"sarvam\",\n  \"voice_id\": \"priya\",\n  \"tts_model\": \"bulbul:v3\",\n  \"language\": \"hi-IN\"\n}")
  .asString();
```

```php Sarvam bulbul:v3
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.voice.formantai.com/v1/tts/batch', [
  'body' => '{
  "texts": [
    "Namaste! Aapka order ship ho gaya hai.",
    "Your order will arrive by Friday."
  ],
  "tts_provider": "sarvam",
  "voice_id": "priya",
  "tts_model": "bulbul:v3",
  "language": "hi-IN"
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp Sarvam bulbul:v3
using RestSharp;

var client = new RestClient("https://api.voice.formantai.com/v1/tts/batch");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"texts\": [\n    \"Namaste! Aapka order ship ho gaya hai.\",\n    \"Your order will arrive by Friday.\"\n  ],\n  \"tts_provider\": \"sarvam\",\n  \"voice_id\": \"priya\",\n  \"tts_model\": \"bulbul:v3\",\n  \"language\": \"hi-IN\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Sarvam bulbul:v3
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [
  "texts": ["Namaste! Aapka order ship ho gaya hai.", "Your order will arrive by Friday."],
  "tts_provider": "sarvam",
  "voice_id": "priya",
  "tts_model": "bulbul:v3",
  "language": "hi-IN"
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.voice.formantai.com/v1/tts/batch")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

### Sarvam bulbul:v4-flash

**Request**

```json
{
  "texts": [
    "Namaste! Aapka order ship ho gaya hai.",
    "Your order will arrive by Friday."
  ],
  "tts_provider": "sarvam",
  "voice_id": "ritu_hi_customer",
  "tts_model": "bulbul:v4-flash",
  "language": "hi-IN"
}
```

**Response**

```json
{
  "id": "01b5ebec0fd34bcba12451ca79f27ab4",
  "status": "pending"
}
```

**SDK Code**

```python Sarvam bulbul:v4-flash
import requests

url = "https://api.voice.formantai.com/v1/tts/batch"

payload = {
    "texts": ["Namaste! Aapka order ship ho gaya hai.", "Your order will arrive by Friday."],
    "tts_provider": "sarvam",
    "voice_id": "ritu_hi_customer",
    "tts_model": "bulbul:v4-flash",
    "language": "hi-IN"
}
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript Sarvam bulbul:v4-flash
const url = 'https://api.voice.formantai.com/v1/tts/batch';
const options = {
  method: 'POST',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"texts":["Namaste! Aapka order ship ho gaya hai.","Your order will arrive by Friday."],"tts_provider":"sarvam","voice_id":"ritu_hi_customer","tts_model":"bulbul:v4-flash","language":"hi-IN"}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Sarvam bulbul:v4-flash
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.voice.formantai.com/v1/tts/batch"

	payload := strings.NewReader("{\n  \"texts\": [\n    \"Namaste! Aapka order ship ho gaya hai.\",\n    \"Your order will arrive by Friday.\"\n  ],\n  \"tts_provider\": \"sarvam\",\n  \"voice_id\": \"ritu_hi_customer\",\n  \"tts_model\": \"bulbul:v4-flash\",\n  \"language\": \"hi-IN\"\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Sarvam bulbul:v4-flash
require 'uri'
require 'net/http'

url = URI("https://api.voice.formantai.com/v1/tts/batch")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"texts\": [\n    \"Namaste! Aapka order ship ho gaya hai.\",\n    \"Your order will arrive by Friday.\"\n  ],\n  \"tts_provider\": \"sarvam\",\n  \"voice_id\": \"ritu_hi_customer\",\n  \"tts_model\": \"bulbul:v4-flash\",\n  \"language\": \"hi-IN\"\n}"

response = http.request(request)
puts response.read_body
```

```java Sarvam bulbul:v4-flash
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.voice.formantai.com/v1/tts/batch")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"texts\": [\n    \"Namaste! Aapka order ship ho gaya hai.\",\n    \"Your order will arrive by Friday.\"\n  ],\n  \"tts_provider\": \"sarvam\",\n  \"voice_id\": \"ritu_hi_customer\",\n  \"tts_model\": \"bulbul:v4-flash\",\n  \"language\": \"hi-IN\"\n}")
  .asString();
```

```php Sarvam bulbul:v4-flash
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.voice.formantai.com/v1/tts/batch', [
  'body' => '{
  "texts": [
    "Namaste! Aapka order ship ho gaya hai.",
    "Your order will arrive by Friday."
  ],
  "tts_provider": "sarvam",
  "voice_id": "ritu_hi_customer",
  "tts_model": "bulbul:v4-flash",
  "language": "hi-IN"
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp Sarvam bulbul:v4-flash
using RestSharp;

var client = new RestClient("https://api.voice.formantai.com/v1/tts/batch");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"texts\": [\n    \"Namaste! Aapka order ship ho gaya hai.\",\n    \"Your order will arrive by Friday.\"\n  ],\n  \"tts_provider\": \"sarvam\",\n  \"voice_id\": \"ritu_hi_customer\",\n  \"tts_model\": \"bulbul:v4-flash\",\n  \"language\": \"hi-IN\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Sarvam bulbul:v4-flash
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [
  "texts": ["Namaste! Aapka order ship ho gaya hai.", "Your order will arrive by Friday."],
  "tts_provider": "sarvam",
  "voice_id": "ritu_hi_customer",
  "tts_model": "bulbul:v4-flash",
  "language": "hi-IN"
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.voice.formantai.com/v1/tts/batch")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

### ElevenLabs

**Request**

```json
{
  "texts": [
    "Namaste! Aapka order ship ho gaya hai.",
    "Your order will arrive by Friday."
  ],
  "tts_provider": "elevenlabs",
  "voice_id": "21m00Tcm4TlvDq8ikWAM",
  "tts_model": "eleven_multilingual_v2"
}
```

**Response**

```json
{
  "id": "01b5ebec0fd34bcba12451ca79f27ab4",
  "status": "pending"
}
```

**SDK Code**

```python ElevenLabs
import requests

url = "https://api.voice.formantai.com/v1/tts/batch"

payload = {
    "texts": ["Namaste! Aapka order ship ho gaya hai.", "Your order will arrive by Friday."],
    "tts_provider": "elevenlabs",
    "voice_id": "21m00Tcm4TlvDq8ikWAM",
    "tts_model": "eleven_multilingual_v2"
}
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript ElevenLabs
const url = 'https://api.voice.formantai.com/v1/tts/batch';
const options = {
  method: 'POST',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"texts":["Namaste! Aapka order ship ho gaya hai.","Your order will arrive by Friday."],"tts_provider":"elevenlabs","voice_id":"21m00Tcm4TlvDq8ikWAM","tts_model":"eleven_multilingual_v2"}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go ElevenLabs
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.voice.formantai.com/v1/tts/batch"

	payload := strings.NewReader("{\n  \"texts\": [\n    \"Namaste! Aapka order ship ho gaya hai.\",\n    \"Your order will arrive by Friday.\"\n  ],\n  \"tts_provider\": \"elevenlabs\",\n  \"voice_id\": \"21m00Tcm4TlvDq8ikWAM\",\n  \"tts_model\": \"eleven_multilingual_v2\"\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby ElevenLabs
require 'uri'
require 'net/http'

url = URI("https://api.voice.formantai.com/v1/tts/batch")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"texts\": [\n    \"Namaste! Aapka order ship ho gaya hai.\",\n    \"Your order will arrive by Friday.\"\n  ],\n  \"tts_provider\": \"elevenlabs\",\n  \"voice_id\": \"21m00Tcm4TlvDq8ikWAM\",\n  \"tts_model\": \"eleven_multilingual_v2\"\n}"

response = http.request(request)
puts response.read_body
```

```java ElevenLabs
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.voice.formantai.com/v1/tts/batch")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"texts\": [\n    \"Namaste! Aapka order ship ho gaya hai.\",\n    \"Your order will arrive by Friday.\"\n  ],\n  \"tts_provider\": \"elevenlabs\",\n  \"voice_id\": \"21m00Tcm4TlvDq8ikWAM\",\n  \"tts_model\": \"eleven_multilingual_v2\"\n}")
  .asString();
```

```php ElevenLabs
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.voice.formantai.com/v1/tts/batch', [
  'body' => '{
  "texts": [
    "Namaste! Aapka order ship ho gaya hai.",
    "Your order will arrive by Friday."
  ],
  "tts_provider": "elevenlabs",
  "voice_id": "21m00Tcm4TlvDq8ikWAM",
  "tts_model": "eleven_multilingual_v2"
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp ElevenLabs
using RestSharp;

var client = new RestClient("https://api.voice.formantai.com/v1/tts/batch");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"texts\": [\n    \"Namaste! Aapka order ship ho gaya hai.\",\n    \"Your order will arrive by Friday.\"\n  ],\n  \"tts_provider\": \"elevenlabs\",\n  \"voice_id\": \"21m00Tcm4TlvDq8ikWAM\",\n  \"tts_model\": \"eleven_multilingual_v2\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift ElevenLabs
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [
  "texts": ["Namaste! Aapka order ship ho gaya hai.", "Your order will arrive by Friday."],
  "tts_provider": "elevenlabs",
  "voice_id": "21m00Tcm4TlvDq8ikWAM",
  "tts_model": "eleven_multilingual_v2"
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.voice.formantai.com/v1/tts/batch")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```