curl --request GET \
--url 'https://api.typecast.ai/v2/voices/tc_60e5426de8b95f1d3000d7b5' \
--header 'X-API-KEY: <api-key>'using System;
using System.Net.Http;
using System.Threading.Tasks;
var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-KEY", "<api-key>");
var voiceId = "tc_60e5426de8b95f1d3000d7b5";
var response = await client.GetAsync($"https://api.typecast.ai/v2/voices/{voiceId}");
if (response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsStringAsync();
Console.WriteLine(content);
}import okhttp3.OkHttpClient
import okhttp3.Request
val client = OkHttpClient()
val voiceId = "tc_60e5426de8b95f1d3000d7b5"
val request = Request.Builder()
.url("https://api.typecast.ai/v2/voices/$voiceId")
.addHeader("X-API-KEY", "<api-key>")
.get()
.build()
client.newCall(request).execute().use { response ->
if (response.isSuccessful) {
println(response.body?.string())
}
}#include <curl/curl.h>
#include <string>
#include <iostream>
size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userp) {
((std::string*)userp)->append((char*)contents, size * nmemb);
return size * nmemb;
}
int main() {
CURL* curl = curl_easy_init();
if(curl) {
std::string readBuffer;
struct curl_slist* headers = NULL;
headers = curl_slist_append(headers, "X-API-KEY: <api-key>");
std::string url = "https://api.typecast.ai/v2/voices/tc_60e5426de8b95f1d3000d7b5";
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
CURLcode res = curl_easy_perform(curl);
if(res == CURLE_OK) {
std::cout << readBuffer << std::endl;
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
}
return 0;
}#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>
typedef struct {
char* data;
size_t size;
} MemoryStruct;
size_t WriteMemoryCallback(void* contents, size_t size, size_t nmemb, void* userp) {
size_t realsize = size * nmemb;
MemoryStruct* mem = (MemoryStruct*)userp;
char* ptr = realloc(mem->data, mem->size + realsize + 1);
if(!ptr) return 0;
mem->data = ptr;
memcpy(&(mem->data[mem->size]), contents, realsize);
mem->size += realsize;
mem->data[mem->size] = 0;
return realsize;
}
int main(void) {
CURL* curl;
CURLcode res;
MemoryStruct chunk = {NULL, 0};
curl_global_init(CURL_GLOBAL_ALL);
curl = curl_easy_init();
if(curl) {
struct curl_slist* headers = NULL;
headers = curl_slist_append(headers, "X-API-KEY: <api-key>");
const char* url = "https://api.typecast.ai/v2/voices/tc_60e5426de8b95f1d3000d7b5";
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&chunk);
res = curl_easy_perform(curl);
if(res == CURLE_OK) {
printf("%s\n", chunk.data);
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
free(chunk.data);
}
curl_global_cleanup();
return 0;
}import Foundation
let voiceId = "tc_60e5426de8b95f1d3000d7b5"
let url = URL(string: "https://api.typecast.ai/v2/voices/\(voiceId)")!
var request = URLRequest(url: url)
request.httpMethod = "GET"
request.setValue("<api-key>", forHTTPHeaderField: "X-API-KEY")
let task = URLSession.shared.dataTask(with: request) { data, response, error in
if let data = data, let jsonString = String(data: data, encoding: .utf8) {
print(jsonString)
}
}
task.resume()use reqwest;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = reqwest::Client::new();
let voice_id = "tc_60e5426de8b95f1d3000d7b5";
let url = format!("https://api.typecast.ai/v2/voices/{}", voice_id);
let response = client
.get(&url)
.header("X-API-KEY", "<api-key>")
.send()
.await?;
if response.status().is_success() {
let body = response.text().await?;
println!("{}", body);
}
Ok(())
}import requests
url = "https://api.typecast.ai/v2/voices/{voice_id}"
headers = {"X-API-KEY": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-KEY': '<api-key>'}};
fetch('https://api.typecast.ai/v2/voices/{voice_id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.typecast.ai/v2/voices/{voice_id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-KEY: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.typecast.ai/v2/voices/{voice_id}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-KEY", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.typecast.ai/v2/voices/{voice_id}")
.header("X-API-KEY", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.typecast.ai/v2/voices/{voice_id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-KEY"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"voice_id": "tc_60e5426de8b95f1d3000d7b5",
"voice_name": "Olivia",
"models": [
{
"version": "ssfm-v30",
"emotions": [
"normal",
"happy",
"sad",
"angry",
"whisper",
"toneup",
"tonedown"
]
},
{
"version": "ssfm-v21",
"emotions": [
"normal",
"happy",
"sad",
"angry"
]
}
],
"gender": "female",
"age": "young_adult",
"use_cases": [
"Audiobook",
"E-learning",
"Ads"
],
"voice_type": "original"
}{
"detail": "Invalid API key"
}{
"detail": "Voice not found"
}{
"detail": "Invalid request format"
}Get Voice Details
Retrieves detailed information for a specific voice with enhanced metadata (V2).
This endpoint returns the complete information for a single voice, including model-grouped emotion support and metadata such as gender, age group, and use cases. Use this when you need to verify voice details or check available emotions before making a TTS request.
Response includes:
- voice_id: Unique voice identifier
- voice_name: Human-readable voice name
- models: Array of supported TTS models with their respective emotion sets
- gender: Voice gender classification (male/female)
- age: Age group classification (child/teenager/young_adult/middle_age/elder)
- use_cases: Recommended content categories for this voice
Use Cases:
- Verify voice availability before TTS request
- Check supported emotions for a specific voice and model combination
- Display voice details in a voice selection UI
curl --request GET \
--url 'https://api.typecast.ai/v2/voices/tc_60e5426de8b95f1d3000d7b5' \
--header 'X-API-KEY: <api-key>'using System;
using System.Net.Http;
using System.Threading.Tasks;
var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-KEY", "<api-key>");
var voiceId = "tc_60e5426de8b95f1d3000d7b5";
var response = await client.GetAsync($"https://api.typecast.ai/v2/voices/{voiceId}");
if (response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsStringAsync();
Console.WriteLine(content);
}import okhttp3.OkHttpClient
import okhttp3.Request
val client = OkHttpClient()
val voiceId = "tc_60e5426de8b95f1d3000d7b5"
val request = Request.Builder()
.url("https://api.typecast.ai/v2/voices/$voiceId")
.addHeader("X-API-KEY", "<api-key>")
.get()
.build()
client.newCall(request).execute().use { response ->
if (response.isSuccessful) {
println(response.body?.string())
}
}#include <curl/curl.h>
#include <string>
#include <iostream>
size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userp) {
((std::string*)userp)->append((char*)contents, size * nmemb);
return size * nmemb;
}
int main() {
CURL* curl = curl_easy_init();
if(curl) {
std::string readBuffer;
struct curl_slist* headers = NULL;
headers = curl_slist_append(headers, "X-API-KEY: <api-key>");
std::string url = "https://api.typecast.ai/v2/voices/tc_60e5426de8b95f1d3000d7b5";
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
CURLcode res = curl_easy_perform(curl);
if(res == CURLE_OK) {
std::cout << readBuffer << std::endl;
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
}
return 0;
}#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>
typedef struct {
char* data;
size_t size;
} MemoryStruct;
size_t WriteMemoryCallback(void* contents, size_t size, size_t nmemb, void* userp) {
size_t realsize = size * nmemb;
MemoryStruct* mem = (MemoryStruct*)userp;
char* ptr = realloc(mem->data, mem->size + realsize + 1);
if(!ptr) return 0;
mem->data = ptr;
memcpy(&(mem->data[mem->size]), contents, realsize);
mem->size += realsize;
mem->data[mem->size] = 0;
return realsize;
}
int main(void) {
CURL* curl;
CURLcode res;
MemoryStruct chunk = {NULL, 0};
curl_global_init(CURL_GLOBAL_ALL);
curl = curl_easy_init();
if(curl) {
struct curl_slist* headers = NULL;
headers = curl_slist_append(headers, "X-API-KEY: <api-key>");
const char* url = "https://api.typecast.ai/v2/voices/tc_60e5426de8b95f1d3000d7b5";
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&chunk);
res = curl_easy_perform(curl);
if(res == CURLE_OK) {
printf("%s\n", chunk.data);
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
free(chunk.data);
}
curl_global_cleanup();
return 0;
}import Foundation
let voiceId = "tc_60e5426de8b95f1d3000d7b5"
let url = URL(string: "https://api.typecast.ai/v2/voices/\(voiceId)")!
var request = URLRequest(url: url)
request.httpMethod = "GET"
request.setValue("<api-key>", forHTTPHeaderField: "X-API-KEY")
let task = URLSession.shared.dataTask(with: request) { data, response, error in
if let data = data, let jsonString = String(data: data, encoding: .utf8) {
print(jsonString)
}
}
task.resume()use reqwest;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = reqwest::Client::new();
let voice_id = "tc_60e5426de8b95f1d3000d7b5";
let url = format!("https://api.typecast.ai/v2/voices/{}", voice_id);
let response = client
.get(&url)
.header("X-API-KEY", "<api-key>")
.send()
.await?;
if response.status().is_success() {
let body = response.text().await?;
println!("{}", body);
}
Ok(())
}import requests
url = "https://api.typecast.ai/v2/voices/{voice_id}"
headers = {"X-API-KEY": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-KEY': '<api-key>'}};
fetch('https://api.typecast.ai/v2/voices/{voice_id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.typecast.ai/v2/voices/{voice_id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-KEY: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.typecast.ai/v2/voices/{voice_id}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-KEY", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.typecast.ai/v2/voices/{voice_id}")
.header("X-API-KEY", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.typecast.ai/v2/voices/{voice_id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-KEY"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"voice_id": "tc_60e5426de8b95f1d3000d7b5",
"voice_name": "Olivia",
"models": [
{
"version": "ssfm-v30",
"emotions": [
"normal",
"happy",
"sad",
"angry",
"whisper",
"toneup",
"tonedown"
]
},
{
"version": "ssfm-v21",
"emotions": [
"normal",
"happy",
"sad",
"angry"
]
}
],
"gender": "female",
"age": "young_adult",
"use_cases": [
"Audiobook",
"E-learning",
"Ads"
],
"voice_type": "original"
}{
"detail": "Invalid API key"
}{
"detail": "Voice not found"
}{
"detail": "Invalid request format"
}Authorizations
API key for authentication. You can obtain an API key from the Typecast API Console.
Path Parameters
Response
Success - Returns detailed information for the requested voice
V2 Voice response model with model-grouped emotions and enhanced metadata
Unique voice identifier. Built-in voices use the tc_ prefix (e.g., tc_60e5426de8b95f1d3000d7b5); cloned custom voices created via POST /v1/voices/clone use the uc_ prefix and are also returned by /v2/voices for the owner.
Human-readable name of the voice
List of supported TTS models with their available emotions (e.g., [{'version': 'ssfm-v21', 'emotions': ['happy', 'sad']}])
Show child attributes
Show child attributes
Voice type — original for Typecast-provided stock voices, custom for user-cloned voices.
original, custom Voice gender classification (male/female)
male, female Voice age group classification (child/teenager/young_adult/middle_age/elder)
child, teenager, young_adult, middle_age, elder List of use case categories this voice is suitable for