diff --git a/docs/my-website/docs/pass_through/assembly_ai.md b/docs/my-website/docs/pass_through/assembly_ai.md
index 4606640c5c4..c7c70639e7e 100644
--- a/docs/my-website/docs/pass_through/assembly_ai.md
+++ b/docs/my-website/docs/pass_through/assembly_ai.md
@@ -1,31 +1,36 @@
-# Assembly AI
+# AssemblyAI
-Pass-through endpoints for Assembly AI - call Assembly AI endpoints, in native format (no translation).
+Pass-through endpoints for AssemblyAI - call AssemblyAI endpoints, in native format (no translation).
-| Feature | Supported | Notes |
+| Feature | Supported | Notes |
|-------|-------|-------|
| Cost Tracking | ✅ | works across all integrations |
| Logging | ✅ | works across all integrations |
-Supports **ALL** Assembly AI Endpoints
+Supports **ALL** AssemblyAI Endpoints
-[**See All Assembly AI Endpoints**](https://www.assemblyai.com/docs/api-reference)
+[**See All AssemblyAI Endpoints**](https://www.assemblyai.com/docs/api-reference)
-
+## Supported Routes
+
+| AssemblyAI Service | LiteLLM Route | AssemblyAI Base URL |
+|-------------------|---------------|---------------------|
+| Speech-to-Text (US) | `/assemblyai/*` | `api.assemblyai.com` |
+| Speech-to-Text (EU) | `/eu.assemblyai/*` | `eu.api.assemblyai.com` |
## Quick Start
-Let's call the Assembly AI [`/v2/transcripts` endpoint](https://www.assemblyai.com/docs/api-reference/transcripts)
+Let's call the AssemblyAI [`/v2/transcripts` endpoint](https://www.assemblyai.com/docs/api-reference/transcripts)
-1. Add Assembly AI API Key to your environment
+1. Add AssemblyAI API Key to your environment
```bash
export ASSEMBLYAI_API_KEY=""
```
-2. Start LiteLLM Proxy
+2. Start LiteLLM Proxy
```bash
litellm
@@ -33,53 +38,157 @@ litellm
# RUNNING on http://0.0.0.0:4000
```
-3. Test it!
+3. Test it!
-Let's call the Assembly AI `/v2/transcripts` endpoint
+Let's call the AssemblyAI [`/v2/transcripts` endpoint](https://www.assemblyai.com/docs/api-reference/transcripts). Includes commented-out [Speech Understanding](https://www.assemblyai.com/docs/speech-understanding) features you can toggle on.
```python
import assemblyai as aai
-LITELLM_VIRTUAL_KEY = "sk-1234" #
-LITELLM_PROXY_BASE_URL = "http://0.0.0.0:4000/assemblyai" # /assemblyai
+aai.settings.base_url = "http://0.0.0.0:4000/assemblyai" # /assemblyai
+aai.settings.api_key = "Bearer sk-1234" # Bearer
-aai.settings.api_key = f"Bearer {LITELLM_VIRTUAL_KEY}"
-aai.settings.base_url = LITELLM_PROXY_BASE_URL
+# Use a publicly-accessible URL
+audio_file = "https://assembly.ai/wildfires.mp3"
-# URL of the file to transcribe
-FILE_URL = "https://assembly.ai/wildfires.mp3"
+# Or use a local file:
+# audio_file = "./example.mp3"
-# You can also transcribe a local file by passing in a file path
-# FILE_URL = './path/to/file.mp3'
+config = aai.TranscriptionConfig(
+ speech_models=["universal-3-pro", "universal-2"],
+ language_detection=True,
+ speaker_labels=True,
+ # Speech understanding features
+ # sentiment_analysis=True,
+ # entity_detection=True,
+ # auto_chapters=True,
+ # summarization=True,
+ # summary_type=aai.SummarizationType.bullets,
+ # redact_pii=True,
+ # content_safety=True,
+)
-transcriber = aai.Transcriber()
-transcript = transcriber.transcribe(FILE_URL)
-print(transcript)
-print(transcript.id)
-```
+transcript = aai.Transcriber().transcribe(audio_file, config=config)
-## Calling Assembly AI EU endpoints
+if transcript.status == aai.TranscriptStatus.error:
+ raise RuntimeError(f"Transcription failed: {transcript.error}")
-If you want to send your request to the Assembly AI EU endpoint, you can do so by setting the `LITELLM_PROXY_BASE_URL` to `/eu.assemblyai`
+print(f"\nFull Transcript:\n\n{transcript.text}")
+# Optionally print speaker diarization results
+# for utterance in transcript.utterances:
+# print(f"Speaker {utterance.speaker}: {utterance.text}")
+```
+
+4. [Prompting with Universal-3 Pro](https://www.assemblyai.com/docs/speech-to-text/prompting) (optional)
```python
import assemblyai as aai
-LITELLM_VIRTUAL_KEY = "sk-1234" #
-LITELLM_PROXY_BASE_URL = "http://0.0.0.0:4000/eu.assemblyai" # /eu.assemblyai
+aai.settings.base_url = "http://0.0.0.0:4000/assemblyai" # /assemblyai
+aai.settings.api_key = "Bearer sk-1234" # Bearer
+
+audio_file = "https://assemblyaiassets.com/audios/verbatim.mp3"
+
+config = aai.TranscriptionConfig(
+ speech_models=["universal-3-pro", "universal-2"],
+ language_detection=True,
+ prompt="Produce a transcript suitable for conversational analysis. Every disfluency is meaningful data. Include: fillers (um, uh, er, ah, hmm, mhm, like, you know, I mean), repetitions (I I, the the), restarts (I was- I went), stutters (th-that, b-but, no-not), and informal speech (gonna, wanna, gotta)",
+)
+
+transcript = aai.Transcriber().transcribe(audio_file, config)
+
+print(transcript.text)
+```
+
+## Calling AssemblyAI EU endpoints
+
+If you want to send your request to the AssemblyAI EU endpoint, you can do so by setting the `LITELLM_PROXY_BASE_URL` to `/eu.assemblyai`
-aai.settings.api_key = f"Bearer {LITELLM_VIRTUAL_KEY}"
-aai.settings.base_url = LITELLM_PROXY_BASE_URL
-# URL of the file to transcribe
-FILE_URL = "https://assembly.ai/wildfires.mp3"
+```python
+import assemblyai as aai
+
+aai.settings.base_url = "http://0.0.0.0:4000/eu.assemblyai" # /eu.assemblyai
+aai.settings.api_key = "Bearer sk-1234" # Bearer
-# You can also transcribe a local file by passing in a file path
-# FILE_URL = './path/to/file.mp3'
+# Use a publicly-accessible URL
+audio_file = "https://assembly.ai/wildfires.mp3"
+
+# Or use a local file:
+# audio_file = "./path/to/file.mp3"
transcriber = aai.Transcriber()
-transcript = transcriber.transcribe(FILE_URL)
+transcript = transcriber.transcribe(audio_file)
print(transcript)
print(transcript.id)
```
+
+## LLM Gateway
+
+Use AssemblyAI's [LLM Gateway](https://www.assemblyai.com/docs/llm-gateway) as an OpenAI-compatible provider — a unified API for Claude, GPT, and Gemini models with full LiteLLM logging, guardrails, and cost tracking support.
+
+[**See Available Models**](https://www.assemblyai.com/docs/llm-gateway#available-models)
+
+### Usage
+
+#### LiteLLM Python SDK
+
+```python
+import litellm
+import os
+
+os.environ["ASSEMBLYAI_API_KEY"] = "your-assemblyai-api-key"
+
+response = litellm.completion(
+ model="assemblyai/claude-sonnet-4-5-20250929",
+ messages=[{"role": "user", "content": "What is the capital of France?"}]
+)
+
+print(response.choices[0].message.content)
+```
+
+#### LiteLLM Proxy
+
+1. Config
+
+```yaml
+model_list:
+ - model_name: assemblyai/*
+ litellm_params:
+ model: assemblyai/*
+ api_key: os.environ/ASSEMBLYAI_API_KEY
+```
+
+2. Start proxy
+
+```bash
+litellm --config config.yaml
+
+# RUNNING on http://0.0.0.0:4000
+```
+
+3. Test it!
+
+```python
+import requests
+
+headers = {
+ "authorization": "Bearer sk-1234" # Bearer
+}
+
+response = requests.post(
+ "http://0.0.0.0:4000/v1/chat/completions",
+ headers=headers,
+ json={
+ "model": "assemblyai/claude-sonnet-4-5-20250929",
+ "messages": [
+ {"role": "user", "content": "What is the capital of France?"}
+ ],
+ "max_tokens": 1000
+ }
+)
+
+result = response.json()
+print(result["choices"][0]["message"]["content"])
+```
diff --git a/litellm/llms/openai_like/providers.json b/litellm/llms/openai_like/providers.json
index 1b1b1c2f8cc..b3125d4ad38 100644
--- a/litellm/llms/openai_like/providers.json
+++ b/litellm/llms/openai_like/providers.json
@@ -90,5 +90,9 @@
"headers": {
"api-subscription-key": "{api_key}"
}
+ },
+ "assemblyai": {
+ "base_url": "https://llm-gateway.assemblyai.com/v1",
+ "api_key_env": "ASSEMBLYAI_API_KEY"
}
}
diff --git a/tests/litellm/llms/openai_like/test_assemblyai_provider.py b/tests/litellm/llms/openai_like/test_assemblyai_provider.py
new file mode 100644
index 00000000000..7eee810b271
--- /dev/null
+++ b/tests/litellm/llms/openai_like/test_assemblyai_provider.py
@@ -0,0 +1,77 @@
+"""
+Unit tests for the AssemblyAI LLM Gateway OpenAI-like provider.
+"""
+
+import os
+import sys
+
+sys.path.insert(
+ 0, os.path.abspath(os.path.join(os.path.dirname(__file__), "../../../.."))
+)
+
+from litellm.llms.openai_like.dynamic_config import create_config_class
+from litellm.llms.openai_like.json_loader import JSONProviderRegistry
+
+ASSEMBLYAI_BASE_URL = "https://llm-gateway.assemblyai.com/v1"
+
+
+def _get_config():
+ provider = JSONProviderRegistry.get("assemblyai")
+ assert provider is not None
+ config_class = create_config_class(provider)
+ return config_class()
+
+
+def test_assemblyai_provider_registered():
+ provider = JSONProviderRegistry.get("assemblyai")
+ assert provider is not None
+ assert provider.base_url == ASSEMBLYAI_BASE_URL
+ assert provider.api_key_env == "ASSEMBLYAI_API_KEY"
+
+
+def test_assemblyai_resolves_env_api_key(monkeypatch):
+ config = _get_config()
+ monkeypatch.setenv("ASSEMBLYAI_API_KEY", "test-key")
+ api_base, api_key = config._get_openai_compatible_provider_info(None, None)
+ assert api_base == ASSEMBLYAI_BASE_URL
+ assert api_key == "test-key"
+
+
+def test_assemblyai_complete_url_appends_endpoint():
+ config = _get_config()
+ url = config.get_complete_url(
+ api_base=ASSEMBLYAI_BASE_URL,
+ api_key="test-key",
+ model="assemblyai/claude-sonnet-4-5-20250929",
+ optional_params={},
+ litellm_params={},
+ stream=False,
+ )
+ assert url == f"{ASSEMBLYAI_BASE_URL}/chat/completions"
+
+
+def test_assemblyai_provider_resolution():
+ from litellm.litellm_core_utils.get_llm_provider_logic import get_llm_provider
+
+ model, provider, api_key, api_base = get_llm_provider(
+ model="assemblyai/claude-sonnet-4-5-20250929",
+ custom_llm_provider=None,
+ api_base=None,
+ api_key=None,
+ )
+
+ assert model == "claude-sonnet-4-5-20250929"
+ assert provider == "assemblyai"
+ assert api_base == ASSEMBLYAI_BASE_URL
+
+
+def test_assemblyai_provider_config_manager():
+ from litellm import LlmProviders
+ from litellm.utils import ProviderConfigManager
+
+ config = ProviderConfigManager.get_provider_chat_config(
+ model="claude-sonnet-4-5-20250929", provider=LlmProviders.ASSEMBLYAI
+ )
+
+ assert config is not None
+ assert config.custom_llm_provider == "assemblyai"