This guide helps you migrate from Deepgram Python SDK v3+ (versions 3.0.0 to 4.8.1) to v5.0.0. The v5 release introduces significant improvements including better type safety, cleaner API design, and enhanced WebSocket functionality.
- Installation Changes
- Configuration Changes
- Authentication Changes
- API Method Changes
- Keep Alive Functionality
- Breaking Changes Summary
To upgrade from v3+ to v5.0.0:
pip install --upgrade deepgram-sdkfrom deepgram import DeepgramClient
# Basic initialization
deepgram = DeepgramClient("YOUR_API_KEY")
# With configuration
from deepgram import DeepgramClientOptions
config = DeepgramClientOptions(api_key="your-api-key")
client = DeepgramClient(config=config)from deepgram import DeepgramClient
# API key authentication (server-side)
client = DeepgramClient(api_key="YOUR_API_KEY")
# Access token authentication (recommended for client-side)
client = DeepgramClient(access_token="YOUR_ACCESS_TOKEN")
# Environment variable authentication
# Set DEEPGRAM_API_KEY or DEEPGRAM_TOKEN
client = DeepgramClient()
# With custom HTTP client
import httpx
client = DeepgramClient(
httpx_client=httpx.Client(
proxies="http://proxy.example.com",
timeout=httpx.Timeout(30.0)
)
)- v3+:
DEEPGRAM_API_KEY - v5.0.0:
DEEPGRAM_TOKEN(takes precedence) orDEEPGRAM_API_KEY
- Explicit
access_tokenparameter (highest priority) - Explicit
api_keyparameter DEEPGRAM_TOKENenvironment variableDEEPGRAM_API_KEYenvironment variable (lowest priority)
v3+ (3.0.0 - 4.8.1)
response = deepgram.auth.v("1").grant_token()v5.0.0
response = client.auth.v1.tokens.grant()
# With custom TTL
response = client.auth.v1.tokens.grant(ttl_seconds=60)In v5.0.0, there are two types of responses for transcription requests:
- Synchronous Response: When no callback is provided, returns the full transcription result immediately
- Asynchronous Response: When a callback URL is provided, returns a "listen accepted" response and sends the actual transcription to the callback URL
v3+ (3.0.0 - 4.8.1)
from deepgram import PrerecordedOptions, UrlSource
payload: UrlSource = {
"url": "https://dpgr.am/spacewalk.wav"
}
options = PrerecordedOptions(model="nova-3")
response = deepgram.listen.rest.v("1").transcribe_url(
payload,
options
)v5.0.0
# Returns the full transcription result immediately (synchronous)
response = client.listen.v1.media.transcribe_url(
url="https://dpgr.am/spacewalk.wav",
model="nova-3"
)v3+ (3.0.0 - 4.8.1)
from deepgram import PrerecordedOptions, FileSource
with open("path/to/your/audio.wav", "rb") as file:
buffer_data = file.read()
payload: FileSource = {
"buffer": buffer_data,
}
options = PrerecordedOptions(model="nova-3")
response = deepgram.listen.rest.v("1").transcribe_file(
payload,
options
)v5.0.0
# Returns the full transcription result immediately (synchronous)
with open("audio.wav", "rb") as audio_file:
response = client.listen.v1.media.transcribe_file(
request=audio_file.read(),
model="nova-3"
)v3+ (3.0.0 - 4.8.1)
response = deepgram.listen.rest.v("1").transcribe_url_callback(
payload,
"https://your-callback-url.com/webhook",
options=options
)v5.0.0
# Returns a listen accepted response (not the full transcription)
response = client.listen.v1.media.transcribe_url(
url="https://dpgr.am/spacewalk.wav",
callback="https://your-callback-url.com/webhook",
model="nova-3"
)
# The actual transcription will be sent to the callback URLv3+ (3.0.0 - 4.8.1)
response = deepgram.listen.rest.v("1").transcribe_file_callback(
payload,
"https://your-callback-url.com/webhook",
options=options
)v5.0.0
# Returns a listen accepted response (not the full transcription)
with open("audio.wav", "rb") as audio_file:
response = client.listen.v1.media.transcribe_file(
request=audio_file.read(),
callback="https://your-callback-url.com/webhook",
model="nova-3"
)
# The actual transcription will be sent to the callback URLv3+ (3.0.0 - 4.8.1)
from deepgram import LiveOptions, LiveTranscriptionEvents
connection = deepgram.listen.websocket.v("1")
@connection.on(LiveTranscriptionEvents.Transcript)
def handle_transcript(result):
print(result.channel.alternatives[0].transcript)
connection.start(LiveOptions(model="nova-3", language="en-US"))
connection.send(open("path/to/your/audio.wav", "rb").read())
connection.finish()v5.0.0
from deepgram.core.events import EventType
from deepgram.extensions.types.sockets import ListenV1SocketClientResponse
with client.listen.v1.connect(model="nova-3") as connection:
def on_message(message: ListenV1SocketClientResponse) -> None:
msg_type = getattr(message, "type", "Unknown")
print(f"Received {msg_type} event")
connection.on(EventType.OPEN, lambda _: print("Connection opened"))
connection.on(EventType.MESSAGE, on_message)
connection.on(EventType.CLOSE, lambda _: print("Connection closed"))
connection.on(EventType.ERROR, lambda error: print(f"Error: {error}"))
connection.start_listening()
# Read and send audio data
with open("path/to/your/audio.wav", "rb") as audio_file:
audio_bytes = audio_file.read()
from deepgram.extensions.types.sockets import ListenV1MediaMessage
connection.send_media(ListenV1MediaMessage(audio_bytes))v5.0.0
with client.listen.v2.connect(
model="flux-general-en",
encoding="linear16",
sample_rate="16000"
) as connection:
def on_message(message):
print(f"Received {message.type} event")
connection.on(EventType.OPEN, lambda _: print("Connection opened"))
connection.on(EventType.MESSAGE, on_message)
connection.on(EventType.CLOSE, lambda _: print("Connection closed"))
connection.on(EventType.ERROR, lambda error: print(f"Error: {error}"))
connection.start_listening()v3+ (3.0.0 - 4.8.1)
from deepgram import SpeakOptions
options = SpeakOptions(model="aura-2-thalia-en")
response = deepgram.speak.rest.v("1").save(
"output.mp3",
{"text": "Hello world!"},
options
)v5.0.0
response = client.speak.v1.audio.generate(
text="Hello, this is a sample text to speech conversion.",
model="aura-2-asteria-en"
)
# Save the audio file
with open("output.mp3", "wb") as audio_file:
audio_file.write(response.stream.getvalue())v3+ (3.0.0 - 4.8.1)
from deepgram import (
SpeakWSOptions,
SpeakWebSocketEvents
)
connection = deepgram.speak.websocket.v("1")
@connection.on(SpeakWebSocketEvents.AudioData)
def handle_audio_data(data):
# Handle audio data
pass
options = SpeakWSOptions(
model="aura-2-thalia-en",
encoding="linear16",
sample_rate=16000
)
connection.start(options)
connection.send_text("Hello, this is a text to speech example.")
connection.flush()
connection.wait_for_complete()
connection.finish()v5.0.0
from deepgram.extensions.types.sockets import SpeakV1SocketClientResponse
with client.speak.v1.connect(
model="aura-2-asteria-en",
encoding="linear16",
sample_rate=24000
) as connection:
def on_message(message: SpeakV1SocketClientResponse) -> None:
if isinstance(message, bytes):
print("Received audio event")
else:
msg_type = getattr(message, "type", "Unknown")
print(f"Received {msg_type} event")
connection.on(EventType.OPEN, lambda _: print("Connection opened"))
connection.on(EventType.MESSAGE, on_message)
connection.on(EventType.CLOSE, lambda _: print("Connection closed"))
connection.on(EventType.ERROR, lambda error: print(f"Error: {error}"))
connection.start_listening()
# Send text to be converted to speech
from deepgram.extensions.types.sockets import SpeakV1TextMessage
connection.send_text(SpeakV1TextMessage(text="Hello, world!"))
# Send control messages
from deepgram.extensions.types.sockets import SpeakV1ControlMessage
connection.send_control(SpeakV1ControlMessage(type="Flush"))
connection.send_control(SpeakV1ControlMessage(type="Close"))v3+ (3.0.0 - 4.8.1)
from deepgram import (
SettingsOptions,
Speak
)
connection = deepgram.agent.websocket.v("1")
options = SettingsOptions()
options.language = "en"
options.agent.think.provider.type = "open_ai"
options.agent.think.provider.model = "gpt-4o-mini"
options.agent.think.prompt = "You are a helpful AI assistant."
options.agent.listen.provider.type = "deepgram"
options.agent.listen.provider.model = "nova-3"
primary = Speak()
primary.provider.type = "deepgram"
primary.provider.model = "aura-2-zeus-en"
options.agent.speak = [primary]
options.greeting = "Hello, I'm your AI assistant."
connection.start(options)v5.0.0
from deepgram.extensions.types.sockets import (
AgentV1SettingsMessage, AgentV1Agent, AgentV1AudioConfig,
AgentV1AudioInput, AgentV1Listen, AgentV1ListenProvider,
AgentV1Think, AgentV1OpenAiThinkProvider, AgentV1SpeakProviderConfig,
AgentV1DeepgramSpeakProvider
)
with client.agent.v1.connect() as agent:
settings = AgentV1SettingsMessage(
audio=AgentV1AudioConfig(
input=AgentV1AudioInput(encoding="linear16", sample_rate=44100)
),
agent=AgentV1Agent(
listen=AgentV1Listen(
provider=AgentV1ListenProvider(type="deepgram", model="nova-3")
),
think=AgentV1Think(
provider=AgentV1OpenAiThinkProvider(
type="open_ai", model="gpt-4o-mini"
)
),
speak=AgentV1SpeakProviderConfig(
provider=AgentV1DeepgramSpeakProvider(
type="deepgram", model="aura-2-asteria-en"
)
)
)
)
agent.send_settings(settings)
agent.start_listening()v3+ (3.0.0 - 4.8.1)
from deepgram import AnalyzeOptions, TextSource
options = AnalyzeOptions(
sentiment=True,
intents=True,
topics=True,
summarize=True
)
payload: TextSource = {
"buffer": "The quick brown fox jumps over the lazy dog."
}
response = deepgram.read.analyze.v("1").analyze_text(
payload,
options
)v5.0.0
response = client.read.v1.text.analyze(
request={"text": "Hello, world!"},
language="en",
sentiment=True,
summarize=True,
topics=True,
intents=True
)v3+ (3.0.0 - 4.8.1)
# Not available in v3+v5.0.0
response = client.manage.v1.models.list()
# Include outdated models
response = client.manage.v1.models.list(include_outdated=True)v3+ (3.0.0 - 4.8.1)
# Not available in v3+v5.0.0
response = client.manage.v1.models.get(
model_id="6ba7b814-9dad-11d1-80b4-00c04fd430c8"
)v3+ (3.0.0 - 4.8.1)
# Get projects
response = deepgram.manage.v("1").get_projects()
# Get project
response = deepgram.manage.v("1").get_project("550e8400-e29b-41d4-a716-446655440000")
# Update project
response = deepgram.manage.v("1").update_project("550e8400-e29b-41d4-a716-446655440000", options)
# Delete project
response = deepgram.manage.v("1").delete_project("550e8400-e29b-41d4-a716-446655440000")v5.0.0
# Get projects
response = client.manage.v1.projects.list()
# Get project
response = client.manage.v1.projects.get(project_id="550e8400-e29b-41d4-a716-446655440000")
# Update project
response = client.manage.projects.update(
project_id="550e8400-e29b-41d4-a716-446655440000",
name="New Project Name"
)
# Delete project
response = client.manage.projects.delete(project_id="550e8400-e29b-41d4-a716-446655440000")v3+ (3.0.0 - 4.8.1)
# List keys
response = deepgram.manage.v("1").get_keys("550e8400-e29b-41d4-a716-446655440000")
# Get key
response = deepgram.manage.v("1").get_key("550e8400-e29b-41d4-a716-446655440000", "6ba7b810-9dad-11d1-80b4-00c04fd430c8")
# Create key
response = deepgram.manage.v("1").create_key("550e8400-e29b-41d4-a716-446655440000", options)
# Delete key
response = deepgram.manage.v("1").delete_key("550e8400-e29b-41d4-a716-446655440000", "6ba7b810-9dad-11d1-80b4-00c04fd430c8")v5.0.0
# List keys
response = client.manage.v1.projects.keys.list(
project_id="550e8400-e29b-41d4-a716-446655440000"
)
# Get key
response = client.manage.v1.projects.keys.get(
project_id="550e8400-e29b-41d4-a716-446655440000",
key_id="6ba7b810-9dad-11d1-80b4-00c04fd430c8"
)
# Create key
response = client.manage.projects.keys.create(
project_id="550e8400-e29b-41d4-a716-446655440000",
request={"key": "value"}
)
# Delete key
response = client.manage.projects.keys.delete(
project_id="550e8400-e29b-41d4-a716-446655440000",
key_id="6ba7b810-9dad-11d1-80b4-00c04fd430c8"
)v3+ (3.0.0 - 4.8.1)
# Get members
response = deepgram.manage.v("1").get_members("550e8400-e29b-41d4-a716-446655440000")
# Remove member
response = deepgram.manage.v("1").remove_member("550e8400-e29b-41d4-a716-446655440000", "6ba7b811-9dad-11d1-80b4-00c04fd430c8")v5.0.0
# Get members
response = client.manage.v1.projects.members.list(
project_id="550e8400-e29b-41d4-a716-446655440000"
)
# Remove member
response = client.manage.v1.projects.members.delete(
project_id="550e8400-e29b-41d4-a716-446655440000",
member_id="6ba7b811-9dad-11d1-80b4-00c04fd430c8"
)v3+ (3.0.0 - 4.8.1)
# Get member scopes
response = deepgram.manage.v("1").get_member_scopes("550e8400-e29b-41d4-a716-446655440000", "6ba7b811-9dad-11d1-80b4-00c04fd430c8")
# Update scope
response = deepgram.manage.v("1").update_member_scope("550e8400-e29b-41d4-a716-446655440000", "6ba7b811-9dad-11d1-80b4-00c04fd430c8", options)v5.0.0
# Get member scopes
response = client.manage.v1.projects.members.scopes.list(
project_id="550e8400-e29b-41d4-a716-446655440000",
member_id="6ba7b811-9dad-11d1-80b4-00c04fd430c8"
)
# Update scope
response = client.manage.projects.members.scopes.update(
project_id="550e8400-e29b-41d4-a716-446655440000",
member_id="6ba7b811-9dad-11d1-80b4-00c04fd430c8",
scope="admin"
)v3+ (3.0.0 - 4.8.1)
# List invites
response = deepgram.manage.v("1").get_invites("550e8400-e29b-41d4-a716-446655440000")
# Send invite
response = deepgram.manage.v("1").send_invite("550e8400-e29b-41d4-a716-446655440000", options)
# Delete invite
response = deepgram.manage.v("1").delete_invite("550e8400-e29b-41d4-a716-446655440000", "hello@deepgram.com")
# Leave project
response = deepgram.manage.v("1").leave_project("550e8400-e29b-41d4-a716-446655440000")v5.0.0
# List invites
response = client.manage.v1.projects.members.invites.list(
project_id="550e8400-e29b-41d4-a716-446655440000"
)
# Send invite
response = client.manage.v1.projects.members.invites.create(
project_id="550e8400-e29b-41d4-a716-446655440000",
email="hello@deepgram.com",
scope="member"
)
# Delete invite
response = client.manage.v1.projects.members.invites.delete(
project_id="550e8400-e29b-41d4-a716-446655440000",
email="hello@deepgram.com"
)
# Leave project
response = client.manage.v1.projects.leave(
project_id="550e8400-e29b-41d4-a716-446655440000"
)v3+ (3.0.0 - 4.8.1)
# Get all requests
response = deepgram.manage.v("1").get_usage_requests("550e8400-e29b-41d4-a716-446655440000")
# Get request
response = deepgram.manage.v("1").get_usage_request("550e8400-e29b-41d4-a716-446655440000", "6ba7b812-9dad-11d1-80b4-00c04fd430c8")
# Get fields
response = deepgram.manage.v("1").get_usage_fields("550e8400-e29b-41d4-a716-446655440000")
# Summarize usage
response = deepgram.manage.v("1").get_usage_summary("550e8400-e29b-41d4-a716-446655440000")v5.0.0
# Get all requests
response = client.manage.v1.projects.requests.list(
project_id="550e8400-e29b-41d4-a716-446655440000"
)
# Get request
response = client.manage.v1.projects.requests.get(
project_id="550e8400-e29b-41d4-a716-446655440000",
request_id="6ba7b812-9dad-11d1-80b4-00c04fd430c8"
)
# Get fields
response = client.manage.v1.projects.usage.fields.list(
project_id="550e8400-e29b-41d4-a716-446655440000"
)
# Get usage summary
response = client.manage.v1.projects.usage.get(
project_id="550e8400-e29b-41d4-a716-446655440000"
)
# Get usage breakdown (new in v5)
response = client.manage.v1.projects.usage.breakdown.get(
project_id="550e8400-e29b-41d4-a716-446655440000"
)v3+ (3.0.0 - 4.8.1)
# Get all balances
response = deepgram.manage.v("1").get_balances("550e8400-e29b-41d4-a716-446655440000")
# Get balance
response = deepgram.manage.v("1").get_balance("550e8400-e29b-41d4-a716-446655440000", "6ba7b813-9dad-11d1-80b4-00c04fd430c8")v5.0.0
# Get all balances
response = client.manage.v1.projects.balances.list(
project_id="550e8400-e29b-41d4-a716-446655440000"
)
# Get balance
response = client.manage.v1.projects.balances.get(
project_id="550e8400-e29b-41d4-a716-446655440000",
balance_id="6ba7b813-9dad-11d1-80b4-00c04fd430c8"
)v3+ (3.0.0 - 4.8.1)
# Get all project models
response = deepgram.manage.v("1").get_project_models("550e8400-e29b-41d4-a716-446655440000")
# Get model
response = deepgram.manage.v("1").get_project_model("550e8400-e29b-41d4-a716-446655440000", "6ba7b814-9dad-11d1-80b4-00c04fd430c8")v5.0.0
# Get all project models
response = client.manage.v1.projects.models.list(
project_id="550e8400-e29b-41d4-a716-446655440000"
)
# Get model
response = client.manage.v1.projects.models.get(
project_id="550e8400-e29b-41d4-a716-446655440000",
model_id="6ba7b814-9dad-11d1-80b4-00c04fd430c8"
)v3+ (3.0.0 - 4.8.1)
# List credentials
response = deepgram.selfhosted.v("1").list_selfhosted_credentials("550e8400-e29b-41d4-a716-446655440000")
# Get credentials
response = deepgram.selfhosted.v("1").get_selfhosted_credentials("550e8400-e29b-41d4-a716-446655440000", "6ba7b815-9dad-11d1-80b4-00c04fd430c8")
# Create credentials
response = deepgram.selfhosted.v("1").create_selfhosted_credentials("550e8400-e29b-41d4-a716-446655440000", options)
# Delete credentials
response = deepgram.selfhosted.v("1").delete_selfhosted_credentials("550e8400-e29b-41d4-a716-446655440000", "6ba7b815-9dad-11d1-80b4-00c04fd430c8")v5.0.0
# List credentials
response = client.self_hosted.v1.distribution_credentials.list(
project_id="550e8400-e29b-41d4-a716-446655440000"
)
# Get credentials
response = client.self_hosted.v1.distribution_credentials.get(
project_id="550e8400-e29b-41d4-a716-446655440000",
distribution_credentials_id="6ba7b815-9dad-11d1-80b4-00c04fd430c8"
)
# Create credentials
response = client.self_hosted.v1.distribution_credentials.create(
project_id="550e8400-e29b-41d4-a716-446655440000",
scopes=["read", "write"],
provider="quay",
comment="Development credentials"
)
# Delete credentials
response = client.self_hosted.v1.distribution_credentials.delete(
project_id="550e8400-e29b-41d4-a716-446655440000",
distribution_credentials_id="6ba7b815-9dad-11d1-80b4-00c04fd430c8"
)v3+ (3.0.0 - 4.8.1)
# Keep alive was passed as a config option
config = DeepgramClientOptions(
options={"keepalive": "true"}
)
deepgram = DeepgramClient(API_KEY, config)v5.0.0
# Keep alive is now manually managed via control messages.
from deepgram.extensions.types.sockets import ListenV1ControlMessage, AgentV1ControlMessage
# For Listen V1 connections
with client.listen.v1.connect(model="nova-3") as connection:
# Send keep alive message
connection.send_control(ListenV1ControlMessage(type="KeepAlive"))
# For Agent V1 connections
with client.agent.v1.connect() as agent:
# Send keep alive message
agent.send_control(AgentV1ControlMessage(type="KeepAlive"))- Authentication: New access token support with environment variable
DEEPGRAM_TOKEN - API structure: Flattened method names and cleaner parameter passing
- WebSocket API: Complete redesign with context managers and typed message objects
- WebSocket Keep Alive: Managed via control messages, no longer an automatic thing via config
- Type safety: Enhanced type annotations and response objects
- Error handling: Improved error types and handling
- Custom configuration objects (replaced with direct parameters)
- String-based versioning (
v("1")→v1) - Separate callback methods (integrated into main methods)
- Legacy WebSocket event system
- Listen V2: Advanced conversational speech recognition with contextual turn detection
- Enhanced Agent V1: More flexible voice agent configuration
- Raw response access: Access to HTTP headers and raw response data
- Custom HTTP client: Support for custom httpx clients
- Usage breakdown: Detailed usage analytics
- Better async support: Full async/await support throughout
- Upgrade to latest version:
pip install --upgrade deepgram-sdk - Update import statements if needed
- Replace API key configuration with new authentication methods
- Update all API method calls to new structure
- Migrate WebSocket connections to new context manager pattern
- Update WebSocket keep alive implementation
- Update error handling for new exception types
- Test all functionality with new API structure