Dev.to AI 🤖 Ai 👁 0 📖 6 min read

Building a Voice AI Portfolio Site That Gets You Hired

Why a Voice‑AI Portfolio Can Be Your Golden Ticket If you’re a developer looking to stand out in the AI job market, showcasing a live voice‑AI demo is one of the most compelling ways to prove your skills. Employers are

Why a Voice‑AI Portfolio Can Be Your Golden Ticket

If you’re a developer looking to stand out in the AI job market, showcasing a live voice‑AI demo is one of the most compelling ways to prove your skills. Employers are increasingly looking for talent that can build conversational agents, audio‑based assistants, or even personalized voice‑cloned systems. A portfolio that lets recruiters hear your code in action—literally—speaks louder than a plain‑text résumé.

In this post we’ll walk through building a minimal but production‑ready voice‑AI portfolio site. We’ll use ElevenLabs for high‑quality text‑to‑speech and voice cloning, and we’ll show how to deploy the app to a reliable, budget‑friendly host—Bluehost. By the end, you’ll have a working demo you can drop into your GitHub, LinkedIn, or personal website.

TL;DR

  1. Get an ElevenLabs API key.
  2. Build a tiny Flask (or Node) server that calls the ElevenLabs API.
  3. Add a simple front‑end that lets visitors type text or upload an audio sample.
  4. Deploy to Bluehost using their easy one‑click Python or Node installer.
  5. Share the live link on your résumé and social profiles.

1. Get Started with ElevenLabs

ElevenLabs provides a state‑of‑the‑art neural TTS engine. Their API is straightforward: you send a JSON payload with the text, and you get back an MP3 (or raw audio) stream. The same platform lets you clone a voice from a few minutes of audio—perfect for a personalized demo.

  1. Sign up at ElevenLabs.
  2. Once you’re in, generate an API key from the dashboard.
  3. Note the voice IDs you’ll use; you can browse their catalog or upload your own voice sample for cloning.

Tip: The free tier is generous for prototyping, but if you plan to show the demo to many visitors, consider their paid plans to avoid rate limits.

2. Build a Simple Backend

Below is a minimal Flask app (Python 3.8+) that exposes two endpoints:

  • /synthesize – accepts a JSON payload with text and optional voice_id.
  • /clone – accepts a multipart form upload of an audio file to create a new voice model.
# app.py
import os
import requests
from flask import Flask, request, jsonify, send_file

ELEVENLABS_API_KEY = os.getenv("ELEVENLABS_API_KEY")
BASE_URL = "https://api.elevenlabs.io/v1"

app = Flask(__name__)

def elevenlabs_request(endpoint, method="POST", json=None, files=None):
    url = f"{BASE_URL}{endpoint}"
    headers = {"xi-api-key": ELEVENLABS_API_KEY}
    response = requests.request(method, url, headers=headers, json=json, files=files)
    response.raise_for_status()
    return response

@app.route("/synthesize", methods=["POST"])
def synthesize():
    data = request.get_json()
    text = data.get("text")
    voice_id = data.get("voice_id", "eleven_monolingual_v1")  # default voice
    payload = {"text": text, "voice_id": voice_id}
    resp = elevenlabs_request("/text-to-speech", json=payload)
    return send_file(
        io.BytesIO(resp.content),
        mimetype="audio/mpeg",
        as_attachment=False,
        attachment_filename="output.mp3",
    )

@app.route("/clone", methods=["POST"])
def clone():
    audio_file = request.files["file"]
    files = {"audio_file": (audio_file.filename, audio_file.stream, audio_file.mimetype)}
    resp = elevenlabs_request("/voice-cloning", method="POST", files=files)
    voice_id = resp.json()["voice_id"]
    return jsonify({"voice_id": voice_id})

if __name__ == "__main__":
    app.run(debug=True)

What this does

  • The /synthesize route forwards the user’s text to ElevenLabs and streams back the MP3.
  • The /clone route accepts an audio file, sends it to the voice‑cloning endpoint, and returns the new voice_id that you can use in subsequent syntheses.

