Supafone Labs ยท Documentation

Dynamic Voice Catalog and Selection#

Supafone exposes one normalized voice catalog across Ultravox, Cartesia, ElevenLabs, and Inworld. Developers can discover the voices their account can actually use, filter them with stable fields, preview them, or ask Supafone to select one from a plain-language description.

The catalog is live. Supafone pages each connected provider API to exhaustion, normalizes the results, and caches the account-scoped result for 10 minutes. Provider additions therefore appear without an SDK release.

The Compatibility Rule#

A provider having a voice does not automatically mean that voice can run in every language on a live Supafone call. Supafone keeps three sets separate:

  1. native_language_codes: languages or locales advertised for that voice.
  2. model_language_codes: languages supported by its selected TTS model.
  3. runtime_supported_language_codes: the intersection of the TTS model and
  4. Ultravox's spoken-language set.

For a live call, the effective language set is:

text
provider model languages INTERSECT Ultravox spoken languages

Native language is then used for ranking. A cross-lingual model may speak a different supported language, but a voice native to the requested language is ranked higher because it generally gives better accent and speaker similarity.

Current Model Limits#

Verified against official provider documentation on 2026-08-09:

Provider modelProvider language coverageUltravox-compatible set
Ultravox Realtime2626
Cartesia Sonic 3.54226
Cartesia Sonic 34226
Cartesia Sonic 287
ElevenLabs Flash v2.53226
ElevenLabs Multilingual v22924
ElevenLabs v370+; 74 currently enumerated26
Inworld TTS-2200+ languages/locales; 15 GA plus tested experimental languages26
Inworld TTS 1.5 Max/Mini1513

documented_language_count_is_minimum distinguishes 70+ and 200+ from an exact count. enumerated_language_count reports how many base codes Supafone can explicitly expose from the provider's current documentation.

The API never assumes that an unknown model supports every language. Unknown provider/model combinations remain discoverable but have known: false and are not recommended as runtime-compatible until their capability is known.

Official references:

Inspect Capabilities#

TypeScript:

ts
const capabilities = await supafone.labs.voices.capabilities();

for (const provider of capabilities.providers) {
  for (const model of provider.models) {
    console.log(
      provider.provider,
      model.model,
      model.documented_language_count,
      model.ultravox_routing_language_count,
    );
  }
}

Python:

python
capabilities = supafone.labs.voices.capabilities()
for provider in capabilities["providers"]:
    for model in provider["models"]:
        print(
            provider["provider"],
            model["model"],
            model["documented_language_count"],
            model["ultravox_routing_language_count"],
        )

List and Filter Voices#

language means the voice's native/accent language. compatibleLanguage means the provider model and Ultravox can both run that language live.

ts
const catalog = await supafone.labs.voices.listAll({
  provider: "cartesia",
  language: "es-MX",
  compatibleLanguage: "es",
  gender: "female",
  voiceType: "customer_support",
  model: "sonic-3.5",
  configuredOnly: true,
});
python
catalog = supafone.labs.voices.list_all(
    provider="cartesia",
    language="es-MX",
    compatible_language="es",
    gender="female",
    voice_type="customer_support",
    model="sonic-3.5",
    configured_only=True,
)

Available filters are provider, search, language, compatible_language, gender, voice_type, model, runtime_provider, and configured_only. The endpoint is cursor-paginated; listAll() and list_all() safely follow every page.

Select from Plain Language#

Supafone searches both normalized fields and sanitized provider-native metadata. This means new provider labels, accent descriptors, use cases, and categories become searchable without adding a new regex for every field.

ts
const result = await supafone.labs.voices.recommend({
  description: "warm Puerto Rican Spanish female intake voice",
  language: "es-PR",
  voiceType: "warm_empathetic",
  configuredOnly: true,
  limit: 3,
});

const selected = result.matches[0].voice;
await supafone.labs.agents.createInbound({
  name: "Spanish intake",
  voice: supafone.labs.voices.selection(selected),
});

Agent Factory can resolve the preference in one request:

python
agent = supafone.labs.agents.create_inbound({
    "name": "Hindi patient intake",
    "preferredLanguage": "hi-IN",
    "voicePreference": {
        "description": "calm Hindi patient-support voice",
        "provider": "inworld",
        "configuredOnly": True,
    },
})

The backend stores the exact selected provider, voice ID, model, and fixed language hint. preferredLanguage applies for the whole call and supplies the default language filter for voicePreference. It does not enable live language or voice switching. Existing agents that specify a voice directly keep their current behavior; preference resolution is additive.

To use multiple catalog voices during the same Agent Factory call, opt into languageVoiceRouting and provide an ordered language list or explicit profiles. The server validates every selection against this live catalog before creating the agent. See Live Language and Voice Routing.

Normalized Voice Shape#

Every row includes:

Provider metadata is recursively sanitized and bounded. Supafone removes API keys, credentials, auth headers, tokens, cookies, signatures, binary/audio payloads, embeddings, emails, and account/user/owner/workspace identifiers before returning or indexing it.

Failure Isolation#

Provider calls run concurrently. If one provider is unavailable, its error is reported in errors while the other providers and safe fallback voices still load. Catalog cache keys are account-scoped hashes; raw provider keys are not returned in responses or written into catalog rows.

Live Verification Snapshot#

The non-secret smoke test on 2026-08-09 loaded 1,386 voices with no provider errors and no unknown-language rows:

SourceVoices
Ultravox account catalog239
Cartesia848
ElevenLabs24
Inworld269

It also synthesized real preview audio through Cartesia and Inworld. Counts are account-specific and will change as providers add or remove voices.

View raw Markdown