DEV Community

VoiceDeveloper
VoiceDeveloper

Posted on

Host Your TTS API Wrapper: Bluehost VPS Setup Guide

Why Host a TTS API Wrapper on a VPS?

If you’ve been experimenting with voice‑AI—whether it’s generating audiobooks, creating custom voice assistants, or cloning a favorite narrator—you’ve probably hit the same roadblock: how do I make my Text‑to‑Speech (TTS) service reliably reachable from anywhere?

Running the wrapper on your local machine works for quick tests, but production‑grade projects need a server that’s always on, has a static IP, and can handle a handful of concurrent requests without choking. A modest VPS gives you exactly that, and Bluehost makes the process painless and affordable. Pair it with a high‑quality TTS engine like ElevenLabs, and you’ve got a full‑stack voice‑AI solution you can deploy in under an hour.

Below is a step‑by‑step guide to spin up a Linux VPS on Bluehost, install the required dependencies, and expose a simple Python wrapper around the ElevenLabs API.


What You’ll Need

Item Reason
Bluehost VPS (any 2 GB plan will do) Affordable, one‑click Ubuntu install, and easy SSH access
ElevenLabs API key Industry‑leading neural TTS and voice cloning
Python 3.10+ (or later) To run the wrapper script
Git & curl (pre‑installed on most Linux images) For pulling code and testing endpoints
Domain (optional) For a friendly URL instead of the raw IP

You can sign up for an ElevenLabs account using this link: https://try.elevenlabs.io/kr07zfuqn1bp, and grab a VPS from Bluehost here: https://bluehost.sjv.io/5k0d52.


1. Spin Up a Bluehost VPS

  1. Log in to your Bluehost dashboard and navigate to VPS → Create New VPS.
  2. Choose the Ubuntu 22.04 LTS image (the default).
  3. Pick a plan (the 2 GB/2 CPU option is more than enough for a modest TTS wrapper).
  4. Give your server a hostname (e.g., tts-api) and click Create.

Bluehost will email you the server’s public IP address and the root password. SSH in:

ssh root@YOUR_VPS_IP
# First login will ask you to change the root password
Enter fullscreen mode Exit fullscreen mode

Tip: If you prefer a non‑root user, create one now:

adduser devuser
usermod -aG sudo devuser
Enter fullscreen mode Exit fullscreen mode

2. Prepare the Environment

Update the package list and install essential tools:

apt update && apt upgrade -y
apt install -y python3-pip python3-venv git curl
Enter fullscreen mode Exit fullscreen mode

Create a virtual environment for isolation:

mkdir -p /opt/tts-wrapper && cd /opt/tts-wrapper
python3 -m venv venv
source venv/bin/activate
Enter fullscreen mode Exit fullscreen mode

3. Clone the Wrapper Boilerplate

For this tutorial we’ll use a minimal Flask app that forwards requests to ElevenLabs. Clone the repo (or copy the snippet below into a new app.py file):

git clone https://github.com/example/elevenlabs-tts-wrapper.git .
# If you don’t have a repo, just create the file manually:
# nano app.py
Enter fullscreen mode Exit fullscreen mode

app.py

import os
from flask import Flask, request, jsonify
import requests

app = Flask(__name__)

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

@app.route("/synthesize", methods=["POST"])
def synthesize():
    data = request.get_json()
    if not data or "text" not in data or "voice_id" not in data:
        return jsonify({"error": "Missing 'text' or 'voice_id'"}), 400

    payload = {
        "text": data["text"],
        "voice_settings": {"stability": 0.75, "similarity_boost": 0.85}
    }

    headers = {
        "xi-api-key": ELEVEN_API_KEY,
        "Content-Type": "application/json"
    }

    resp = requests.post(
        f"{ELEVEN_TTS_URL}/{data['voice_id']}",
        json=payload,
        headers=headers,
        stream=True,
    )
    if resp.status_code != 200:
        return jsonify({"error": "ElevenLabs API error", "details": resp.text}), 502

    # Return the raw audio bytes (mp3) directly
    return resp.content, 200, {"Content-Type": "audio/mpeg"}

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8000)
Enter fullscreen mode Exit fullscreen mode

Install the Python dependencies:

