How Telegram voice notes work
Telegram voice notes are sent through the official Telegram Bot API. Your bot sends an OGG/OPUS audio file as a voice message, which appears as a native playable waveform in the recipient's chat.
The recipient must have started a conversation with your bot before you can send them messages. This is a Telegram platform requirement — bots cannot message users who haven't initiated contact first.
Setting up a Telegram bot
- Open Telegram and search for @BotFather.
- Send
/newbotand follow the prompts to choose a name and username. - BotFather replies with your bot token — a string like
7000000000:AAH-abc123xyz. - Store this token securely. It grants full access to your bot.
export TELEGRAM_BOT_TOKEN="7000000000:AAH-abc123xyz"
Getting chat IDs
You need the recipient's chat ID (a numeric identifier) to send messages. There are several ways to find it:
Method 1: From incoming messages
Set up a webhook or poll getUpdates to receive messages sent to your bot. Each message includes the sender's chat ID:
curl https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/getUpdates
The response includes message.chat.id for each message.
Method 2: Using @userinfobot
Have the user forward a message to @userinfobot in Telegram. It replies with their numeric user ID.
Method 3: From your application
If you have an existing Telegram integration, you likely already store chat IDs when users interact with your bot.
Audio format
Telegram voice messages use OGG format with OPUS codec. Svara converts your audio automatically:
| Input format | Behavior | |---|---| | OGG / OPUS | Sent directly, no conversion needed | | M4A / AAC | Auto-converted to OGG/OPUS | | MP3 | Auto-converted to OGG/OPUS | | WAV | Auto-converted to OGG/OPUS | | WebM | Auto-converted to OGG/OPUS |
Audio files must be under 50 MB (Telegram's limit). There is no duration restriction, but shorter messages (under 60 seconds) display inline as a waveform. Longer messages are shown with a download button.
Example request
curl -X POST https://api.svarapi.io/v1/send \
-H "Authorization: Bearer $SVARA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"platform": "telegram",
"recipient": "123456789",
"audio_url": "https://cdn.example.com/notes/update.m4a",
"session": {
"bot_token": "7000000000:AAH-abc123xyz"
},
"caption": "Quick update on the project"
}'
const response = await fetch("https://api.svarapi.io/v1/send", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.SVARA_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
platform: "telegram",
recipient: "123456789",
audio_url: "https://cdn.example.com/notes/update.m4a",
session: {
bot_token: process.env.TELEGRAM_BOT_TOKEN,
},
caption: "Quick update on the project",
}),
});
const result = await response.json();
console.log(`Voice note queued: ${result.id}`);
import requests
response = requests.post(
"https://api.svarapi.io/v1/send",
headers={"Authorization": f"Bearer {api_key}"},
json={
"platform": "telegram",
"recipient": "123456789",
"audio_url": "https://cdn.example.com/notes/update.m4a",
"session": {
"bot_token": bot_token,
},
"caption": "Quick update on the project",
},
)
result = response.json()
print(f"Voice note queued: {result['id']}")
Sending with captions
The caption parameter adds a text message alongside the voice note. It appears directly below the voice note waveform in the chat. Captions are optional and support plain text only (no Markdown or HTML).
{
"platform": "telegram",
"recipient": "123456789",
"audio_url": "https://cdn.example.com/notes/update.m4a",
"session": {
"bot_token": "7000000000:AAH-abc123xyz"
},
"caption": "Listen to this 30-second summary of our Q1 results"
}
Common errors
| Error | Cause | Solution |
|---|---|---|
| invalid_bot_token | The bot token is malformed or revoked | Check your token with @BotFather or generate a new one |
| bot_blocked | The user has blocked the bot | The user needs to unblock and re-start the bot |
| chat_not_found | The chat ID is invalid or the user hasn't started the bot | The user must send /start to your bot first |
| audio_too_large | The audio file exceeds 50 MB | Compress or shorten your audio |
| audio_fetch_failed | Could not download the audio from the URL | Ensure the URL is publicly accessible |