Pinecall

TTS Providers

Text-to-speech providers, voices, and tuning parameters.

Voice format#

// Recommended: friendly alias (always lowercase)
{ voice: "elevenlabs/sarah" }
{ voice: "cartesia/yumiko" }
{ voice: "polly/lucia" }

// Full config object (for tuning parameters)
{ voice: { provider: "elevenlabs", voice_id: "...", speed: 1.1 } }

The legacy provider:rawId format (e.g. "elevenlabs:EXAVITQu4vr4xnSDxMaL") still works but is not recommended.

Managed vs bring-your-own-key (BYOK)#

Data-driven from the rate table — see Managed vs BYOK for the full list and the live GET /api/rates/models query.

TTS providerManaged (no key needed)Notes
elevenlabs✅ YesDefault, recommended
cartesia (sonic-3.5)✅ Yes
polly (AWS)✅ Yes
rime❌ BYOK onlyAdd a Rime key under Provider Keys
soniox❌ BYOK onlyOne Soniox key = TTS and STT
xai (Grok)❌ BYOK onlySame xAI key as Grok LLM

BYOK enforcement: configuring rime without a saved Rime key rejects agent registration with PROVIDER_KEY_REQUIRED. With your own key, that usage is billed by the provider directly — not deducted from your Pinecall credits.

Discovering voices#

Use the CLI to browse voices. Without flags, you get a catalog overview:

# Overview — shows providers, voice counts, languages
pinecall voices

# List voices for a provider + language
pinecall voices --provider=elevenlabs --language=es

# Preview a voice (plays audio in your terminal)
pinecall voices play elevenlabs/sarah

Every voice gets a friendly alias auto-generated from its name — use it directly in your config:

{ voice: "elevenlabs/sarah" }    // → Sarah - Mature, Reassuring
{ voice: "elevenlabs/agustin" }  // → Agustin - Conversational & Relaxed

Or use the fetchVoices REST helper:

import { fetchVoices } from "@pinecall/sdk";

const voices = await fetchVoices({ provider: "elevenlabs", language: "es" });
voices.forEach((v) => console.log(`${v.name} → ${v.provider}/${v.alias ?? v.id}`));

Using a voice in an agent#

voice goes on the agent config (or per phone number / per call). Use a provider/alias shortcut, or the full config object documented per provider below — both forms are interchangeable anywhere voice is accepted.

import { Pinecall } from "@pinecall/sdk";

const pc = new Pinecall(); // reads PINECALL_API_KEY

// Shortcut form
const agent = pc.agent("support", {
  voice: "elevenlabs/sarah",
  stt: "deepgram/flux",
  llm: "openai/gpt-5-chat-latest",
  prompt: "You are a friendly support agent.",
});

// Full config object form (same field, with tuning)
pc.agent("support", {
  voice: { provider: "cartesia", voice_id: "a0e99841-...", model: "sonic-3.5", speed: 1.0, emotion: "neutral" },
  stt: "deepgram/flux",
  llm: "openai/gpt-5-chat-latest",
  prompt: "...",
});

Per-number and per-call overrides use the same voice value:

agent.addPhoneNumber("+34911234567", { voice: "elevenlabs/valentina", language: "es" });
call.update({ voice: "cartesia/blake" });   // mid-call swap

ElevenLabs#

voice: {
  provider: "elevenlabs",
  voice_id: "JBFqnCBsd6RMkjVDRZzb",
  speed: 1.0,
  stability: 0.5,
  similarity_boost: 0.75,
  style: 0,
  use_speaker_boost: true,
}

Shortcut: "elevenlabs/sarah"

Model selection (auto for non-English)#

The server picks the ElevenLabs model from your language:

LanguageDefault modelWhy
en (or unset)eleven_flash_v2_5Fastest, optimized for real-time streaming
Any non-English (es, fr, de, …)eleven_multilingual_v2Flash/Turbo don't normalize text, so Spanish & other languages mispronounce numbers, dates, currency and abbreviations. The multilingual model reads them naturally.

