The official Java library for the Typecast API. Convert text to lifelike speech using AI-powered voices.
Compatible with Java 8 and later versions. Works with Maven, Gradle, and manual installation.
Installation
Add the following dependency to your pom.xml:
<dependency>
<groupId>com.neosapience</groupId>
<artifactId>typecast-java</artifactId>
<version>1.2.8</version>
</dependency>
Quick Start
import com.neosapience.TypecastClient;
import com.neosapience.models.*;
import java.io.FileOutputStream;
public class QuickStart {
public static void main(String[] args) throws Exception {
// Initialize client
TypecastClient client = new TypecastClient("YOUR_API_KEY");
// Convert text to speech
TTSRequest request = TTSRequest.builder()
.voiceId("tc_672c5f5ce59fac2a48faeaee") // Find voice IDs at https://studio.typecast.ai/developers/api/voices
.text("Hello there! I'm your friendly text-to-speech agent.")
.model(TTSModel.SSFM_V30)
.build();
TTSResponse response = client.textToSpeech(request);
// Save audio file
try (FileOutputStream fos = new FileOutputStream("output." + response.getFormat())) {
fos.write(response.getAudioData());
}
System.out.println("Audio saved! Duration: " + response.getDuration() + "s, Format: " + response.getFormat());
// Clean up
client.close();
}
}
Features
The Typecast Java SDK provides powerful features for text-to-speech conversion:
- Multiple Voice Models: Support for
ssfm-v30(latest) andssfm-v21AI 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
- Instant Voice Cloning: Upload a WAV/MP3 sample and create a custom voice ID
- Timestamp TTS: Word- and character-level alignment data for subtitles, karaoke, and lip-sync
- Builder Pattern: Fluent API with builder pattern for easy request construction
- Comprehensive Error Handling: Specific exception classes for each error type
- Streaming: Real-time chunked audio delivery for low-latency playback
Voice Recommendations
Use recommendVoices when you know the desired style but not the exact voice_id.
List<RecommendedVoice> voices = client.recommendVoices(
"warm female voice for a product tutorial",
3
);
for (RecommendedVoice voice : voices) {
System.out.println(voice.getVoiceId() + " " + voice.getVoiceName() + " " + voice.getScore());
}
Recommendation results contain only voiceId, voiceName, and score. Use getVoiceV2 or getVoicesV2 when you need detailed metadata such as supported models, emotions, gender, age, or use cases.
Configuration
Set your API key via environment variable, .env file, or constructor:
// Using environment variable
// export TYPECAST_API_KEY="your-api-key-here"
TypecastClient client = new TypecastClient();
// Or pass directly
TypecastClient client = new TypecastClient("your-api-key-here");
// Or with custom base URL
TypecastClient client = new TypecastClient("your-api-key-here", "https://custom-api.example.com");
TypecastClient client = new TypecastClient(null, "https://your-proxy.example.com");
Environment File
Create a .env file in your project root:
TYPECAST_API_KEY=your-api-key-here
Advanced Usage
Emotion Control (ssfm-v30)
ssfm-v30 offers two emotion control modes: Preset and Smart.
Let the AI infer emotion from context:
TTSRequest request = TTSRequest.builder()
.voiceId("tc_672c5f5ce59fac2a48faeaee")
.text("Everything is going to be okay.")
.model(TTSModel.SSFM_V30)
.prompt(SmartPrompt.builder()
.previousText("I just got the best news!") // Optional context
.nextText("I can't wait to celebrate!") // Optional context
.build())
.build();
TTSResponse response = client.textToSpeech(request);
Audio Customization
Control loudness, pitch, tempo, and output format:
TTSRequest request = TTSRequest.builder()
.voiceId("tc_672c5f5ce59fac2a48faeaee")
.text("Customized audio output!")
.model(TTSModel.SSFM_V30)
.output(Output.builder()
.targetLufs(-14.0) // Range: -70 to 0 (LUFS)
.audioPitch(2) // Range: -12 to +12 semitones
.audioTempo(1.2) // Range: 0.5x to 2.0x
.audioFormat(AudioFormat.MP3) // Options: WAV, MP3
.build())
.seed(42) // Non-negative seed for reproducible results
.build();
TTSResponse response = client.textToSpeech(request);
try (FileOutputStream fos = new FileOutputStream("output." + response.getFormat())) {
fos.write(response.getAudioData());
}
System.out.println("Duration: " + response.getDuration() + "s, Format: " + response.getFormat());
Generate audio to a file
Use generateToFile when you want the SDK to synthesize speech and write the audio bytes directly to a local file. The model defaults to ssfm-v30, and .mp3 / .wav extensions infer the output format when Output.audioFormat is not set. Browse available voice IDs on the Voices page.
client.generateToFile("output.mp3", GenerateToFileRequest.builder()
.text("Hello from Typecast.")
.voiceId("tc_672c5f5ce59fac2a48faeaee") // Find voice IDs at https://studio.typecast.ai/developers/api/voices
.build());
Text pauses
Use text pause markup when you only need silent gaps inside one composed text segment. Put <|5s|>, <|1s|>, <|0.3s|>, or <|0.34413s|> directly in the text. The value is interpreted as seconds and must end with s. This keeps the pause expression visible in plain text without adding separate pause calls.
TTSResponse audio = client.composeSpeech()
.defaults(new ComposerSettings().voiceId("tc_672c5f5ce59fac2a48faeaee").model(TTSModel.SSFM_V30))
.say("Hello<|5s|>Nice to meet you<|1s|>Today<|2s|>how does the weather feel?")
.generate();
Multi-speaker composition
Use the composer chaining API when one output file needs different voices or per-segment options such as pitch, tempo, prompt, or seed. The composer generates each segment as WAV, trims leading/trailing silent PCM samples, and concatenates the result. If you need MP3, generate WAV first and convert it in your app or server pipeline.
TypecastClient client = new TypecastClient("YOUR_API_KEY");
TTSResponse audio = client.composeSpeech()
.defaults(new ComposerSettings().setVoiceId("tc_672c5f5ce59fac2a48faeaee").setModel(TTSModel.SSFM_V30))
.say("Hello there")
.pause(5)
.say("Nice to meet you", new ComposerSettings()
.setVoiceId("tc_60e5426de8b95f1d3000d7b5")
.setOutput(Output.builder().volume(null).audioPitch(2).build()))
.say("Today")
.pause(2)
.say("How does the weather feel?")
.generate();
Files.write(Path.of("conversation.wav"), audio.getAudioData());
Voice Discovery (V2 API)
List and filter available voices with enhanced metadata:
// Get all voices
List<VoiceV2Response> voices = client.getVoicesV2();
// Filter by criteria
VoicesV2Filter filter = VoicesV2Filter.builder()
.model(TTSModel.SSFM_V30)
.gender(GenderEnum.FEMALE)
.age(AgeEnum.YOUNG_ADULT)
.build();
List<VoiceV2Response> filtered = client.getVoicesV2(filter);
// Display voice info
for (VoiceV2Response voice : voices) {
System.out.println("ID: " + voice.getVoiceId() + ", Name: " + voice.getVoiceName());
System.out.println("Gender: " + voice.getGender() + ", Age: " + voice.getAge());
for (ModelInfo model : voice.getModels()) {
System.out.println("Model: " + model.getVersion() + ", Emotions: " + model.getEmotions());
}
if (voice.getUseCases() != null) {
System.out.println("Use cases: " + String.join(", ", voice.getUseCases()));
}
}
Multilingual Content
The SDK supports 37 languages with automatic language detection:
// Auto-detect language (recommended)
TTSRequest request = TTSRequest.builder()
.voiceId("tc_672c5f5ce59fac2a48faeaee")
.text("こんにちは。お元気ですか。")
.model(TTSModel.SSFM_V30)
.build();
TTSResponse response = client.textToSpeech(request);
// Or specify language explicitly
TTSRequest koreanRequest = TTSRequest.builder()
.voiceId("tc_672c5f5ce59fac2a48faeaee")
.text("안녕하세요. 반갑습니다.")
.model(TTSModel.SSFM_V30)
.language(LanguageCode.KOR) // ISO 639-3 language code
.build();
TTSResponse koreanResponse = client.textToSpeech(koreanRequest);
try (FileOutputStream fos = new FileOutputStream("output." + response.getFormat())) {
fos.write(response.getAudioData());
}
Streaming
Stream audio chunks in real-time for low-latency playback:
import javax.sound.sampled.*;
// Set up audio playback: 32000 Hz, 16-bit, mono, little-endian
AudioFormat format = new AudioFormat(32000, 16, 1, true, false);
SourceDataLine line = AudioSystem.getSourceDataLine(format);
line.open(format, 8192);
line.start();
try (InputStream stream = client.textToSpeechStream(request)) {
byte[] buf = new byte[4096];
boolean first = true;
int bytesRead;
while ((bytesRead = stream.read(buf)) != -1) {
int offset = 0;
if (first) {
offset = 44; // Skip 44-byte WAV header
bytesRead -= 44;
first = false;
}
line.write(buf, offset, bytesRead);
}
}
line.drain();
line.close();
client.close();
Timestamp TTS
textToSpeechWithTimestamps() wraps POST /v1/text-to-speech/with-timestamps and returns the audio together with per-word and per-character alignment data - useful for karaoke highlights, subtitle generation, and lip-sync applications.
Basic Usage
import com.neosapience.TypecastClient;
import com.neosapience.models.*;
import java.io.FileOutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
TypecastClient client = new TypecastClient("YOUR_API_KEY");
TTSRequestWithTimestamps request = TTSRequestWithTimestamps.builder()
.voiceId("tc_60e5426de8b95f1d3000d7b5")
.text("Hello. How are you?")
.model(TTSModel.SSFM_V30)
.build();
TTSWithTimestampsResponse result = client.textToSpeechWithTimestamps(request);
Files.write(Paths.get("output.wav"), result.getAudioBytes());
System.out.printf("Duration: %.3fs%n", result.getAudioDuration());
for (WordAlignment word : result.getWords()) {
System.out.printf(" [%.3fs – %.3fs] %s%n",
word.getStartTime(), word.getEndTime(), word.getText());
}
client.close();
Granularity
Pass .granularity(Granularity.WORD) (default) or .granularity(Granularity.CHAR) to control the alignment unit.
TTSRequestWithTimestamps request = TTSRequestWithTimestamps.builder()
.voiceId("tc_60e5426de8b95f1d3000d7b5")
.text("Hello. How are you?")
.model(TTSModel.SSFM_V30)
.granularity(Granularity.CHAR) // required for Japanese / Chinese
.build();
Subtitle Export
// Export SRT captions
String srt = result.toSrt();
Files.writeString(Paths.get("output.srt"), srt);
// Export WebVTT captions
String vtt = result.toVtt();
Files.writeString(Paths.get("output.vtt"), vtt);
Instant Voice Cloning
Clone a custom voice from a short audio sample, then pass the returned uc_ voice ID directly to TTS.
import com.neosapience.TypecastClient;
import com.neosapience.models.*;
import java.io.File;
TypecastClient client = new TypecastClient("YOUR_API_KEY");
CustomVoice voice = client.cloneVoice(
new File("sample.wav"),
"My Voice",
"ssfm-v30"
);
TTSRequest request = TTSRequest.builder()
.voiceId(voice.getVoiceId())
.text("Hello from my cloned voice!")
.model(TTSModel.SSFM_V30)
.build();
TTSResponse response = client.textToSpeech(request);
client.deleteVoice(voice.getVoiceId());
client.close();
Supported Languages
The SDK supports 37 languages with automatic language detection:
| 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 |
Error Handling
The SDK provides specific exception classes for handling API errors:
import com.neosapience.TypecastClient;
import com.neosapience.exceptions.*;
try {
TTSResponse response = client.textToSpeech(request);
} catch (UnauthorizedException e) {
// 401: Invalid API key
System.err.println("Invalid API key: " + e.getMessage());
} catch (PaymentRequiredException e) {
// 402: Insufficient credits
System.err.println("Insufficient credits: " + e.getMessage());
} catch (ForbiddenException e) {
// 403: Access denied
System.err.println("Access denied: " + e.getMessage());
} catch (NotFoundException e) {
// 404: Resource not found
System.err.println("Voice not found: " + e.getMessage());
} catch (UnprocessableEntityException e) {
// 422: Validation error
System.err.println("Validation error: " + e.getMessage());
} catch (RateLimitException e) {
// 429: Rate limit exceeded
System.err.println("Rate limit exceeded - please retry later");
} catch (InternalServerException e) {
// 500: Server error
System.err.println("Server error: " + e.getMessage());
} catch (TypecastException e) {
// Generic error
System.err.println("API error (" + e.getStatusCode() + "): " + e.getMessage());
}
Exception Hierarchy
| Exception | Status Code | Description |
|---|---|---|
BadRequestException | 400 | Invalid request parameters |
UnauthorizedException | 401 | Invalid or missing API key |
PaymentRequiredException | 402 | Insufficient credits |
ForbiddenException | 403 | Access denied |
NotFoundException | 404 | Resource not found |
UnprocessableEntityException | 422 | Validation error |
RateLimitException | 429 | Rate limit exceeded |
InternalServerException | 500 | Server error |
TypecastException | * | Base exception class |
Eclipse IDE Setup
Import Project - Open Eclipse
- Go to
File→Import... - Select
Maven→Existing Maven Projects - Browse to the
typecast-javadirectory - Click
Finish
Add Dependency Add to your project's
pom.xml:<dependency> <groupId>com.neosapience</groupId> <artifactId>typecast-java</artifactId> <version>1.2.8</version> </dependency>Update Project Right-click on your project →
Maven→Update Project...
IntelliJ IDEA Setup
Import Project - Open IntelliJ IDEA
- Go to
File→Open... - Select the
typecast-javadirectory - Select "Open as Project"
Add Dependency IntelliJ will automatically detect the
pom.xmland import dependencies.Or add to your project's
pom.xml:<dependency> <groupId>com.neosapience</groupId> <artifactId>typecast-java</artifactId> <version>1.2.8</version> </dependency>Reload Maven Click the Maven refresh button or right-click
pom.xml→Maven→Reload Project
API Reference
TypecastClient Methods
| Method | Description |
|---|---|
textToSpeech(TTSRequest) | Convert text to speech audio |
generateToFile(String, GenerateToFileRequest) | Generate speech and save it directly to a local file |
cloneVoice(byte[], filename, name, model) | Create a custom voice via instant cloning |
cloneVoice(File, name, model) | Create a custom voice from a local audio file |
deleteVoice(String voiceId) | Delete a custom cloned voice |
getVoicesV2() | Get all available voices |
getVoicesV2(VoicesV2Filter) | Get filtered voices |
getVoiceV2(String voiceId) | Get a specific voice by ID |
close() | Release resources |
TTSRequest Fields
| Field | Type | Required | Description |
|---|---|---|---|
voiceId | String | ✓ | Voice ID (format: tc_* or uc_*) |
text | String | ✓ | Text to synthesize (max 5000 chars) |
model | TTSModel | ✓ | TTS model (SSFM_V21 or SSFM_V30) |
language | LanguageCode | ISO 639-3 code (auto-detected if omitted) | |
prompt | Prompt / PresetPrompt / SmartPrompt | Emotion settings | |
output | Output | Audio output settings | |
seed | Integer | Non-negative integer seed for reproducibility (≥ 0) |
TTSResponse Fields
| Field | Type | Description |
|---|---|---|
audioData | byte[] | Generated audio data |
duration | double | Audio duration in seconds |
format | String | Audio format (wav or mp3) |