Typecast SDK for Python
The official Python SDK for the Typecast Text-to-Speech API
Convert text to lifelike speech using AI-powered voices
Table of Contents
Installation
Python 3.11 through 3.14 is required. Python 3.8, 3.9, and 3.10 are no longer supported because they are end-of-life. The last compatible published releases are 0.3.15 for Python 3.8/3.9 and 0.4.1 for Python 3.10. Upgrade Python and recreate your virtual environment before installing 0.5.1. Temporarily pinning an older release does not restore security support for an EOL runtime.
pip install typecast-python
Quick Start
from typecast import Typecast
from typecast.models import TTSRequest
client = Typecast(api_key="YOUR_API_KEY")
response = client.text_to_speech(TTSRequest(
text="Hello! I'm your friendly text-to-speech assistant.",
model="ssfm-v30",
voice_id="tc_672c5f5ce59fac2a48faeaee"
))
with open("output.wav", "wb") as f:
f.write(response.audio_data)
print(f"Saved: output.wav ({response.duration}s)")
Features
| Feature | Description |
|---|---|
| Multiple Models | Support for ssfm-v21 and ssfm-v30 AI voice models |
| 37 Languages | English, Korean, Japanese, Chinese, Spanish, and 32 more |
| Emotion Control | Preset emotions or smart context-aware inference |
| Audio Customization | Volume, pitch, tempo, and format (WAV/MP3) |
| Voice Discovery | Filter voices by model, gender, age, and use cases |
| Async Support | Built-in async client for high-performance applications |
| Type Hints | Full type annotations with Pydantic models |
Usage
Configuration
from typecast import Typecast
# Using environment variable (recommended)
# export TYPECAST_API_KEY="your-api-key"
client = Typecast()
# Or pass directly
client = Typecast(
api_key="your-api-key",
host="https://api.typecast.ai" # optional
)
Text to Speech
Basic Usage
from typecast.models import TTSRequest
response = client.text_to_speech(TTSRequest(
text="Hello, world!",
voice_id="tc_672c5f5ce59fac2a48faeaee",
model="ssfm-v30"
))
With Audio Options
from typecast.models import TTSRequest, Output
response = client.text_to_speech(TTSRequest(
text="Hello, world!",
voice_id="tc_672c5f5ce59fac2a48faeaee",
model="ssfm-v30",
language="eng",
output=Output(
volume=120, # 0-200 (default: 100)
audio_pitch=2, # -12 to +12 semitones
audio_tempo=1.2, # 0.5x to 2.0x
audio_format="mp3" # "wav" or "mp3"
),
))
Voice Discovery
from typecast.models import VoicesV2Filter, TTSModel, GenderEnum, AgeEnum
# Get all voices (V3 API)
voices = client.voices_v3()
# Filter by criteria
filtered = client.voices_v3(VoicesV2Filter(
model=TTSModel.SSFM_V30,
gender=GenderEnum.FEMALE,
age=AgeEnum.YOUNG_ADULT
))
# Display voice info
print(f"Name: {voices[0].voice_name}")
print(f"Gender: {voices[0].gender}, Age: {voices[0].age}")
print(f"Models: {', '.join(m.version.value for m in voices[0].models)}")
Emotion Control
ssfm-v21: Basic Emotion
from typecast.models import TTSRequest, Prompt
response = client.text_to_speech(TTSRequest(
text="I'm so excited!",
voice_id="tc_62a8975e695ad26f7fb514d1",
model="ssfm-v21",
prompt=Prompt(
emotion_preset="happy", # normal, happy, sad, angry
emotion_intensity=1.5 # 0.0 to 2.0
)
))
ssfm-v30: Preset Mode
from typecast.models import TTSRequest, PresetPrompt, TTSModel
response = client.text_to_speech(TTSRequest(
text="I'm so excited!",
voice_id="tc_672c5f5ce59fac2a48faeaee",
model=TTSModel.SSFM_V30,
prompt=PresetPrompt(
emotion_type="preset",
emotion_preset="happy", # normal, happy, sad, angry, whisper, toneup, tonedown
emotion_intensity=1.5
)
))
ssfm-v30: Smart Mode (Context-Aware)
from typecast.models import TTSRequest, SmartPrompt, TTSModel
response = client.text_to_speech(TTSRequest(
text="Everything is perfect.",
voice_id="tc_672c5f5ce59fac2a48faeaee",
model=TTSModel.SSFM_V30,
prompt=SmartPrompt(
emotion_type="smart",
previous_text="I just got the best news!",
next_text="I can't wait to celebrate!"
)
))
Async Client
import asyncio
from typecast import AsyncTypecast
from typecast.models import TTSRequest
async def main():
async with AsyncTypecast(api_key="YOUR_API_KEY") as client:
response = await client.text_to_speech(TTSRequest(
text="Hello from async!",
model="ssfm-v30",
voice_id="tc_672c5f5ce59fac2a48faeaee"
))
with open("output.wav", "wb") as f:
f.write(response.audio_data)
asyncio.run(main())
Timestamp TTS
Use text_to_speech_with_timestamps() to receive base64 audio plus
word/character-level timestamps aligned with the synthesized speech. The
result object exposes save_audio(), to_srt(), and to_vtt() helpers
so you can finish the typical "audio + subtitles" flow in one line.
from typecast import Typecast
from typecast.models import TTSRequestWithTimestamps
client = Typecast(api_key="YOUR_API_KEY")
resp = client.text_to_speech_with_timestamps(
TTSRequestWithTimestamps(
voice_id="tc_60e5426de8b95f1d3000d7b5",
text="Hello. How are you?",
model="ssfm-v30",
language="eng",
),
)
resp.save_audio("hello.wav")
print(resp.to_srt()) # SRT subtitles
print(resp.to_vtt()) # WebVTT subtitles
Caption splits follow BBC/Netflix subtitle guidelines: 7s/42-char cue maximums.
# Real-time karaoke / highlight: iterate the words array directly.
for w in resp.words or []:
print(f"[{w.start:.2f}s - {w.end:.2f}s] {w.text}")
Pass granularity="word" or granularity="char" to receive only one of
the two alignment arrays. For non-whitespace languages (Japanese,
Chinese), pair with granularity="char" — word-level alignment will
collapse the entire sentence into a single segment.
Instant cloning
Clone a custom voice from a short audio sample (≤ 25 MB), then use it just like any built-in voice. The cloned voice ID has a uc_ prefix and works with text_to_speech directly.
from typecast import Typecast
from typecast.models import TTSRequest
client = Typecast(api_key="YOUR_API_KEY")
# 1) Clone
voice = client.clone_voice(
audio="path/to/sample.wav", # str path | Path | bytes | file object
name="my-voice", # 1-30 chars
model="ssfm-v30", # or "ssfm-v21"
)
print(voice.voice_id) # uc_64a1b2...
# 2) Synthesize with the cloned voice
audio = client.text_to_speech(TTSRequest(
text="Hello from my cloned voice!",
voice_id=voice.voice_id,
model="ssfm-v30",
))
with open("output.wav", "wb") as f:
f.write(audio.audio_data)
# 3) Delete when done
client.delete_voice(voice.voice_id)
Limits
- Audio file: max 25 MB. Supported formats: WAV, MP3.
- Voice name: 1–30 characters.
- Model:
ssfm-v21orssfm-v30.
Async usage is identical via AsyncTypecast:
from typecast import AsyncTypecast
async with AsyncTypecast(api_key="YOUR_API_KEY") as client:
voice = await client.clone_voice(audio="sample.wav", name="my-voice", model="ssfm-v30")
await client.delete_voice(voice.voice_id)
Supported Languages
View all 37 supported languages
| Code | Language | Code | Language | Code | Language |
|---|---|---|---|---|---|
eng |
English | jpn |
Japanese | ukr |
Ukrainian |
kor |
Korean | ell |
Greek | ind |
Indonesian |
spa |
Spanish | tam |
Tamil | dan |
Danish |
deu |
German | tgl |
Tagalog | swe |
Swedish |
fra |
French | fin |
Finnish | msa |
Malay |
ita |
Italian | zho |
Chinese | ces |
Czech |
pol |
Polish | slk |
Slovak | por |
Portuguese |
nld |
Dutch | ara |
Arabic | bul |
Bulgarian |
rus |
Russian | hrv |
Croatian | ron |
Romanian |
ben |
Bengali | hin |
Hindi | hun |
Hungarian |
nan |
Hokkien | nor |
Norwegian | pan |
Punjabi |
tha |
Thai | tur |
Turkish | vie |
Vietnamese |
yue |
Cantonese |
from typecast.models import LanguageCode
# Auto-detect (recommended)
response = client.text_to_speech(TTSRequest(
text="こんにちは",
voice_id="...",
model="ssfm-v30"
))
# Explicit language
response = client.text_to_speech(TTSRequest(
text="안녕하세요",
voice_id="...",
model="ssfm-v30",
language=LanguageCode.KOR
))
Error Handling
from typecast import (
Typecast,
TypecastError,
BadRequestError,
UnauthorizedError,
PaymentRequiredError,
NotFoundError,
UnprocessableEntityError,
RateLimitError,
InternalServerError,
)
try:
response = client.text_to_speech(request)
except UnauthorizedError:
print("Invalid API key")
except PaymentRequiredError:
print("Insufficient credits")
except RateLimitError:
print("Rate limit exceeded - please retry later")
except TypecastError as e:
print(f"Error {e.status_code}: {e.message}")
| Exception | Status Code | Description |
|---|---|---|
BadRequestError |
400 | Invalid request parameters |
UnauthorizedError |
401 | Invalid or missing API key |
PaymentRequiredError |
402 | Insufficient credits |
NotFoundError |
404 | Resource not found |
UnprocessableEntityError |
422 | Validation error |
RateLimitError |
429 | Rate limit exceeded |
InternalServerError |
500 | Server error |
License
Metadata
Release files for typecast-python 0.5.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| typecast_python-0.5.1.tar.gz | 30.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| typecast_python-0.5.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 70.9 kB
Release files / typecast_python-0.5.1.tar.gz
| Download URL | typecast_python-0.5.1.tar.gz |
|---|---|
| Size | 30.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
89e23962a1f72800c12a9df32cc86420a0b935ea1d27834a86a38aa358f45d3f
|
|
BLAKE2b-256 checksum How to use checksums |
65244be7b08423187404ce8e1a9ca4d0d66ce91e3772b3951a94fd01f9a9174e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / typecast_python-0.5.1-py3-none-any.whl
| Download URL | typecast_python-0.5.1-py3-none-any.whl |
|---|---|
| Size | 40.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
38bce70497404e47d101841e7d92c4ae4699a6a46d816569c23e113dec46d29e
|
|
BLAKE2b-256 checksum How to use checksums |
8fbba682adfeb1865fbfe63c0d204c180a0316675b4ed4830813d4fd11f15078
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|