DEV Community

VoiceDeveloper
VoiceDeveloper

Posted on

Build a Voice Notification System with ElevenLabs

Why Voice Notifications Matter

If you’ve ever built a monitoring dashboard, you know that a flashing banner or a red badge can only do so much. When a critical alert fires, you want to make sure the right person hears it right away—even if they’re not staring at a screen. That’s where voice notifications shine. They cut through visual noise, work well on mobile devices, and can be personalized to sound like a trusted teammate rather than a generic robot.

In the last couple of years, text‑to‑speech (TTS) APIs have gone from “nice‑to‑have” to production‑ready, thanks to advances in neural synthesis and voice cloning. Among the options on the market, ElevenLabs stands out for its natural‑sounding voices, easy‑to‑use REST API, and generous free tier. In this post we’ll walk through a complete, end‑to‑end voice notification system using ElevenLabs, a tiny Flask webhook, and a few curl/Python snippets you can drop into any project.

Quick note: If you don’t have an ElevenLabs account yet, you can sign up through this affiliate link and get a boost of free credits: https://try.elevenlabs.io/kr07zfuqn1bp


Overview of the Architecture

+----------------+      HTTP POST       +-----------------+      GET      +-------------------+
|   Monitoring   |--------------------->|  Flask webhook  |------------->|  ElevenLabs TTS   |
|   System (e.g.,|   alert payload      |   (Python)      |   audio file   |   API (voice)    |
|   Prometheus)  |                      |                 |                |                   |
+----------------+                      +-----------------+                +-------------------+
Enter fullscreen mode Exit fullscreen mode
  1. Monitoring system (Prometheus, Grafana, custom script…) detects a condition and sends a JSON payload to our webhook.
  2. Flask webhook receives the payload, builds a short message (“CPU usage is 95% on server X”), and calls the ElevenLabs TTS endpoint.
  3. ElevenLabs returns an MP3/OGG file that we can either stream directly to a phone, push to a smart speaker, or store for later playback.

All the heavy lifting—voice quality, language support, and voice cloning—is handled by ElevenLabs, so we can focus on wiring things together.


Getting Started with ElevenLabs

  1. Create an account – go to https://try.elevenlabs.io/kr07zfuqn1bp and sign up.
  2. Grab your API key – after logging in, navigate to API → Your API keys and copy the secret. Keep it safe; it’s like a password.
  3. Choose a voice – ElevenLabs provides several “premade” voices (e.g., “Rachel”, “Domi”). You can also upload a few minutes of audio to create a custom clone, but for a quick demo the built‑in voices work perfectly.

Setting Up the Flask Webhook

First, let’s spin up a minimal Flask app that will accept alerts and turn them into spoken messages.

# Create a virtual environment
python -m venv venv
source venv/bin/activate

# Install dependencies
pip install flask requests python-dotenv
Enter fullscreen mode Exit fullscreen mode

Create a file named .env and store your ElevenLabs API key:

ELEVENLABS_API_KEY=your_secret_key_here
Enter fullscreen mode Exit fullscreen mode

Now the app.py:

import os
import json
import requests
from flask import Flask, request, jsonify, send_file
from dotenv import load_dotenv
from io import BytesIO

load_dotenv()
app = Flask(__name__)

ELEVENLABS_API_KEY = os.getenv("ELEVENLABS_API_KEY")
ELEVENLABS_TTS_URL = "https://api.elevenlabs.io/v1/text-to-speech"

# Choose a voice ID – you can list your voices via the API or use a known one
DEFAULT_VOICE_ID = "EXAVITQu4vr4xnSDxMaL"  # Example: "Rachel"

def synthesize_text(text: str, voice_id: str = DEFAULT_VOICE_ID) -> bytes:
    """Call ElevenLabs TTS and return raw audio bytes."""
    url = f"{ELEVENLABS_TTS_URL}/{voice_id}"
    headers = {
        "xi-api-key": ELEVENLABS_API_KEY,
        "Content-Type": "application/json"
    }
    payload = {
        "text": text,
        "model_id": "eleven_monolingual_v1",
        "voice_settings": {
            "stability": 0.75,
            "similarity_boost": 0.75
        }
    }
    response = requests.post(url, headers=headers, json=payload)
    response.raise_for_status()
    # The API returns a binary audio stream
    return response.content