3. Add a Front‑End

A lightweight static page with a bit of JavaScript can consume the above API. Below is a single‑file example that lets visitors:

  • Type text and click “Speak”.
  • Upload an audio clip to clone a new voice.
  • Listen to the synthesized result.
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Voice AI Portfolio Demo</title>
  <style>
    body { font-family: sans-serif; max-width: 600px; margin: 2rem auto; }
    textarea { width: 100%; height: 80px; }
  </style>
</head>
<body>
  <h1>Try My Voice AI Demo</h1>

  <section>
    <h2>Text to Speech</h2>
    <textarea id="textInput" placeholder="Enter text..."></textarea>
    <br>
    <button onclick="speak()">Speak</button>
    <audio id="audioPlayer" controls></audio>
  </section>

  <section>
    <h2>Clone a Voice</h2>
    <input type="file" id="audioFile">
    <button onclick="cloneVoice()">Clone Voice</button>
    <p id="cloneStatus"></p>
  </section>

  <script>
    async function speak() {
      const text = document.getElementById('textInput').value;
      const voiceId = document.getElementById('cloneStatus').dataset.voiceId || 'eleven_monolingual_v1';
      const res = await fetch('/synthesize', {
        method: 'POST',
        headers: {'Content-Type': 'application/json'},
        body: JSON.stringify({text, voice_id: voiceId})
      });
      const blob = await res.blob();
      document.getElementById('audioPlayer').src = URL.createObjectURL(blob);
    }

    async function cloneVoice() {
      const file = document.getElementById('audioFile').files[0];
      if (!file) return alert('Select an audio file first.');
      const form = new FormData();
      form.append('file', file);
      const res = await fetch('/clone', {method: 'POST', body: form});
      const data = await res.json();
      document.getElementById('cloneStatus').textContent = `Voice cloned! ID: ${data.voice_id}`;
      document.getElementById('cloneStatus').dataset.voiceId = data.voice_id;
    }
  </script>
</body>
</html>

Deployment Tip: Place app.py and the HTML file in the same folder. If you’re using a WSGI server like Gunicorn, point it at app:app.

4. Deploy to Bluehost

Bluehost is a great choice for quick, low‑cost deployments. Their shared hosting plans come with a free domain (after the first year), 1‑click installers for Python, and a generous amount of bandwidth—perfect for a portfolio site that may get occasional visitors.

Steps

  1. Sign up for a Bluehost plan that includes a Python environment.
  2. In the control panel, navigate to Site → Python and click Create Application.
  3. Choose the folder where you’ll upload your app (e.g., /home/username/myportfolio).
  4. Upload app.py, the HTML file, and any other static assets via the file manager or FTP.
  5. Set the WSGI entry point to app:app.
  6. If you need environment variables (e.g., ELEVENLABS_API_KEY), add them under Python → Environment Variables.
  7. Point your domain to the application (the control panel handles this automatically).
  8. Visit your site—your portfolio is live!

Why Bluehost?

It’s an affordable, beginner‑friendly host that still offers the flexibility you need for Python apps. No hidden fees, and the support team is helpful if you run into hiccups.

5. Polish and Showcase

  • Add a README on GitHub that explains the tech stack and links to the live demo.
  • Embed the demo on your LinkedIn profile or personal blog.
  • Record a short video that walks through the voice‑cloning process.
  • Mention your tech choices in a blog post—this article is a great place to do that.

Call to Action

Want to elevate your voice‑AI portfolio? Try ElevenLabs’ cutting‑edge TTS and voice cloning today: https://try.elevenlabs.io/kr07zfuqn1bp. And when you’re ready to deploy, hit up Bluehost for an easy, affordable hosting solution: https://bluehost.sjv.io/5k0d52. Build, deploy, and let your voice‑AI work speak for you!

📰 Read the original article on Dev.to AI

Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.