The official Rust library for the Typecast API . Convert text to lifelike speech using AI-powered voices.
Built with async/await support using Tokio runtime. Works with Cargo package manager.
Crates.io Typecast Rust SDK
Source Code Typecast Rust SDK Source Code
Installation
Add the following to your Cargo.toml:
[ dependencies ]
typecast-rust = "0.1.1"
tokio = { version = "1" , features = [ "full" ] }
Or use Cargo to add the dependency:
cargo add typecast-rust tokio --features tokio/full
Make sure you have version 0.1.1 or higher installed. Check your Cargo.toml if you need to update.
Quick Start
use typecast_rust :: { TypecastClient , TTSRequest , TTSModel };
use std :: fs;
#[tokio :: main]
async fn main () -> Result <(), Box < dyn std :: error :: Error >> {
// Initialize client (reads TYPECAST_API_KEY from environment)
let client = TypecastClient :: from_env () ? ;
// Convert text to speech
let request = TTSRequest :: new (
"tc_672c5f5ce59fac2a48faeaee" ,
"Hello there! I'm your friendly text-to-speech agent." ,
TTSModel :: SsfmV30 ,
);
let response = client . text_to_speech ( & request ) . await ? ;
// Save audio file
fs :: write ( "output.wav" , & response . audio_data) ? ;
println! (
"Audio saved! Duration: {:.2}s, Format: {:?}" ,
response . duration, response . format
);
Ok (())
}
Features
The Typecast Rust SDK provides powerful features for text-to-speech conversion:
Multiple Voice Models : Support for ssfm-v30 (latest) and ssfm-v21 AI voice models
Multi-language Support : 37 languages including English, Korean, Spanish, Japanese, Chinese, and more
Emotion Control : Preset emotions (normal, happy, sad, angry, whisper, toneup, tonedown) or smart context-aware inference
Audio Customization : Control loudness (LUFS -70 to 0), pitch (-12 to +12 semitones), tempo (0.5x to 2.0x), and format (WAV/MP3)
Voice Discovery : V2 Voices API with filtering by model, gender, age, and use cases
Builder Pattern : Fluent API with method chaining for easy request construction
Async/Await : Built on Tokio for efficient asynchronous operations
Comprehensive Error Handling : Typed error enum with pattern matching support
Configuration
Set your API key via environment variable or constructor:
use typecast_rust :: { TypecastClient , ClientConfig };
use std :: time :: Duration ;
// Using environment variable (recommended)
// export TYPECAST_API_KEY="your-api-key-here"
let client = TypecastClient :: from_env () ? ;
// Or pass directly
let client = TypecastClient :: with_api_key ( "your-api-key-here" ) ? ;
// Or with custom configuration
let config = ClientConfig :: new ( "your-api-key-here" )
. base_url ( "https://api.typecast.ai" )
. timeout ( Duration :: from_secs ( 120 ));
let client = TypecastClient :: new ( config ) ? ;
Environment File
Create a .env file in your project root:
TYPECAST_API_KEY = your-api-key-here
Use the dotenvy crate to load environment variables from .env files.
Advanced Usage
Emotion Control (ssfm-v30)
ssfm-v30 offers two emotion control modes: Preset and Smart .
Let the AI infer emotion from context: use typecast_rust :: { TTSRequest , TTSModel , SmartPrompt };
let request = TTSRequest :: new (
"tc_672c5f5ce59fac2a48faeaee" ,
"Everything is going to be okay." ,
TTSModel :: SsfmV30 ,
)
. prompt (
SmartPrompt :: new ()
. previous_text ( "I just got the best news!" ) // Optional context
. next_text ( "I can't wait to celebrate!" ) // Optional context
);
let response = client . text_to_speech ( & request ) . await ? ;
Explicitly set emotion with preset values: use typecast_rust :: { TTSRequest , TTSModel , PresetPrompt , EmotionPreset };
let request = TTSRequest :: new (
"tc_672c5f5ce59fac2a48faeaee" ,
"I am so excited to show you these features!" ,
TTSModel :: SsfmV30 ,
)
. prompt (
PresetPrompt :: new ()
. emotion_preset ( EmotionPreset :: Happy ) // Normal, Happy, Sad, Angry, Whisper, ToneUp, ToneDown
. emotion_intensity ( 1.5 ) // Range: 0.0 to 2.0
);
let response = client . text_to_speech ( & request ) . await ? ;
Audio Customization
Control loudness, pitch, tempo, and output format:
use typecast_rust :: { TTSRequest , TTSModel , Output , AudioFormat };
let request = TTSRequest :: new (
"tc_672c5f5ce59fac2a48faeaee" ,
"Customized audio output!" ,
TTSModel :: SsfmV30 ,
)
. output (
Output :: new ()
. target_lufs ( - 14.0 ) // Range: -70 to 0 (LUFS)
. audio_pitch ( 2 ) // Range: -12 to +12 semitones
. audio_tempo ( 1.2 ) // Range: 0.5x to 2.0x
. audio_format ( AudioFormat :: Mp3 ) // Options: Wav, Mp3
)
. seed ( 42 ); // For reproducible results
let response = client . text_to_speech ( & request ) . await ? ;
fs :: write ( "output.mp3" , & response . audio_data) ? ;
println! ( "Duration: {:.2}s, Format: {:?}" , response . duration, response . format);
Voice Discovery (V2 API)
List and filter available voices with enhanced metadata:
use typecast_rust :: { TypecastClient , VoicesV2Filter , TTSModel , Gender , Age };
// Get all voices
let voices = client . get_voices_v2 ( None ) . await ? ;
// Filter by criteria
let filter = VoicesV2Filter :: new ()
. model ( TTSModel :: SsfmV30 )
. gender ( Gender :: Female )
. age ( Age :: YoungAdult );
let filtered = client . get_voices_v2 ( Some ( filter )) . await ? ;
// Display voice info
for voice in & voices {
println! ( "ID: {}, Name: {}" , voice . voice_id, voice . voice_name);
println! ( "Gender: {:?}, Age: {:?}" , voice . gender, voice . age);
for model in & voice . models {
println! ( "Model: {:?}, Emotions: {:?}" , model . version, model . emotions);
}
if let Some ( use_cases ) = & voice . use_cases {
println! ( "Use cases: {}" , use_cases . join ( ", " ));
}
}
// Get a specific voice by ID
let voice = client . get_voice_v2 ( "tc_672c5f5ce59fac2a48faeaee" ) . await ? ;
println! ( "Voice: {} ({:?})" , voice . voice_name, voice . gender);
Multilingual Content
The SDK supports 37 languages with automatic language detection:
// Auto-detect language (recommended)
let request = TTSRequest :: new (
"tc_672c5f5ce59fac2a48faeaee" ,
"こんにちは。お元気ですか。" ,
TTSModel :: SsfmV30 ,
);
let response = client . text_to_speech ( & request ) . await ? ;
// Or specify language explicitly
let korean_request = TTSRequest :: new (
"tc_672c5f5ce59fac2a48faeaee" ,
"안녕하세요. 반갑습니다." ,
TTSModel :: SsfmV30 ,
)
. language ( "kor" ); // ISO 639-3 language code
let korean_response = client . text_to_speech ( & korean_request ) . await ? ;
Supported Languages
The SDK supports 37 languages with automatic language detection:
Code Language Code Language Code Language engEnglish jpnJapanese ukrUkrainian korKorean ellGreek indIndonesian spaSpanish tamTamil danDanish deuGerman tglTagalog sweSwedish fraFrench finFinnish msaMalay itaItalian zhoChinese cesCzech polPolish slkSlovak porPortuguese nldDutch araArabic bulBulgarian rusRussian hrvCroatian ronRomanian benBengali hinHindi hunHungarian nanHokkien norNorwegian panPunjabi thaThai turTurkish vieVietnamese yueCantonese
If not specified, the language will be automatically detected from the input text.
Error Handling
The SDK provides a typed error enum for handling API errors with pattern matching:
use typecast_rust :: { TypecastClient , TTSRequest , TTSModel , TypecastError };
let request = TTSRequest :: new ( "voice_id" , "Hello" , TTSModel :: SsfmV30 );
match client . text_to_speech ( & request ) . await {
Ok ( response ) => {
println! ( "Success! Duration: {:.2}s" , response . duration);
}
Err ( TypecastError :: Unauthorized { detail }) => {
// 401: Invalid API key
eprintln! ( "Invalid API key: {}" , detail );
}
Err ( TypecastError :: PaymentRequired { detail }) => {
// 402: Insufficient credits
eprintln! ( "Insufficient credits: {}" , detail );
}
Err ( TypecastError :: NotFound { detail }) => {
// 404: Resource not found
eprintln! ( "Voice not found: {}" , detail );
}
Err ( TypecastError :: RateLimited { detail }) => {
// 429: Rate limit exceeded
eprintln! ( "Rate limit exceeded - please retry later: {}" , detail );
}
Err ( TypecastError :: ServerError { detail }) => {
// 500: Server error
eprintln! ( "Server error: {}" , detail );
}
Err ( e ) => {
eprintln! ( "Error: {}" , e );
}
}
Error Types
Error Variant Status Code Description BadRequest400 Invalid request parameters Unauthorized401 Invalid or missing API key PaymentRequired402 Insufficient credits Forbidden403 Access denied NotFound404 Resource not found ValidationError422 Validation error RateLimited429 Rate limit exceeded ServerError500 Server error HttpError- HTTP client error JsonError- JSON serialization error
Helper Methods
if let Err ( e ) = result {
if e . is_unauthorized () {
println! ( "Check your API key" );
} else if e . is_rate_limited () {
println! ( "Wait and retry" );
} else if e . is_server_error () {
println! ( "Server issue, try again later" );
}
if let Some ( code ) = e . status_code () {
println! ( "HTTP status: {}" , code );
}
}
API Reference
TypecastClient Methods
Method Description from_env()Create client from environment variables with_api_key(key)Create client with API key new(config)Create client with custom configuration text_to_speech(&request)Convert text to speech audio get_voices_v2(filter)Get available voices with optional filter get_voice_v2(voice_id)Get a specific voice by ID
TTSRequest Fields
Field Type Required Description voice_idString✓ Voice ID (format: tc_* or uc_*) textString✓ Text to synthesize (max 2000 chars) modelTTSModel✓ TTS model (SsfmV21 or SsfmV30) languageOption<String>ISO 639-3 code (auto-detected if omitted) promptOption<TTSPrompt>Emotion settings (Prompt/PresetPrompt/SmartPrompt) outputOption<Output>Audio output settings seedOption<i32>Random seed for reproducibility
TTSResponse Fields
Field Type Description audio_dataVec<u8>Generated audio data durationf64Audio duration in seconds formatAudioFormatAudio format (Wav or Mp3)
Complete Example
use typecast_rust :: {
TypecastClient , TTSRequest , TTSModel , PresetPrompt ,
EmotionPreset , Output , AudioFormat , VoicesV2Filter , Gender ,
};
use std :: fs;
use std :: error :: Error ;
#[tokio :: main]
async fn main () -> Result <(), Box < dyn Error >> {
// Initialize client
let client = TypecastClient :: from_env () ? ;
// Discover voices
let filter = VoicesV2Filter :: new ()
. model ( TTSModel :: SsfmV30 )
. gender ( Gender :: Female );
let voices = client . get_voices_v2 ( Some ( filter )) . await ? ;
println! ( "Found {} female voices" , voices . len ());
// Use first voice
if let Some ( voice ) = voices . first () {
let request = TTSRequest :: new (
& voice . voice_id,
"Welcome to Typecast! This is a demonstration of our text-to-speech API." ,
TTSModel :: SsfmV30 ,
)
. language ( "eng" )
. prompt (
PresetPrompt :: new ()
. emotion_preset ( EmotionPreset :: Happy )
. emotion_intensity ( 1.2 )
)
. output (
Output :: new ()
. target_lufs ( - 14.0 )
. audio_format ( AudioFormat :: Mp3 )
);
let response = client . text_to_speech ( & request ) . await ? ;
fs :: write ( "welcome.mp3" , & response . audio_data) ? ;
println! ( "Saved welcome.mp3 ({:.2}s)" , response . duration);
}
Ok (())
}