@app.route("/alert", methods=["POST"])
def alert():
    data = request.get_json()
    # Expecting a simple payload: {"message": "CPU usage 95% on server X"}
    message = data.get("message", "No message provided")
    try:
        audio_bytes = synthesize_text(message)
        # Return the audio as an attachment so callers can play it immediately
        return send_file(
            BytesIO(audio_bytes),
            mimetype="audio/mpeg",
            as_attachment=False,
            download_name="notification.mp3"
        )
    except Exception as e:
        return jsonify({"error": str(e)}), 500

if __name__ == "__main__":
    # Run on localhost for testing; in production use a proper WSGI server
    app.run(host="0.0.0.0", port=5000, debug=True)
Enter fullscreen mode Exit fullscreen mode

How It Works

  • The /alert endpoint expects a JSON body with a message field.
  • synthesize_text builds the request for ElevenLabs, specifying the voice and a couple of optional settings (stability and similarity_boost).
  • The binary MP3 response is streamed back to the caller, which could be a mobile app, a browser, or even a simple curl command.

Testing the End‑to‑End Flow with curl

You can simulate an alert from your monitoring system using a one‑liner:

curl -X POST http://localhost:5000/alert \
     -H "Content-Type: application/json" \
     -d '{"message":"🚨 High memory usage detected on server prod‑db‑01. Current usage: 92%"}' \
     --output notification.mp3
Enter fullscreen mode Exit fullscreen mode

Open notification.mp3 with any player, and you should hear a clear, human‑like voice announcing the alert.


Integrating with Real‑World Monitoring (Prometheus Example)

Prometheus Alertmanager can POST alerts to a webhook. Add a new receiver in alertmanager.yml:

receivers:
  - name: voice-notifier
    webhook_configs:
      - url: http://your-flask-host:5000/alert
        send_resolved: true
Enter fullscreen mode Exit fullscreen mode

Then create a simple routing rule:

route:
  receiver: voice-notifier
  group_by: ['alertname']
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 1h
Enter fullscreen mode Exit fullscreen mode

Whenever a Prometheus rule fires, Alertmanager will forward the alert payload. You may need to tweak the Flask code to extract the exact text you want from the Alertmanager JSON format (e.g., {{ .CommonAnnotations.summary }}).


Going a Step Further: Voice Cloning

If you want the notification to sound like a specific team member (think “Your friendly DevOps bot, Alex”), ElevenLabs lets you clone a voice with as little as 10 seconds of audio. The workflow is:

  1. Record a short, clean voice sample (WAV/MP3).
  2. Upload it via the Voice Cloning endpoint (or through the web UI).
  3. Use the returned voice_id in synthesize_text.
def clone_voice(name: str, audio_path: str) -> str:
    url = "https://api.elevenlabs.io/v1/voices/add"
    headers = {"xi-api-key": ELEVENLABS_API_KEY}
    files = {"audio_file": open(audio_path, "rb")}
    data = {"name": name}
    response = requests.post(url, headers=headers, files=files, data=data)
    response.raise_for_status()
    return response.json()["voice_id"]
Enter fullscreen mode Exit fullscreen mode

After cloning, replace DEFAULT_VOICE_ID with the new ID and you’ve got a fully branded voice notification system.


Tips for Production‑Ready Deployments

Concern Recommendation
Latency Cache the audio for recurring alerts (e.g., “Server X is down”).
Scalability Run Flask behind Gunicorn or uWSGI; consider a queue (RabbitMQ, SQS) if alerts burst.
Security Keep the ElevenLabs API key in a secret manager (AWS Secrets Manager, Vault). Use HTTPS for your webhook.
Error handling If ElevenLabs returns a 429 (rate‑limit), fallback to a simple text‑to‑speech library like pyttsx3.
Monitoring Export metrics (request count, latency) with Prometheus client library for your Flask service.

Wrapping Up

Building a voice notification system is now a matter of wiring a few HTTP calls together. ElevenLabs provides the heavy‑lifting—high‑fidelity, low‑latency speech synthesis and optional voice cloning—while the surrounding glue code can be as lightweight as a Flask route or as robust as a full microservice architecture.

Give it a spin:

  1. Sign up for ElevenLabs via https://try.elevenlabs.io/kr07zfuqn1bp
  2. Clone the example repo (or copy the snippets above).
  3. Hook it into your existing monitoring pipeline.

You’ll be surprised how much more immediate and personable alerts become when they speak to you in a natural voice.

Ready to make your alerts audible? Try ElevenLabs today and bring your monitoring stack to life! https://try.elevenlabs.io/kr07zfuqn1bp

Top comments (0)