pip install flask requests
Enter fullscreen mode Exit fullscreen mode

4. Set Your ElevenLabs API Key

Export the key as an environment variable (you can also add it to /etc/environment for persistence):

export ELEVEN_API_KEY="YOUR_ELEVENLABS_API_KEY"
Enter fullscreen mode Exit fullscreen mode

If you haven’t created a key yet, head over to ElevenLabs and generate one: https://try.elevenlabs.io/kr07zfuqn1bp.


5. Run the Service

Start the Flask app in the background with nohup (or use a process manager like systemd or supervisor for production):

nohup python app.py > tts.log 2>&1 &
Enter fullscreen mode Exit fullscreen mode

Check that it’s listening:

curl -s http://localhost:8000/health || echo "No health endpoint yet"
Enter fullscreen mode Exit fullscreen mode

You should see a blank response (the app doesn’t expose a health route, but no error means it’s up).


6. Test the Endpoint with curl

Now that the server is running, let’s hit it from your workstation:

curl -X POST https://YOUR_VPS_IP:8000/synthesize \
  -H "Content-Type: application/json" \
  -d '{
        "text": "Hello, this is a test of the ElevenLabs voice cloning API.",
        "voice_id": "EXAMPLE_VOICE_ID"
      }' \
  --output hello.mp3
Enter fullscreen mode Exit fullscreen mode

Replace EXAMPLE_VOICE_ID with a voice you own in ElevenLabs (you can list them via the ElevenLabs dashboard). The command should download an hello.mp3 file that you can play locally.

If you get a JSON error back, double‑check that the API key is correctly exported and that the voice ID matches.


7. Secure the API (Optional but Recommended)

a. Add a Simple Token

Edit app.py and require a bearer token:

API_TOKEN = os.getenv("API_TOKEN", "change-me")

def check_auth():
    auth = request.headers.get("Authorization", "")
    return auth == f"Bearer {API_TOKEN}"
Enter fullscreen mode Exit fullscreen mode

Then wrap the route:

if not check_auth():
    return jsonify({"error": "Unauthorized"}), 401
Enter fullscreen mode Exit fullscreen mode

Export the token on the server:

export API_TOKEN="my-secret-token"
Enter fullscreen mode Exit fullscreen mode

b. Enable HTTPS with Let’s Encrypt

Bluehost makes it easy to add a free SSL certificate via cPanel → SSL/TLS → Let’s Encrypt. Once the cert is installed, you can front Flask with Gunicorn and Nginx:

pip install gunicorn
gunicorn -w 4 -b 0.0.0.0:8000 app:app
Enter fullscreen mode Exit fullscreen mode

Create an Nginx site config (/etc/nginx/sites-available/tts):

server {
    listen 443 ssl;
    server_name yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}
Enter fullscreen mode Exit fullscreen mode

Enable and restart:

ln -s /etc/nginx/sites-available/tts /etc/nginx/sites-enabled/
systemctl restart nginx
Enter fullscreen mode Exit fullscreen mode

Now your TTS wrapper is reachable via https://yourdomain.com/synthesize—secure and ready for production traffic.


8. Scaling Thoughts

  • CPU: Neural TTS is CPU‑intensive. If you start hitting latency spikes, bump the VPS to a 4 GB plan on Bluehost (still cheap).
  • Caching: Store generated audio in a Redis cache or local filesystem to avoid repeated calls for the same text.
  • Rate Limits: ElevenLabs enforces per‑minute limits; respect them by adding a simple request‑throttling middleware.

Wrap‑Up

You now have a fully functional TTS API wrapper running on a Bluehost VPS, powered by the state‑of‑the‑art ElevenLabs neural engine. The whole setup—from provisioning the server to securing the endpoint—can be completed in less than an hour, and the cost stays well under $10/month for modest traffic.

Ready to bring your voice AI ideas to life?

Give ElevenLabs a spin and experience the quality of their voice cloning: https://try.elevenlabs.io/kr07zfuqn1bp.

Then grab a cost‑effective, developer‑friendly VPS from Bluehost and deploy your wrapper today: https://bluehost.sjv.io/5k0d52.

Happy coding, and may your projects sound as good as they look!

Top comments (0)