Why a Text‑to‑Speech SaaS?
Voice AI is moving from niche research labs into everyday products—think audiobooks, interactive bots, and personalized voicemail. Building a Text‑to‑Speech (TTS) SaaS lets you package that power for anyone who needs a quick, high‑quality voice output without the heavy lifting of training models.
In this guide you’ll:
- Hook up the ElevenLabs API (the industry‑leading voice cloning service)
- Wrap it in a tiny Node.js server that accepts text and returns an audio file
- Deploy the whole thing on Bluehost, the easy, affordable hosting platform that supports Node.js apps.
By the end you’ll have a working endpoint you can call from any front‑end, mobile app, or automation script.
Prerequisites
| What you need | Why it matters |
|---|---|
| Node.js ≥ 18 | Modern syntax, native fetch, and better performance |
| npm or yarn | Dependency management |
| ElevenLabs API key – sign up here | Gives you access to high‑fidelity, neural voices |
| Bluehost account – get started here | Will host the Node.js app for you, with one‑click SSL and auto‑scaling |
If you already have a GitHub repo, you can push straight to Bluehost later; otherwise, we’ll start from scratch.
1️⃣ Set Up the ElevenLabs Client
ElevenLabs exposes a simple REST API. The only thing you need is the API key (found in your dashboard). Let’s create a tiny wrapper.
mkdir tts-saas && cd tts-saas
npm init -y
npm i dotenv node-fetch
Create a .env file (never commit this to source control):
ELEVENLABS_API_KEY=your_api_key_here
Now, eleven.js:
// eleven.js
import fetch from 'node-fetch';
import { config } from 'dotenv';
config();
const BASE_URL = 'https://api.elevenlabs.io/v1';
export async function synthesize(text, voiceId = 'EXAVITQu4vr4xnSDxMaL') {
const response = await fetch(`${BASE_URL}/text-to-speech/${voiceId}`, {
method: 'POST',
headers: {
'xi-api-key': process.env.ELEVENLABS_API_KEY,
'Content-Type': 'application/json',
Accept: 'audio/mpeg',
},
body: JSON.stringify({
text,
voice_settings: {
stability: 0.75,
similarity_boost: 0.85,
},
}),
});
if (!response.ok) {
const err = await response.text();
throw new Error(`ElevenLabs error: ${err}`);
}
// Returns a Buffer with the MP3 data
return await response.buffer();
}
Pro tip: ElevenLabs lets you create custom voices in their UI. Replace the default
voiceIdwith your own for brand‑specific tones.
2️⃣ Build the Express API
We’ll expose a single POST endpoint: /api/speak. It receives JSON { "text": "Hello world" } and streams back an MP3.
npm i express cors morgan
Create server.js:
// server.js
import express from 'express';
import cors from 'cors';
import morgan from 'morgan';
import { synthesize } from './eleven.js';
const app = express();
app.use(cors());
app.use(express.json());
app.use(morgan('dev'));
app.post('/api/speak', async (req, res) => {
const { text, voiceId } = req.body;
if (!text) {
return res.status(400).json({ error: 'Missing "text" in request body' });
}
try {
const audioBuffer = await synthesize(text, voiceId);
res.set({
'Content-Type': 'audio/mpeg',
'Content-Length': audioBuffer.length,
'Content-Disposition': 'attachment; filename="speech.mp3"',
});
res.send(audioBuffer);
} catch (err) {
console.error(err);
res.status(500).json({ error: err.message });
}
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`🚀 Server listening on ${PORT}`));
Run locally:
node server.js
Test with curl:
curl -X POST http://localhost:3000/api/speak \
-H "Content-Type: application/json" \
-d '{"text":"Welcome to your new voice AI service!"}' \
--output speech.mp3
You should now have a speech.mp3 file generated by ElevenLabs.
3️⃣ Prepare for Deployment
Bluehost supports Node.js via its “Application Manager”. The steps are straightforward:
- Push your code to GitHub (or zip it up).
- In the Bluehost dashboard, go to Hosting → Manage → Application Manager → Node.js.
- Click Create New App, select the repo, set the start command to
node server.js, and choose a Node version ≥ 18. - Bluehost automatically installs dependencies (
npm install) and sets up a reverse proxy on port 80, so your API will be reachable athttps://yourdomain.com/api/speak.
Why Bluehost? It offers a one‑click Node.js environment, free SSL, and a generous free tier for low‑traffic SaaS prototypes. You can spin up the service in minutes without fiddling with Dockerfiles or VPS firewalls.
4️⃣ Secure Your API Key
When you add the .env file in the Bluehost UI, make sure:
- Never commit the key to Git.
- Use environment variables in the hosting panel (Bluehost lets you add them under “Environment Variables”).
- Set
ELEVENLABS_API_KEYthere, and the app will pick it up automatically.
5️⃣ Scaling Tips
-
Rate limiting: ElevenLabs limits requests per minute per key. Add a simple middleware like
express-rate-limitto protect your endpoint. - Caching: Store generated audio in a CDN (e.g., Cloudflare) keyed by a hash of the text + voice ID. This cuts down on repeated API calls and saves credits.
- Billing alerts: Monitor usage in the ElevenLabs dashboard; set alerts to avoid surprise charges.
6️⃣ Next Steps & Ideas
- User authentication – let each user store their own custom voice IDs.
-
Web UI – a React front‑end that records text, hits
/api/speak, and plays back the audio instantly. -
Batch processing – expose a
/api/batchendpoint that accepts an array of strings and returns a ZIP of MP3s.
All of these can be built on top of the same lightweight Express server, and Bluehost will handle the underlying scaling for you.
🎉 Wrap‑up
You now have a functional Text‑to‑Speech SaaS that leverages ElevenLabs’ state‑of‑the‑art voice synthesis and runs on Bluehost, the hassle‑free hosting platform. From a single endpoint you can generate natural‑sounding speech for any application—be it a chatbot, an e‑learning platform, or a custom voicemail service.
Ready to give your product a voice?
Happy coding, and may your SaaS be as smooth as the voices it produces!
Top comments (0)