Skip to main content
Universal-3.5 Pro is our latest Voice AI model currently in preview. It delivers:
  • State-of-the-art transcription accuracy across 18 languages
  • Strong performance on accented English and seamless code-switching between supported languages
  • A more intelligent contextual prompting that reliably follows the context you provide — from a single topic label to a full description of your audio

Quickstart

Get started with Universal-3.5 Pro using the code below. This example transcribes a pre-recorded audio file and prints the transcript text to your terminal.
1
Install the required library
pip install requests
2
Create a new file main.py and paste the code below. Replace <YOUR_API_KEY> with your API key.
3
Run with python main.py.
import requests
import time

base_url = "https://api.assemblyai.com"
headers = {"authorization": "<YOUR_API_KEY>"}

data = {
    "audio_url": "https://assembly.ai/new-approved-medication",
    "language_detection": True,
    "speech_models": ["universal-3-5-pro"]
}

response = requests.post(base_url + "/v2/transcript", headers=headers, json=data)

if response.status_code != 200:
    print(f"Error: {response.status_code}, Response: {response.text}")
    response.raise_for_status()

transcript_response = response.json()
transcript_id = transcript_response["id"]
polling_endpoint = f"{base_url}/v2/transcript/{transcript_id}"

while True:
    transcript = requests.get(polling_endpoint, headers=headers).json()
    if transcript["status"] == "completed":
        print(transcript["text"])
        break
    elif transcript["status"] == "error":
        raise RuntimeError(f"Transcription failed: {transcript['error']}")
    else:
        time.sleep(3)

Code switching

Universal-3.5 Pro natively handles code switching across 18 languages — no prompt configuration needed. When speakers shift mid-sentence between languages like English and Spanish, French, Hindi or Mandarin, the model follows seamlessly, preserving exactly what was said without translating everything into a single language. See Universal-3.5 Pro code switching in action.
English <> French
I said something like, j'ai dit à mes étudiants que it's time to really pay attention to what the idea of code-switching is.
English <> Hindi
मेरा रुकने का तो बहुत मन है, but I have an exam to give tomorrow.
English <> Mandarin
But this sentence, 我父母不工作了, you can see the 了 at the end of the sentence indicates that the situation now, my parents don't work, is different from what it was before.

Contextual prompting

Universal-3.5 Pro is highly accurate out of the box, but for challenging audio like short clips with limited context, noisy environments, or audio with very niche references, providing a brief description in the prompt parameter can meaningfully improve accuracy. For example, this is a 2-second clip from a League of Legends pro interview: Without prompt:
And so look who I've been a dear.
With prompt:
In solo queue, I ban Azir.
import requests
import time

base_url = "https://api.assemblyai.com"
headers = {"authorization": "<YOUR_API_KEY>"}

data = {
    "audio_url": "https://assembly.ai/prompt-8",
    "language_detection": True,
    "speech_models": ["universal-3-5-pro"],
    "prompt": "League of Legend roles"
}

response = requests.post(base_url + "/v2/transcript", headers=headers, json=data)

if response.status_code != 200:
    print(f"Error: {response.status_code}, Response: {response.text}")
    response.raise_for_status()

transcript_response = response.json()
transcript_id = transcript_response["id"]
polling_endpoint = f"{base_url}/v2/transcript/{transcript_id}"

while True:
    transcript = requests.get(polling_endpoint, headers=headers).json()
    if transcript["status"] == "completed":
        print(transcript["text"])
        break
    elif transcript["status"] == "error":
        raise RuntimeError(f"Transcription failed: {transcript['error']}")
    else:
        time.sleep(3)

Prompting guide

