详细内容

reCAPTCHA
Recaptcha requires verification.
protected by reCAPTCHA
reCAPTCHA is changing its terms of service. Take action.
Fast & Affordable Text-to-Speech API
11x cheaper than Eleven Labs
Stream audio in 300ms
Request up to 10-hour audio
Includes per-word timestamps
Get a Free API Key →
Live Demo
Non-Fiction
Fiction
News
Blog
Conversation
Amid the intricate labyrinth of human neurons lies a molecule that has confounded and fascinated scientists for ages: the neurotransmitter known as dopamine. Often heralded as the pleasure molecule, dopamine's role is far more nuanced than just mediating euphoria.
0/250
Voice
Sierra
Autumn
Melody
Hannah
Emily
Ivy
Kaitlyn
Luna
Willow
Lauren
Sierra
Noah
Jasper
Caleb
Ronan
Ethan
Daniel
Zane
Rowan
Language
🇺🇸 US English
🇺🇸 US English
🇬🇧 UK English
🇨🇳 Mandarin Chinese
🇮🇳 Hindi
🇪🇸 Spanish
🇧🇷 Portuguese
🇯🇵 Japanese
🇫🇷 French
🇮🇹 Italian
Format
Standard
Standard
MP3
Phone Call
PCM µ-law
Normal
Speed
1.0
Pitch
Bitrate
192k
192k
128k
96k
64k
48k
32k
16k
Synthesize
Speed
0 s
Filesize
0 kb
Per-word Timestamps
Highlight words in sync with the speech.
Ourmodelachieves28.4BLEUontheWMT2014English-to-Germantranslationtask,improvingovertheexistingbestresults,includingensemblesbyover2BLEU.
How To Get Timestamps
NEW: Use a websocket connection to stream both audio and timestamps using /streamWithTimestamps
Use /speech or /synthesisTasks with
TimestampType set to word or sentence (see docs).
The response will have a TimestampsUri containing JSON like this:
[\
{\
"word": "Our",\
"start": 0.5,\
"end": 0.6666666666666667,\
"text_offset": 0\
},\
{\
"word": "model",\
"start": 0.6666666666666667,\
"end": 1.075,\
"text_offset": 4\
},\
{\
"word": "achieves",\
"start": 1.075,\
"end": 1.5166666666666666,\
"text_offset": 10\
},\
...\
]
The more you use it, the cheaper it gets
Start for free. Stay for discounts.
| Number of Characters<br>Per month | 625M |
| Audio Duration<br>Estimated | ~14K hours |
| Enterprise Plan<br>Includes 625M characters | $4999<br>a month<br>High Volume Inquiry |
| Additional Usage<br>$8 per 1M characters | — |
Comparison
vs
Amazon
Amazon
Microsoft
Google

ElevenLabs

Play.ht
$4999
a month
$10.0K
a month
Scarlett
Scarlett
Dan
Score
Fiction
4.72
Non-Fiction
4.37
Conversation
3.91
Neural
Neural
Standard
Score
Fiction
3.00
Non-Fiction
2.51
Conversation
2.63
Price Comparison
Unreal
ElevenLabs
Amazon
Microsoft
Calculated using public prices. Custom plans may be cheaper.
\* 1 minute of audio = roughly 750 characters (~150 WPM)
Get Started for Free →
Need a custom solution? Contact
us
"Unreal Speech saved us 75% on our text-to-speech cost. It sounds better than Amazon Polly, and is much
cheaper. We switched over at high volumes, and often processing 10,000+ pages per hour. Unreal was able to
handle the volume, while delivering a high quality listening experience."

