Skip to main content

Text-to-Speech

Convert text to audio using ElevenLabs voices.
POST /api/ai/generate-audio

Request Body

text
string
required
Text to convert to speech (max ~5000 characters)
voice
string
default:"rachel"
Voice ID or name. Options: rachel, adam, josh, bella, antoni, domi

Response

Returns raw MP3 audio with Content-Type: audio/mpeg header.

Example

const response = await fetch('http://localhost:3001/api/ai/generate-audio', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    text: 'Your simulation shows a 78% probability of success.',
    voice: 'josh'
  })
})

const audioBlob = await response.blob()
const audioUrl = URL.createObjectURL(audioBlob)
const audio = new Audio(audioUrl)
audio.play()

Stream Audio

Stream audio generation for real-time playback (lower latency).
POST /api/ai/stream-audio

Request Body

Same as /generate-audio.

Response

Returns chunked audio stream with Transfer-Encoding: chunked.

Speech-to-Text

Transcribe audio to text.
POST /api/ai/transcribe

Request Body

audio
string
required
Base64-encoded audio data (MP3, WAV, or OGG)

Response

transcript
string
Transcribed text from the audio

Example

// Convert audio file to base64
const audioFile = await fetch('/path/to/audio.mp3')
const audioBuffer = await audioFile.arrayBuffer()
const base64Audio = btoa(
  new Uint8Array(audioBuffer).reduce((data, byte) => data + String.fromCharCode(byte), '')
)

const response = await fetch('http://localhost:3001/api/ai/transcribe', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ audio: base64Audio })
})

const { transcript } = await response.json()
console.log('User said:', transcript)

Voice Goal Conversation

Multi-turn voice conversation for setting financial goals.
POST /api/ai/voice-goal

Request Body

audio
string
Base64-encoded audio (optional if text provided)
text
string
Text input (optional if audio provided)
conversationHistory
array
required
Array of previous messages in the conversation

Response

userTranscript
string
Transcribed text from user’s audio (if audio was provided)
assistantResponse
string
AI assistant’s text response
isComplete
boolean
Whether the goal has been fully specified
parsedGoal
object
Structured goal data (only present if isComplete is true)
audio
string
Base64-encoded audio of assistant’s response (if ElevenLabs configured)
audioAvailable
boolean
Whether audio was generated

Example

const response = await fetch('http://localhost:3001/api/ai/voice-goal', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    text: 'I want to save for a house',
    conversationHistory: []
  })
})

const { assistantResponse, isComplete, parsedGoal } = await response.json()

console.log(assistantResponse)
// "Great! How much are you looking to save, and when do you want to achieve this goal?"

if (isComplete) {
  console.log('Goal:', parsedGoal)
}

Voice Results Conversation

Discuss simulation results through voice interaction.
POST /api/ai/voice-results

Request Body

audio
string
Base64-encoded audio (optional if text provided)
text
string
Text input (optional if audio provided)
conversationHistory
array
required
Previous conversation messages
context
object
required
Simulation context for the conversation

Response

userTranscript
string
Transcribed user input
assistantResponse
string
AI response
audio
string
Base64-encoded audio response
audioAvailable
boolean
Whether audio was generated

Get Available Voices

List all available ElevenLabs voices.
GET /api/ai/voices

Response

configured
boolean
Whether ElevenLabs is configured
voices
array
Array of available voices

Example

const response = await fetch('http://localhost:3001/api/ai/voices')
const { configured, voices } = await response.json()

voices.forEach(voice => {
  console.log(`${voice.name}: ${voice.description}`)
})
// Josh: Energetic, celebratory
// Adam: Confident, encouraging
// Bella: Empathetic, supportive
All voice endpoints require ELEVENLABS_API_KEY to be configured. Without it, endpoints return 503 Service Unavailable.

Build docs developers (and LLMs) love