Contextual prompts work at three levels of specificity. Use the least specific level that covers your use case, and add detail when your audio contains uncommon names or terms the model can’t otherwise know.
LevelLengthWhat it containsExample
Domain2–5 wordsThe domain onlyMedical consultation call.
Scenario5–15 wordsWhat the conversation is aboutCardiology consultation about chest pain symptoms.
Detailed20–50 wordsFull description, including names, products, or identifiersCardiology consultation between Dr. Smith and an elderly patient regarding recurring chest pain, ECG results, and medication adjustment for hypertension.
Guidelines for writing contextual prompts:
  • Write plain, complete sentences that describe the audio
  • Keep it to one short block of text. Don’t pack lists of keywords into the contextual prompt

Keyterms prompting

Universal-3.5 Pro has strong out-of-the-box vocabulary coverage, so in many cases you won’t need keyterms prompting at all. But when you’re dealing with highly specific names, brands, acronyms, or niche industry jargon, the keyterms_prompt parameter gives you an extra layer of control. You can pass up to 1,000 words or phrases (max 6 words per phrase) to boost recognition for those terms and contextually similar variations. See keyterms prompt in action: Without keyterms prompting:
Hi, this is Kelly Byrne Donahue
With keyterms prompting:
Hi, this is Kelly Byrne-Donoghue
import requests
import time

base_url = "https://api.assemblyai.com"
headers = {"authorization": "<YOUR_API_KEY>"}

data = {
    "audio_url": "https://assemblyaiassets.com/audios/keyterms_prompting.wav",
    "language_detection": True,
    "speech_models": ["universal-3-5-pro"],
    "keyterms_prompt": ["Kelly Byrne-Donoghue"]
}

response = requests.post(base_url + "/v2/transcript", headers=headers, json=data)

if response.status_code != 200:
    print(f"Error: {response.status_code}, Response: {response.text}")
    response.raise_for_status()

transcript_response = response.json()
transcript_id = transcript_response["id"]
polling_endpoint = f"{base_url}/v2/transcript/{transcript_id}"

while True:
    transcript = requests.get(polling_endpoint, headers=headers).json()
    if transcript["status"] == "completed":
        print(transcript["text"])
        break
    elif transcript["status"] == "error":
        raise RuntimeError(f"Transcription failed: {transcript['error']}")
    else:
        time.sleep(3)

Support for 99 languages

Universal-3.5 Pro supports 18 languages, and for anything outside that set, the system automatically falls back to Universal-2, giving you coverage across 99 languages total without any extra configuration.
ModelSupported languages
universal-3-5-proGlobal English, Australian English, British English, US English, Spanish, French, German, Italian, Portuguese, Arabic, Danish, Dutch, Finnish, Hebrew, Hindi, Japanese, Mandarin, Norwegian, Swedish, Turkish, Vietnamese
universal-2Global English, Australian English, British English, US English, Spanish, French, German, Italian, Portuguese, Dutch, Hindi, Japanese, Chinese, Finnish, Korean, Polish, Russian, Turkish, Ukrainian, Vietnamese, Afrikaans, Albanian, Amharic, Arabic, Armenian, Assamese, Azerbaijani, Bashkir, Basque, Belarusian, Bengali, Bosnian, Breton, Bulgarian, Burmese, Catalan, Croatian, Czech, Danish, Estonian, Faroese, Galician, Georgian, Greek, Gujarati, Haitian, Hausa, Hawaiian, Hebrew, Hungarian, Icelandic, Indonesian, Javanese, Kannada, Kazakh, Khmer, Lao, Latin, Latvian, Lingala, Lithuanian, Luxembourgish, Macedonian, Malagasy, Malay, Malayalam, Maltese, Maori, Marathi, Mongolian, Nepali, Norwegian, Norwegian Nynorsk, Occitan, Panjabi, Pashto, Persian, Romanian, Sanskrit, Serbian, Shona, Sindhi, Sinhala, Slovak, Slovenian, Somali, Sundanese, Swahili, Swedish, Swiss German, Tagalog, Tajik, Tamil, Tatar, Telugu, Thai, Tibetan, Turkmen, Urdu, Uzbek, Welsh