Derek Pankaew — CEO,\
Listening.com
7B
Characters per month
0.3s
Latency
99.9%
Uptime
Code Samples
Get started quickly with our simple text-to-speech API.
/stream
/speech
/synthesisTasks
/streamWithTimestamps
Python
Python
Node.js
React Native
Bash
Copy
# Endpoint: /stream
# - Convert up to 1,000 characters ASAP
# - Synchronous, instant response (0.3s)
# - Streams back raw audio data (no timestamps)
import requests
response = requests.post(
'https://api.v8.unrealspeech.com/stream',
headers = {
'Authorization' : 'Bearer YOUR_API_KEY'
},
json = {
'Text': '''<YOUR_TEXT>''', # Up to 1,000 characters
'VoiceId': '<VOICE_ID>', # af, af_bella, af_sarah, am_adam, am_michael, bf_emma, bf_isabella, bm_george, bm_lewis, af_nicole, af_sky
'Bitrate': '192k', # 320k, 256k, 192k, ...
'Speed': '0', # -1.0 to 1.0
'Pitch': '1', # 0.5 to 1.5
'Codec': 'libmp3lame', # libmp3lame or pcm_mulaw
}
)
with open('audio.mp3', 'wb') as f:
f.write(response.content)
# Endpoint: /speech
# - Up to 3,000 characters
# - Synchronous, takes ~1s per 700 chars
# - Returns MP3 and JSON timestamp URLs
import requests
response = requests.post(
'https://api.v8.unrealspeech.com/speech',
headers = {
'Authorization' : 'Bearer YOUR_API_KEY'
},
json = {
'Text': '''<YOUR_TEXT>''', # Up to 3,000 characters
'VoiceId': '<VOICE_ID>', # Scarlett, Dan, Liv, Will, Amy
'Bitrate': '192k', # 320k, 256k, 192k, ...
'Speed': '0', # -1.0 to 1.0
'Pitch': '1', # 0.5 to 1.5
'TimestampType': 'sentence' # word or sentence
}
)
print(response.json())
# Endpoint: /synthesisTasks
# - Up to 500,000 characters
# - Asynchronous, takes ~1s per 800 chars
# - Returns a TaskId (use it to check status)
import requests
response = requests.post(
'https://api.v8.unrealspeech.com/synthesisTasks',
headers = {
'Authorization' : 'Bearer YOUR_API_KEY'
},
json = {
'Text': '''<YOUR_TEXT>''', # Up to 500,000 characters
'VoiceId': '<VOICE_ID>', # Scarlett, Dan, Liv, Will, Amy
'Bitrate': '192k', # 320k, 256k, 192k, ...
'Speed': '0', # -1.0 to 1.0
'Pitch': '1', # 0.5 to 1.5
'TimestampType': 'sentence', # word or sentence
#'CallbackUrl': '<URL>', # pinged when ready
}
)
print(response.json())
# Endpoint: /streamWithTimestamps
# - Convert text with real-time word-level timestamps
# - Streams audio with precise word timing information
# - Perfect for word-by-word highlighting
import websocket
import json
audio_chunks = []
timestamps = []
def on_message(ws, message):
try:
data = json.loads(message)
if data.get("type") == "progress" and "message" in data:
msg_val = data["message"]
if isinstance(msg_val, list):
timestamps.extend(msg_val)
elif data.get("type") == "complete":
ws.close()
except Exception:
# Assume binary audio data
audio_chunks.append(message)
def on_open(ws):
config = {
"Text": "<YOUR_TEXT>",
"VoiceId": "<VOICE_ID>",
"Model": "kokoro",
"Codec": "libmp3lame",
"SampleRate": 24000,
"Speed": 0,
"Bitrate": "192k",
"Pitch": 1.0,
"TimestampType": "word"
}
ws.send(json.dumps(config))
ws = websocket.WebSocketApp(
"wss://api.v8.unrealspeech.com/streamWithTimestamps",
on_open=on_open,
on_message=on_message
)
ws.run_forever()
// Endpoint: streamWithTimestamps (WebSocket)
# - Convert text with real-time word-level timestamps
# - Streams audio with precise word timing information
# - Perfect for word-by-word highlighting
import websocket
import json
import threading
import time
# Files to store output
audio_file = 'output.mp3'
timestamps_file = 'timestamps.json'
audio_chunks = []
timestamps = []
def on_message(ws, message):
if isinstance(message, str):
# Handle JSON messages (timestamps or status)
data = json.loads(message)
if data.get('type') == 'progress' and 'message' in data:
# Add timestamp information
msg_val = data['message']
if isinstance(msg_val, list):
timestamps.extend(msg_val)
elif data.get('type') == 'complete':
# Save the audio and timestamps when complete
with open(audio_file, 'wb') as f:
import io
buffer = io.BytesIO()
for chunk in audio_chunks:
buffer.write(chunk)
f.write(buffer.getvalue())
# Save timestamps (filter out empty ones)
filtered = [ts for ts in timestamps if ts and 'word' in ts]
with open(timestamps_file, 'w') as f:
json.dump(filtered, f, indent=2)
print("Audio saved to:", audio_file)
print("Timestamps saved to:", timestamps_file)
ws.close()
else:
# Handle binary audio data
audio_chunks.append(message)
def on_open(ws):
# Send configuration when connection opens
config = {
'Text': 'Welcome to Unreal Speech.',
'VoiceId': '<VOICE_ID>',
'Model': 'kokoro',
'Codec': 'libmp3lame',
'SampleRate': 24000,
'Bitrate': '192k',
'Pitch': 1.0,
'TimestampType': 'word'
}
ws.send(json.dumps(config))
# Connect to WebSocket endpoint
websocket.enableTrace(False)
ws = websocket.WebSocketApp(
"wss://api.v8.unrealspeech.com/streamWithTimestamps",
header={'Authorization': 'Bearer YOUR_API_KEY'},
on_open=on_open,
on_message=on_message
)
# Run WebSocket connection
ws.run_forever()
// Short endpoint: /stream
// - Up to 1,000 characters
// - Synchronous, instant response (0.3s+)
// - Streams back raw audio data
const axios = require('axios');
const fs = require('fs');
const headers = {
'Authorization': 'Bearer YOUR_API_KEY',
};
const data = {
'Text': '<YOUR_TEXT>', // Up to 1,000 characters
'VoiceId': '<VOICE_ID>', // Scarlett, Dan, Liv, Will, Amy
'Bitrate': '192k', // 320k, 256k, 192k, ...
'Speed': '0', // -1.0 to 1.0
'Pitch': '1', // 0.5 to 1.5
'Codec': 'libmp3lame', // libmp3lame or pcm_mulaw
};
axios({
method: 'post',
url: 'https://api.v8.unrealspeech.com/stream',
headers: headers,
data: data,
responseType: 'stream'
}).then(function (response) {
response.data.pipe(fs.createWriteStream('audio.mp3'))
});
// Medium endpoint: /speech
// - Up to 3,000 characters
// - Synchronous, takes ~1s per 700 chars
// - Returns MP3 and JSON timestamp URLs
const axios = require('axios');
const headers = {
'Authorization': 'Bearer YOUR_API_KEY',
};
const data = {
'Text': '<YOUR_TEXT>', // Up to 3,000 characters
'VoiceId': '<VOICE_ID>', // Scarlett, Dan, Liv, Will, Amy
'Bitrate': '192k', // 320k, 256k, 192k, ...
'Speed': '0', // -1.0 to 1.0
'Pitch': '1', // 0.5 to 1.5
'TimestampType': 'sentence', // word or sentence
};
axios({
method: 'post',
url: 'https://api.v8.unrealspeech.com/speech',
headers: headers,
data: data,
}).then(function (response) {
console.log(JSON.stringify(response.data));
});
// Long endpoint: /synthesisTasks
// - Up to 500,000 characters
// - Asynchronous, takes ~1s per 800 chars
// - Returns a TaskId (use to check status)
const axios = require('axios');
const headers = {
'Authorization': 'Bearer YOUR_API_KEY',
};
const data = {
'Text': '<YOUR_TEXT>', // Up to 500,000 characters
'VoiceId': '<VOICE_ID>', // Scarlett, Dan, Liv, Will, Amy
'Bitrate': '192k', // 320k, 256k, 192k, ...
'Speed': '0', // -1.0 to 1.0
'Pitch': '1', // 0.5 to 1.5
'TimestampType': 'sentence', // word or sentence
//'CallbackUrl': '<URL>', // pinged when ready
};
axios({
method: 'post',
url: 'https://api.v8.unrealspeech.com/synthesisTasks',
headers: headers,
data: data,
}).then(function (response) {
console.log(JSON.stringify(response.data));
});
Sample Response
{
'SynthesisTask': {
'CreationTime': '2023-09-01T15:05:22.15Z',
'OutputUri': 'https://unreal-tts-live-demo.s3-us-west-1.amazonaws.com/d8ef514d.mp3',
'RequestCharacters': 14,
'TaskId': 'd8ef514d',
'TaskStatus': 'scheduled',
'TimestampsUri': 'https://unreal-tts-live-demo.s3-us-west-1.amazonaws.com/d8ef514d.json',
'VoiceId': 'Scarlett'
}
}
Check Task Status
Make a GET request with TaskId in the URL to check the
status.
const axios = require('axios');
const headers = {
'Authorization': 'Bearer YOUR_API_KEY',
};
axios({
method: 'get',
url: 'https://api.v8.unrealspeech.com/synthesisTasks/d8ef514d',
headers: headers,
}).then(function (response) {
console.log(JSON.stringify(response.data));
});
// Short endpoint: /stream
// - Up to 1,000 characters
// - Synchronous, instant response (0.3s+)
// - Streams back raw audio data
import React from "react";
import { View, Button, ActivityIndicator } from "react-native";
import { useUnrealSpeech, blobToDataURI } from "react-native-unrealspeech";
import { Audio } from "expo-av";
export default function App() {
const { stream, requestState } = useUnrealSpeech("YOUR_API_KEY");
const play = async (response: any) => {
try {
if (!response.ok) {
throw new Error("Network response was not ok");
}
const blobData = await response.blob();
const blob = new Blob([blobData], { type: "audio/mp3" });
const uri = await blobToDataURI(blob);
const { sound } = await Audio.Sound.createAsync({ uri }, {});
console.log(uri);
await sound.playAsync();
} catch (error) {
console.error("Error occurred while playing sound:", error);
}
};
const handleSpeak = async () => {
try {
const response = await stream(
"<YOUR_TEXT>", // Up to 1,000 characters
"<VOICE_ID>", // Scarlett, Dan, Liv, Will, Amy
"192k", // 320k, 256k, 192k, ...
0, // Speed: -1.0 to 1.0
1, // Pitch: 0.5 to 1.5
"libmp3lame" // Codec: libmp3lame or pcm_mulaw
);
play(response);
} catch (error) {
console.error("Error occurred while handling speak:", error);
}
};
return (
<View style={{ flex: 1, justifyContent: "center" }}>
{requestState === "loading" ? (
<ActivityIndicator />
) : (
<Button title="Speak" onPress={handleSpeak} />
)}
</View>
);
}
// Medium endpoint: /speech
// - Up to 3,000 characters
// - Synchronous, takes ~1s per 700 chars
// - Returns MP3 and JSON timestamp URLs
import React from "react";
import { StatusBar } from "expo-status-bar";
import { StyleSheet, Button, View, ActivityIndicator } from "react-native";
import { useUnrealSpeech } from "react-native-unrealspeech";
export default function App() {
const { speech, requestState } = useUnrealSpeech("YOUR_API_KEY");
const handleSpeak = async () => {
const mySpeech = await speech(
"<YOUR_TEXT>", // Up to 3,000 characters
"<VOICE_ID>", // Scarlett, Dan, Liv, Will, Amy
"192k", // 320k, 256k, 192k, ...
"sentence" // word or sentence
);
console.log(mySpeech);
};
return (
<View style={styles.container}>
<StatusBar style="auto" />
{requestState === "loading" ? (
<ActivityIndicator />
) : (
<Button title="Speak" onPress={handleSpeak} />
)}
</View>
);
}
const styles = StyleSheet.create(
{
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center"
}
}
);
// Long endpoint: /synthesisTasks
// - Up to 500,000 characters
// - Asynchronous, takes ~1s per 800 chars
// - Returns a TaskId (use to check status)
import React from "react";
import { StatusBar } from "expo-status-bar";
import { StyleSheet, Button, View, ActivityIndicator } from "react-native";
import { useUnrealSpeech } from "react-native-unrealspeech";
export default function App() {
const {
createSynthesisTask,
getSynthesisTaskStatus,
speech,
stream,
status,
requestState
} = useUnrealSpeech("YOUR_API_KEY");
const handleSpeak = async () => {
const task = await createSynthesisTask(
"<YOUR_TEXT>", // Up to 500,000 characters
"<VOICE_ID>", // Scarlett, Dan, Liv, Will, Amy
"192k", // 320k, 256k, 192k, ...
"sentence" // word or sentence
);
if (status) {
const response = await getSynthesisTaskStatus(status);
console.log(response);
}
};
return (
<View style={styles.container}>
<StatusBar style="auto" />
{requestState === "loading" ? (
<ActivityIndicator />
) : (
<Button title="Speak" onPress={handleSpeak} />
)}
</View>
);
}
const styles = StyleSheet.create(
{
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center"
}
}
);
# Short endpoint: /stream
# - Up to 1,000 characters
# - Synchronous, instant response (0.3s+)
# - Streams back raw audio data
curl -X POST "https://api.v8.unrealspeech.com/stream" -H "Content-Type: application/json" -H "Authorization: Bearer YOUR_API_KEY" --data '{"Text": "<YOUR_TEXT>", "VoiceId": "<VOICE_ID>", "Bitrate": "128k", "Speed": "0", "Pitch": "1", "Codec": "libmp3lame"}' --output audio.mp3
# Medium endpoint: /speech
# - Up to 3,000 characters
# - Synchronous, takes ~1s per 700 chars
# - Returns MP3 and JSON timestamp URLs
curl -X POST "https://api.v8.unrealspeech.com/speech" -H "Content-Type: application/json" -H "Authorization: Bearer YOUR_API_KEY" --data '{"Text": "<YOUR_TEXT>", "VoiceId": "<VOICE_ID>", "Bitrate": "192k", "Speed": "0", "Pitch": "1", "TimestampType": "sentence"}'
# Long endpoint: /synthesisTasks
# - Up to 500,000 characters
# - Asynchronous, takes ~1s per 800 chars
# - Returns a TaskId (use to check status)
curl -X POST "https://api.v8.unrealspeech.com/synthesisTasks" -H "Content-Type: application/json" -H "Authorization: Bearer YOUR_API_KEY" --data '{"Text": "<YOUR_TEXT>", "VoiceId": "<VOICE_ID>", "Bitrate": "128k", "Speed": "0", "Pitch": "1", "TimestampType": "sentence"}'
Sample Response
{
'SynthesisTask': {
'CreationTime': '2023-09-01T15:05:22.15Z',
'OutputUri': 'https://unreal-tts-live-demo.s3-us-west-1.amazonaws.com/d8ef514d.mp3',
'RequestCharacters': 14,
'TaskId': 'd8ef514d',
'TaskStatus': 'scheduled',
'TimestampsUri': 'https://unreal-tts-live-demo.s3-us-west-1.amazonaws.com/d8ef514d.json',
'VoiceId': 'Scarlett'
}
}
Check Task Status
Make a GET request with TaskId in the URL to check the
status.
curl -X GET "https://api.v8.unrealspeech.com/synthesisTasks/d8ef514d" -H "Content-Type: application/json" -H "Authorization: Bearer YOUR_API_KEY"
Ready to dive in?
Get a Free API Key →
Super Fast Text-to-Speech API
Build real-time apps. Generate long-form audio fast.
Play audio in
0.3s
Create 10-hour audio in
15 min
Get Started for Free →
FAQ
Do you offer voices in other
languages?
Yes, we provide 48 voices across 8 different languages, including US English, UK
English, Mandarin Chinese, Hindi, Spanish, Portuguese, Japanese, French and Italian.
Can I create custom voices (voice
cloning)?
Not right now, but we're working on it!
What happens if I use all of my monthly
characters?
Additional usage over the monthly allowance will be charged daily at the
rate of your current plan:
- Basic – $16 per 1M characters
- Plus – $12 per 1M characters
- Pro – $10 per 1M characters
- Enterprise – $8 per 1M characters
What happens to unused characters at the end
of the month?
- Free plan – Characters are reset on the 1st of every month.
- Paid plan – Unused characters roll over to the next billing cycle.
Can I use generated audio
commercially?
Yes, audio generated with Unreal Speech can be used commercially. The
following terms apply, based on your subscription plan:
- Free plan – You must attribute Unreal Speech when publishing audio by including a link to
"unrealspeech.com" in the description. - Paid plan – You do not need to include any attribution.
How do I update my payment method?
Go to your Dashboard and choose "Manage
Subscription".
How do I cancel my subscription?
You can cancel your subscription at any time. Go to your Dashboard and choose "Manage Subscription".
Do you have an affiliate program?
Yes! You can earn 15% recurring on all paid referrals. Click here to sign up.
Sign In
Sign in with GoogleGoogle
Sign in with emailEmail
By continuing, you are indicating that you accept our Terms of Service and Privacy Policy.
Copied to clipboard!