eleven_multilingual_v2 is billed at a higher rate than flash (it's a higher-quality model). If you'd rather keep the faster/cheaper flash model for a non-English agent, use the flash shortcut or pin the model explicitly (both below).

flash: true — keep flash on a non-English agent#

The multilingual model trades a little latency for much better pronunciation. If your non-English agent should prioritize lowest latency / lowest cost over pronunciation quality, set the top-level flash flag — it opts out of the multilingual auto-default and keeps eleven_flash_v2_5:

const agent = pc.agent("sofia", {
  prompt: "Sos Sofía, asistente de la clínica.",
  llm: "openai/gpt-5-chat-latest",
  voice: "elevenlabs/agus",
  stt: "deepgram/flux",
  language: "es",
  flash: true,        // ← stay on eleven_flash_v2_5 despite language: "es"
});

flash is a sibling of language (not inside voice), so it reads cleanly with the rest of the shortcuts. Semantics:

ConfigResulting ElevenLabs model
language: "es"eleven_multilingual_v2 (auto)
language: "es", flash: trueeleven_flash_v2_5
language: "en" (with or without flash)eleven_flash_v2_5
voice: { model: "..." } (any flash/language)the pinned model — explicit always wins

Notes:

  • ElevenLabs only. flash has no effect on Cartesia or Polly.
  • No-op for English — English already defaults to flash.
  • An explicit voice: { model } always wins over flash. Use flash: true for the common "I want the cheap fast model" case; use the model field when you need a specific model id.
  • Works per-channel too: phoneNumbers: [{ number, language: "es", flash: true }].

Override the model with the optional model field — it always wins over both the auto-default and flash:

voice: {
  provider: "elevenlabs",
  voice_id: "JBFqnCBsd6RMkjVDRZzb",
  model: "eleven_multilingual_v2",  // or "eleven_flash_v2_5" / "eleven_turbo_v2_5"
}

The model is part of the voice config, so it hot-reloads with it — agent.update({ voice }) and a same-provider call.update({ voice }) keep the model/language already in effect unless you pass a new one.

Tuning notes:

  • stability higher = more consistent, less expressive
  • similarity_boost higher = closer to the cloned voice
  • style 0–1, adds expressiveness (slight latency cost)

Cartesia#

voice: {
  provider: "cartesia",
  voice_id: "a0e99841-438c-4a64-b679-ae501e7d6091",
  model: "sonic-3.5",   // latest; also "sonic-3" / "sonic-latest"
  speed: 1.0,
  volume: 1.0,
  emotion: null,
  language: "en",
}

Shortcut: "cartesia/yumiko"

Tuning notes:

  • model: "sonic-3.5" — latest/fastest Cartesia model (sub-90ms, 42 languages), designed for streaming. sonic-3 and sonic-latest also available.
  • emotion accepts named emotion presets (check Cartesia docs for the current list)

AWS Polly#

voice: {
  provider: "polly",
  voice_id: "Joanna",
  engine: "neural",        // "neural" | "standard"
  language: "en-US",
  rate: "medium",          // "slow" | "medium" | "fast" | "+10%" / "-10%"
  volume: "medium",        // "soft" | "medium" | "loud" | "+6dB" / "-6dB"
  pitch: "+5%",            // standard engine only
}

Shortcut: "polly/joanna"

Tuning notes:

  • engine: "neural" is required for natural-sounding output. The older standard engine is robotic.
  • rate / volume accept named levels or relative values; pitch only applies to the standard engine.
  • Polly is the cheapest option but the least natural — fine for IVR-style flows, not for engaging conversation.

Rime (BYOK)#

Ultra-natural, expressive English. Requires your own Rime key.

voice: {
  provider: "rime",
  voice_id: "cove",      // Rime speaker id
  model: "mistv2",        // or "arcana" (most expressive)
  speed: 1.0,
}

Shortcut: "rime/cove"

Soniox (BYOK)#

Real-time TTS in 60+ languages. One Soniox key serves both Soniox TTS and STT. Requires your own Soniox key.

voice: {
  provider: "soniox",
  voice_id: "Adrian",   // Soniox voice name
  model: "tts-rt-v1",
  language: "en",
}

Shortcut: "soniox/Adrian"

xAI Grok (BYOK)#

Expressive Grok voices: ara, eve, leo, rex, sal. Uses the same xAI key as Grok LLM (XAI_API_KEY). Requires your own key.

voice: {
  provider: "xai",
  voice_id: "eve",   // ara | eve | leo | rex | sal
  speed: 1.0,
}

Shortcut: "xai/eve"

Which to choose#

ProviderBest forTrade-off
ElevenLabsMost natural-sounding outputHigher cost per character
CartesiaReal-time streaming, low latencySmaller voice library
PollyCheap IVR, simple flowsLess natural
RimeUltra-natural expressive EnglishBYOK only; English-focused
SonioxMultilingual (60+), single-vendor with Soniox STTBYOK only
xAI GrokExpressive Grok voices (ara/eve/leo/rex/sal)BYOK only

For most agents, start with ElevenLabs (eleven_flash_v2_5) or Cartesia (sonic-3.5). Use Polly only for high-volume, low-engagement flows.

Hot-reloading voices#

Voice can change at any time:

// Agent-wide
agent.update({ voice: "cartesia/blake" });

// One call only
call.update({ voice: "elevenlabs/daniel" });

// Per-channel override
agent.addPhoneNumber("+34911234567", {
  voice: "elevenlabs/valentina",
});

What's next#