diff --git a/docs/my-website/docs/providers/watsonx.md b/docs/my-website/docs/providers/watsonx.md
deleted file mode 100644
index 23d8d259ac..0000000000
--- a/docs/my-website/docs/providers/watsonx.md
+++ /dev/null
@@ -1,287 +0,0 @@
-import Tabs from '@theme/Tabs';
-import TabItem from '@theme/TabItem';
-
-# IBM watsonx.ai
-
-LiteLLM supports all IBM [watsonx.ai](https://watsonx.ai/) foundational models and embeddings.
-
-## Environment Variables
-```python
-os.environ["WATSONX_URL"] = "" # (required) Base URL of your WatsonX instance
-# (required) either one of the following:
-os.environ["WATSONX_APIKEY"] = "" # IBM cloud API key
-os.environ["WATSONX_TOKEN"] = "" # IAM auth token
-# optional - can also be passed as params to completion() or embedding()
-os.environ["WATSONX_PROJECT_ID"] = "" # Project ID of your WatsonX instance
-os.environ["WATSONX_DEPLOYMENT_SPACE_ID"] = "" # ID of your deployment space to use deployed models
-os.environ["WATSONX_ZENAPIKEY"] = "" # Zen API key (use for long-term api token)
-```
-
-See [here](https://cloud.ibm.com/apidocs/watsonx-ai#api-authentication) for more information on how to get an access token to authenticate to watsonx.ai.
-
-## Usage
-
-
-
-
-
-```python
-import os
-from litellm import completion
-
-os.environ["WATSONX_URL"] = ""
-os.environ["WATSONX_APIKEY"] = ""
-
-## Call WATSONX `/text/chat` endpoint - supports function calling
-response = completion(
- model="watsonx/meta-llama/llama-3-1-8b-instruct",
- messages=[{ "content": "what is your favorite colour?","role": "user"}],
- project_id="" # or pass with os.environ["WATSONX_PROJECT_ID"]
-)
-
-## Call WATSONX `/text/generation` endpoint - not all models support /chat route.
-response = completion(
- model="watsonx/ibm/granite-13b-chat-v2",
- messages=[{ "content": "what is your favorite colour?","role": "user"}],
- project_id=""
-)
-```
-
-## Usage - Streaming
-```python
-import os
-from litellm import completion
-
-os.environ["WATSONX_URL"] = ""
-os.environ["WATSONX_APIKEY"] = ""
-os.environ["WATSONX_PROJECT_ID"] = ""
-
-response = completion(
- model="watsonx/meta-llama/llama-3-1-8b-instruct",
- messages=[{ "content": "what is your favorite colour?","role": "user"}],
- stream=True
-)
-for chunk in response:
- print(chunk)
-```
-
-#### Example Streaming Output Chunk
-```json
-{
- "choices": [
- {
- "finish_reason": null,
- "index": 0,
- "delta": {
- "content": "I don't have a favorite color, but I do like the color blue. What's your favorite color?"
- }
- }
- ],
- "created": null,
- "model": "watsonx/ibm/granite-13b-chat-v2",
- "usage": {
- "prompt_tokens": null,
- "completion_tokens": null,
- "total_tokens": null
- }
-}
-```
-
-## Usage - Models in deployment spaces
-
-Models that have been deployed to a deployment space (e.g.: tuned models) can be called using the `deployment/` format (where `` is the ID of the deployed model in your deployment space).
-
-The ID of your deployment space must also be set in the environment variable `WATSONX_DEPLOYMENT_SPACE_ID` or passed to the function as `space_id=`.
-
-```python
-import litellm
-response = litellm.completion(
- model="watsonx/deployment/",
- messages=[{"content": "Hello, how are you?", "role": "user"}],
- space_id=""
-)
-```
-
-## Usage - Embeddings
-
-LiteLLM also supports making requests to IBM watsonx.ai embedding models. The credential needed for this is the same as for completion.
-
-```python
-from litellm import embedding
-
-response = embedding(
- model="watsonx/ibm/slate-30m-english-rtrvr",
- input=["What is the capital of France?"],
- project_id=""
-)
-print(response)
-# EmbeddingResponse(model='ibm/slate-30m-english-rtrvr', data=[{'object': 'embedding', 'index': 0, 'embedding': [-0.037463713, -0.02141933, -0.02851813, 0.015519324, ..., -0.0021367231, -0.01704561, -0.001425816, 0.0035238306]}], object='list', usage=Usage(prompt_tokens=8, total_tokens=8))
-```
-
-## OpenAI Proxy Usage
-
-Here's how to call IBM watsonx.ai with the LiteLLM Proxy Server
-
-### 1. Save keys in your environment
-
-```bash
-export WATSONX_URL=""
-export WATSONX_APIKEY=""
-export WATSONX_PROJECT_ID=""
-```
-
-### 2. Start the proxy
-
-
-
-
-```bash
-$ litellm --model watsonx/meta-llama/llama-3-8b-instruct
-
-# Server running on http://0.0.0.0:4000
-```
-
-
-
-
-```yaml
-model_list:
- - model_name: llama-3-8b
- litellm_params:
- # all params accepted by litellm.completion()
- model: watsonx/meta-llama/llama-3-8b-instruct
- api_key: "os.environ/WATSONX_API_KEY" # does os.getenv("WATSONX_API_KEY")
-```
-
-
-
-### 3. Test it
-
-
-
-
-
-```shell
-curl --location 'http://0.0.0.0:4000/chat/completions' \
---header 'Content-Type: application/json' \
---data ' {
- "model": "llama-3-8b",
- "messages": [
- {
- "role": "user",
- "content": "what is your favorite colour?"
- }
- ]
- }
-'
-```
-
-
-
-```python
-import openai
-client = openai.OpenAI(
- api_key="anything",
- base_url="http://0.0.0.0:4000"
-)
-
-# request sent to model set on litellm proxy, `litellm --model`
-response = client.chat.completions.create(model="llama-3-8b", messages=[
- {
- "role": "user",
- "content": "what is your favorite colour?"
- }
-])
-
-print(response)
-
-```
-
-
-
-```python
-from langchain.chat_models import ChatOpenAI
-from langchain.prompts.chat import (
- ChatPromptTemplate,
- HumanMessagePromptTemplate,
- SystemMessagePromptTemplate,
-)
-from langchain.schema import HumanMessage, SystemMessage
-
-chat = ChatOpenAI(
- openai_api_base="http://0.0.0.0:4000", # set openai_api_base to the LiteLLM Proxy
- model = "llama-3-8b",
- temperature=0.1
-)
-
-messages = [
- SystemMessage(
- content="You are a helpful assistant that im using to make a test request to."
- ),
- HumanMessage(
- content="test from litellm. tell me why it's amazing in 1 sentence"
- ),
-]
-response = chat(messages)
-
-print(response)
-```
-
-
-
-
-## Authentication
-
-### Passing credentials as parameters
-
-You can also pass the credentials as parameters to the completion and embedding functions.
-
-```python
-import os
-from litellm import completion
-
-response = completion(
- model="watsonx/ibm/granite-13b-chat-v2",
- messages=[{ "content": "What is your favorite color?","role": "user"}],
- url="",
- api_key="",
- project_id=""
-)
-```
-
-
-## Supported IBM watsonx.ai Models
-
-Here are some examples of models available in IBM watsonx.ai that you can use with LiteLLM:
-
-| Mode Name | Command |
-|------------------------------------|------------------------------------------------------------------------------------------|
-| Flan T5 XXL | `completion(model=watsonx/google/flan-t5-xxl, messages=messages)` |
-| Flan Ul2 | `completion(model=watsonx/google/flan-ul2, messages=messages)` |
-| Mt0 XXL | `completion(model=watsonx/bigscience/mt0-xxl, messages=messages)` |
-| Gpt Neox | `completion(model=watsonx/eleutherai/gpt-neox-20b, messages=messages)` |
-| Mpt 7B Instruct2 | `completion(model=watsonx/ibm/mpt-7b-instruct2, messages=messages)` |
-| Starcoder | `completion(model=watsonx/bigcode/starcoder, messages=messages)` |
-| Llama 2 70B Chat | `completion(model=watsonx/meta-llama/llama-2-70b-chat, messages=messages)` |
-| Llama 2 13B Chat | `completion(model=watsonx/meta-llama/llama-2-13b-chat, messages=messages)` |
-| Granite 13B Instruct | `completion(model=watsonx/ibm/granite-13b-instruct-v1, messages=messages)` |
-| Granite 13B Chat | `completion(model=watsonx/ibm/granite-13b-chat-v1, messages=messages)` |
-| Flan T5 XL | `completion(model=watsonx/google/flan-t5-xl, messages=messages)` |
-| Granite 13B Chat V2 | `completion(model=watsonx/ibm/granite-13b-chat-v2, messages=messages)` |
-| Granite 13B Instruct V2 | `completion(model=watsonx/ibm/granite-13b-instruct-v2, messages=messages)` |
-| Elyza Japanese Llama 2 7B Instruct | `completion(model=watsonx/elyza/elyza-japanese-llama-2-7b-instruct, messages=messages)` |
-| Mixtral 8X7B Instruct V01 Q | `completion(model=watsonx/ibm-mistralai/mixtral-8x7b-instruct-v01-q, messages=messages)` |
-
-
-For a list of all available models in watsonx.ai, see [here](https://dataplatform.cloud.ibm.com/docs/content/wsj/analyze-data/fm-models.html?context=wx&locale=en&audience=wdp).
-
-
-## Supported IBM watsonx.ai Embedding Models
-
-| Model Name | Function Call |
-|------------|------------------------------------------------------------------------|
-| Slate 30m | `embedding(model="watsonx/ibm/slate-30m-english-rtrvr", input=input)` |
-| Slate 125m | `embedding(model="watsonx/ibm/slate-125m-english-rtrvr", input=input)` |
-
-
-For a list of all available embedding models in watsonx.ai, see [here](https://dataplatform.cloud.ibm.com/docs/content/wsj/analyze-data/fm-models-embed.html?context=wx).
\ No newline at end of file
diff --git a/docs/my-website/docs/providers/watsonx/audio_transcription.md b/docs/my-website/docs/providers/watsonx/audio_transcription.md
new file mode 100644
index 0000000000..37b4bb438a
--- /dev/null
+++ b/docs/my-website/docs/providers/watsonx/audio_transcription.md
@@ -0,0 +1,57 @@
+# WatsonX Audio Transcription
+
+## Overview
+
+| Property | Details |
+|----------|---------|
+| Description | WatsonX audio transcription using Whisper models for speech-to-text |
+| Provider Route on LiteLLM | `watsonx/` |
+| Supported Operations | `/v1/audio/transcriptions` |
+| Link to Provider Doc | [IBM WatsonX.ai ↗](https://www.ibm.com/watsonx) |
+
+## Quick Start
+
+### **LiteLLM SDK**
+
+```python showLineNumbers title="transcription.py"
+import litellm
+
+response = litellm.transcription(
+ model="watsonx/whisper-large-v3-turbo",
+ file=open("audio.mp3", "rb"),
+ api_base="https://us-south.ml.cloud.ibm.com",
+ api_key="your-api-key",
+ project_id="your-project-id"
+)
+print(response.text)
+```
+
+### **LiteLLM Proxy**
+
+```yaml showLineNumbers title="config.yaml"
+model_list:
+ - model_name: whisper-large-v3-turbo
+ litellm_params:
+ model: watsonx/whisper-large-v3-turbo
+ api_key: os.environ/WATSONX_APIKEY
+ api_base: os.environ/WATSONX_URL
+ project_id: os.environ/WATSONX_PROJECT_ID
+```
+
+```bash title="Request"
+curl http://localhost:4000/v1/audio/transcriptions \
+ -H "Authorization: Bearer sk-1234" \
+ -F file="@audio.mp3" \
+ -F model="whisper-large-v3-turbo"
+```
+
+## Supported Parameters
+
+| Parameter | Type | Description |
+|-----------|------|-------------|
+| `model` | string | Model ID (e.g., `watsonx/whisper-large-v3-turbo`) |
+| `file` | file | Audio file to transcribe |
+| `language` | string | Language code (e.g., `en`) |
+| `prompt` | string | Optional prompt to guide transcription |
+| `temperature` | float | Sampling temperature (0-1) |
+| `response_format` | string | `json`, `text`, `srt`, `verbose_json`, `vtt` |
diff --git a/docs/my-website/docs/providers/watsonx/index.md b/docs/my-website/docs/providers/watsonx/index.md
new file mode 100644
index 0000000000..279d2d1024
--- /dev/null
+++ b/docs/my-website/docs/providers/watsonx/index.md
@@ -0,0 +1,177 @@
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+# IBM watsonx.ai
+
+LiteLLM supports all IBM [watsonx.ai](https://watsonx.ai/) foundational models and embeddings.
+
+## Environment Variables
+```python
+os.environ["WATSONX_URL"] = "" # (required) Base URL of your WatsonX instance
+# (required) either one of the following:
+os.environ["WATSONX_APIKEY"] = "" # IBM cloud API key
+os.environ["WATSONX_TOKEN"] = "" # IAM auth token
+# optional - can also be passed as params to completion() or embedding()
+os.environ["WATSONX_PROJECT_ID"] = "" # Project ID of your WatsonX instance
+os.environ["WATSONX_DEPLOYMENT_SPACE_ID"] = "" # ID of your deployment space to use deployed models
+os.environ["WATSONX_ZENAPIKEY"] = "" # Zen API key (use for long-term api token)
+```
+
+See [here](https://cloud.ibm.com/apidocs/watsonx-ai#api-authentication) for more information on how to get an access token to authenticate to watsonx.ai.
+
+## Usage
+
+
+
+
+
+```python showLineNumbers title="Chat Completion"
+import os
+from litellm import completion
+
+os.environ["WATSONX_URL"] = ""
+os.environ["WATSONX_APIKEY"] = ""
+
+response = completion(
+ model="watsonx/meta-llama/llama-3-1-8b-instruct",
+ messages=[{ "content": "what is your favorite colour?","role": "user"}],
+ project_id=""
+)
+```
+
+## Usage - Streaming
+```python showLineNumbers title="Streaming"
+import os
+from litellm import completion
+
+os.environ["WATSONX_URL"] = ""
+os.environ["WATSONX_APIKEY"] = ""
+os.environ["WATSONX_PROJECT_ID"] = ""
+
+response = completion(
+ model="watsonx/meta-llama/llama-3-1-8b-instruct",
+ messages=[{ "content": "what is your favorite colour?","role": "user"}],
+ stream=True
+)
+for chunk in response:
+ print(chunk)
+```
+
+## Usage - Models in deployment spaces
+
+Models deployed to a deployment space (e.g.: tuned models) can be called using the `deployment/` format.
+
+```python showLineNumbers title="Deployment Space"
+import litellm
+
+response = litellm.completion(
+ model="watsonx/deployment/",
+ messages=[{"content": "Hello, how are you?", "role": "user"}],
+ space_id=""
+)
+```
+
+## Usage - Embeddings
+
+```python showLineNumbers title="Embeddings"
+from litellm import embedding
+
+response = embedding(
+ model="watsonx/ibm/slate-30m-english-rtrvr",
+ input=["What is the capital of France?"],
+ project_id=""
+)
+```
+
+## LiteLLM Proxy Usage
+
+### 1. Save keys in your environment
+
+```bash
+export WATSONX_URL=""
+export WATSONX_APIKEY=""
+export WATSONX_PROJECT_ID=""
+```
+
+### 2. Start the proxy
+
+
+
+
+```bash
+$ litellm --model watsonx/meta-llama/llama-3-8b-instruct
+```
+
+
+
+
+```yaml showLineNumbers title="config.yaml"
+model_list:
+ - model_name: llama-3-8b
+ litellm_params:
+ model: watsonx/meta-llama/llama-3-8b-instruct
+ api_key: "os.environ/WATSONX_API_KEY"
+```
+
+
+
+### 3. Test it
+
+
+
+
+
+```shell
+curl --location 'http://0.0.0.0:4000/chat/completions' \
+--header 'Content-Type: application/json' \
+--data '{
+ "model": "llama-3-8b",
+ "messages": [
+ {
+ "role": "user",
+ "content": "what is your favorite colour?"
+ }
+ ]
+ }'
+```
+
+
+
+```python showLineNumbers
+import openai
+
+client = openai.OpenAI(
+ api_key="anything",
+ base_url="http://0.0.0.0:4000"
+)
+
+response = client.chat.completions.create(
+ model="llama-3-8b",
+ messages=[{"role": "user", "content": "what is your favorite colour?"}]
+)
+print(response)
+```
+
+
+
+
+## Supported Models
+
+| Model Name | Command |
+|------------------------------------|------------------------------------------------------------------------------------------|
+| Llama 3.1 8B Instruct | `completion(model="watsonx/meta-llama/llama-3-1-8b-instruct", messages=messages)` |
+| Llama 2 70B Chat | `completion(model="watsonx/meta-llama/llama-2-70b-chat", messages=messages)` |
+| Granite 13B Chat V2 | `completion(model="watsonx/ibm/granite-13b-chat-v2", messages=messages)` |
+| Mixtral 8X7B Instruct | `completion(model="watsonx/ibm-mistralai/mixtral-8x7b-instruct-v01-q", messages=messages)` |
+
+For all available models, see [watsonx.ai documentation](https://dataplatform.cloud.ibm.com/docs/content/wsj/analyze-data/fm-models.html?context=wx).
+
+## Supported Embedding Models
+
+| Model Name | Function Call |
+|------------|------------------------------------------------------------------------|
+| Slate 30m | `embedding(model="watsonx/ibm/slate-30m-english-rtrvr", input=input)` |
+| Slate 125m | `embedding(model="watsonx/ibm/slate-125m-english-rtrvr", input=input)` |
+
+For all available embedding models, see [watsonx.ai embedding documentation](https://dataplatform.cloud.ibm.com/docs/content/wsj/analyze-data/fm-models-embed.html?context=wx).
+
diff --git a/docs/my-website/sidebars.js b/docs/my-website/sidebars.js
index e5eba82e32..b40a533337 100644
--- a/docs/my-website/sidebars.js
+++ b/docs/my-website/sidebars.js
@@ -633,7 +633,14 @@ const sidebars = {
"providers/volcano",
"providers/voyage",
"providers/wandb_inference",
- "providers/watsonx",
+ {
+ type: "category",
+ label: "WatsonX",
+ items: [
+ "providers/watsonx/index",
+ "providers/watsonx/audio_transcription",
+ ]
+ },
"providers/xai",
"providers/xinference",
],
diff --git a/litellm/__init__.py b/litellm/__init__.py
index 6431d78a53..3a715ff1df 100644
--- a/litellm/__init__.py
+++ b/litellm/__init__.py
@@ -1357,6 +1357,9 @@ from .llms.azure.chat.o_series_transformation import AzureOpenAIO1Config
from .llms.watsonx.completion.transformation import IBMWatsonXAIConfig
from .llms.watsonx.chat.transformation import IBMWatsonXChatConfig
from .llms.watsonx.embed.transformation import IBMWatsonXEmbeddingConfig
+from .llms.watsonx.audio_transcription.transformation import (
+ IBMWatsonXAudioTranscriptionConfig,
+)
from .llms.github_copilot.chat.transformation import GithubCopilotConfig
from .llms.github_copilot.responses.transformation import (
GithubCopilotResponsesAPIConfig,
diff --git a/litellm/llms/watsonx/audio_transcription/__init__.py b/litellm/llms/watsonx/audio_transcription/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/litellm/llms/watsonx/audio_transcription/transformation.py b/litellm/llms/watsonx/audio_transcription/transformation.py
new file mode 100644
index 0000000000..8c8324cb72
--- /dev/null
+++ b/litellm/llms/watsonx/audio_transcription/transformation.py
@@ -0,0 +1,78 @@
+"""
+Translates from OpenAI's `/v1/audio/transcriptions` to IBM WatsonX's `/ml/v1/audio/transcriptions`
+
+WatsonX follows the OpenAI spec for audio transcription.
+"""
+
+from typing import List, Optional
+
+import litellm
+from litellm.types.llms.openai import OpenAIAudioTranscriptionOptionalParams
+
+from ...openai.transcriptions.whisper_transformation import (
+ OpenAIWhisperAudioTranscriptionConfig,
+)
+from ..common_utils import IBMWatsonXMixin, _get_api_params
+
+
+class IBMWatsonXAudioTranscriptionConfig(
+ IBMWatsonXMixin, OpenAIWhisperAudioTranscriptionConfig
+):
+ """
+ IBM WatsonX Audio Transcription Config
+
+ WatsonX follows the OpenAI spec for audio transcription, so this class
+ inherits from OpenAIWhisperAudioTranscriptionConfig and uses IBMWatsonXMixin
+ for authentication and URL construction.
+ """
+
+ def get_supported_openai_params(
+ self, model: str
+ ) -> List[OpenAIAudioTranscriptionOptionalParams]:
+ """
+ Get the supported OpenAI params for WatsonX audio transcription.
+ """
+ return [
+ "language",
+ "prompt",
+ "response_format",
+ "temperature",
+ "timestamp_granularities",
+ ]
+
+ def get_complete_url(
+ self,
+ api_base: Optional[str],
+ api_key: Optional[str],
+ model: str,
+ optional_params: dict,
+ litellm_params: dict,
+ stream: Optional[bool] = None,
+ ) -> str:
+ """
+ Construct the complete URL for WatsonX audio transcription.
+
+ URL format: {api_base}/ml/v1/audio/transcriptions?version={version}&project_id={project_id}
+ """
+ # Get base URL
+ url = self._get_base_url(api_base=api_base)
+ url = url.rstrip("/")
+
+ # Add the audio transcription endpoint
+ url = f"{url}/ml/v1/audio/transcriptions"
+
+ # Get API params for project_id
+ api_params = _get_api_params(params=optional_params.copy())
+
+ # Add version parameter
+ api_version = optional_params.pop(
+ "api_version", None
+ ) or litellm.WATSONX_DEFAULT_API_VERSION
+ url = f"{url}?version={api_version}"
+
+ # Add project_id parameter
+ project_id = api_params.get("project_id")
+ if project_id:
+ url = f"{url}&project_id={project_id}"
+
+ return url
diff --git a/litellm/model_prices_and_context_window_backup.json b/litellm/model_prices_and_context_window_backup.json
index 1b1ebf936a..243b5318a3 100644
--- a/litellm/model_prices_and_context_window_backup.json
+++ b/litellm/model_prices_and_context_window_backup.json
@@ -26209,6 +26209,15 @@
"supports_parallel_function_calling": false,
"supports_vision": false
},
+ "watsonx/whisper-large-v3-turbo": {
+ "input_cost_per_second": 0.0001,
+ "output_cost_per_second": 0.0001,
+ "litellm_provider": "watsonx",
+ "mode": "audio_transcription",
+ "supported_endpoints": [
+ "/v1/audio/transcriptions"
+ ]
+ },
"whisper-1": {
"input_cost_per_second": 0.0001,
"litellm_provider": "openai",
diff --git a/litellm/utils.py b/litellm/utils.py
index 1d8f40af41..053368a3e0 100644
--- a/litellm/utils.py
+++ b/litellm/utils.py
@@ -7380,6 +7380,12 @@ class ProviderConfigManager:
)
return HostedVLLMAudioTranscriptionConfig()
+ elif litellm.LlmProviders.WATSONX == provider:
+ from litellm.llms.watsonx.audio_transcription.transformation import (
+ IBMWatsonXAudioTranscriptionConfig,
+ )
+
+ return IBMWatsonXAudioTranscriptionConfig()
return None
@staticmethod
diff --git a/model_prices_and_context_window.json b/model_prices_and_context_window.json
index 1b1ebf936a..243b5318a3 100644
--- a/model_prices_and_context_window.json
+++ b/model_prices_and_context_window.json
@@ -26209,6 +26209,15 @@
"supports_parallel_function_calling": false,
"supports_vision": false
},
+ "watsonx/whisper-large-v3-turbo": {
+ "input_cost_per_second": 0.0001,
+ "output_cost_per_second": 0.0001,
+ "litellm_provider": "watsonx",
+ "mode": "audio_transcription",
+ "supported_endpoints": [
+ "/v1/audio/transcriptions"
+ ]
+ },
"whisper-1": {
"input_cost_per_second": 0.0001,
"litellm_provider": "openai",
diff --git a/provider_endpoints_support.json b/provider_endpoints_support.json
index ff5017c9fc..e05d6d8d00 100644
--- a/provider_endpoints_support.json
+++ b/provider_endpoints_support.json
@@ -855,7 +855,7 @@
"responses": true,
"embeddings": true,
"image_generations": false,
- "audio_transcriptions": false,
+ "audio_transcriptions": true,
"audio_speech": false,
"moderations": false,
"batches": false,
diff --git a/tests/test_litellm/llms/watsonx/__init__.py b/tests/test_litellm/llms/watsonx/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/test_litellm/llms/watsonx/audio_transcription/__init__.py b/tests/test_litellm/llms/watsonx/audio_transcription/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/test_litellm/llms/watsonx/audio_transcription/test_watsonx_audio_transcription_transformation.py b/tests/test_litellm/llms/watsonx/audio_transcription/test_watsonx_audio_transcription_transformation.py
new file mode 100644
index 0000000000..84a9d25d98
--- /dev/null
+++ b/tests/test_litellm/llms/watsonx/audio_transcription/test_watsonx_audio_transcription_transformation.py
@@ -0,0 +1,102 @@
+"""
+Tests for IBM WatsonX Audio Transcription.
+
+Validates that litellm.transcription transforms requests correctly for WatsonX.
+"""
+
+import os
+import sys
+from unittest.mock import AsyncMock, MagicMock, patch
+
+import pytest
+
+sys.path.insert(0, os.path.abspath("../../../../.."))
+
+import litellm
+
+
+class TestWatsonXAudioTranscription:
+ """Tests for WatsonX audio transcription via litellm.transcription."""
+
+ @pytest.mark.asyncio
+ async def test_watsonx_transcription_url_and_headers(self):
+ """
+ Test that litellm.transcription sends request to correct WatsonX URL with proper headers.
+ """
+ captured_request = {}
+
+ async def mock_post(*args, **kwargs):
+ captured_request["url"] = str(kwargs.get("url", args[0] if args else None))
+ captured_request["headers"] = kwargs.get("headers", {})
+ captured_request["data"] = kwargs.get("data", {})
+
+ mock_response = MagicMock()
+ mock_response.json.return_value = {
+ "text": "test transcription",
+ "duration": 1.0,
+ }
+ mock_response.status_code = 200
+ return mock_response
+
+ with patch("litellm.llms.custom_httpx.http_handler.AsyncHTTPHandler.post", new=mock_post):
+ try:
+ await litellm.atranscription(
+ model="watsonx/whisper-large-v3-turbo",
+ file=b"fake_audio_data",
+ api_base="https://us-south.ml.cloud.ibm.com",
+ api_key="test-api-key",
+ project_id="test-project-123",
+ token="test-bearer-token",
+ )
+ except Exception:
+ pass # We just want to capture the request
+
+ # Validate URL contains WatsonX audio transcription endpoint
+ assert "/ml/v1/audio/transcriptions" in captured_request["url"]
+ assert "version=" in captured_request["url"]
+ assert "project_id=test-project-123" in captured_request["url"]
+
+ # Validate headers contain WatsonX auth
+ assert "Authorization" in captured_request["headers"]
+ assert "Bearer test-bearer-token" in captured_request["headers"]["Authorization"]
+
+ @pytest.mark.asyncio
+ async def test_watsonx_transcription_request_body(self):
+ """
+ Test that litellm.transcription sends correct request body for WatsonX.
+ """
+ captured_request = {}
+
+ async def mock_post(*args, **kwargs):
+ captured_request["data"] = kwargs.get("data", {})
+ captured_request["files"] = kwargs.get("files", {})
+
+ mock_response = MagicMock()
+ mock_response.json.return_value = {
+ "text": "test transcription",
+ "duration": 1.0,
+ }
+ mock_response.status_code = 200
+ return mock_response
+
+ with patch("litellm.llms.custom_httpx.http_handler.AsyncHTTPHandler.post", new=mock_post):
+ try:
+ await litellm.atranscription(
+ model="watsonx/whisper-large-v3-turbo",
+ file=b"fake_audio_data",
+ api_base="https://us-south.ml.cloud.ibm.com",
+ api_key="test-api-key",
+ project_id="test-project-123",
+ token="test-bearer-token",
+ language="en",
+ temperature=0.5,
+ )
+ except Exception:
+ pass # We just want to capture the request
+
+ # Validate request body contains expected fields
+ data = captured_request.get("data", {})
+ assert data.get("model") == "whisper-large-v3-turbo"
+ assert data.get("language") == "en"
+ assert data.get("temperature") == 0.5
+ assert data.get("response_format") == "verbose_json" # Default for cost calculation