I'm working on integrating AssemblyAI's real-time transcription API with WebSocket in Python, using the websockets library. However, when I attempt to connect to the WebSocket endpoint, I get the following error:
WebSocket closed with code 4001: Not authorized
Connecting to WebSocket at wss://api.assemblyai.com/v2/realtime/ws?sample_rate=16000
WebSocket connected. Receiving SessionBegins...
SessionBegins: {"error":"Not authorized"}
Starting to send and receive messages...
Receive: WebSocket closed with code 4001: Not authorized
Send: WebSocket closed with code 4001: Not authorized
Here is the code I'm using:
import websockets
import asyncio
import base64
import json
from configure import auth_key
import pyaudio
# Audio configuration
FRAMES_PER_BUFFER = 3200
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 16000
# Initialize PyAudio
p = pyaudio.PyAudio()
# Start recording
stream = p.open(
format=FORMAT,
channels=CHANNELS,
rate=RATE,
input=True,
frames_per_buffer=FRAMES_PER_BUFFER
)
# AssemblyAI WebSocket endpoint
URL = "wss://api.assemblyai.com/v2/realtime/ws?sample_rate=16000"
async def send_receive():
print(f"Connecting to WebSocket at {URL}")
try:
auth_url = f"{URL}&auth_key={auth_key}" # Append API key to URL
async with websockets.connect(
auth_url,
ping_interval=5,
ping_timeout=20
) as _ws:
await asyncio.sleep(0.1)
print("WebSocket connected. Receiving SessionBegins...")
# Receive SessionBegins
session_begins = await _ws.recv()
print(f"SessionBegins: {session_begins}")
print("Starting to send and receive messages...")
# Define the send coroutine
async def send():
while True:
try:
# Read audio data, encode and send
data = stream.read(FRAMES_PER_BUFFER)
data = base64.b64encode(data).decode("utf-8")
json_data = json.dumps({"audio_data": data})
await _ws.send(json_data)
print("Sent audio data")
except websockets.ConnectionClosedError as e:
print(f"Send: WebSocket closed with code {e.code}: {e.reason}")
break
except Exception as e:
print(f"Send: Unexpected error: {e}")
break
await asyncio.sleep(0.01)
# Define the receive coroutine
async def receive():
while True:
try:
# Receive and print text data
result_str = await _ws.recv()
print(f"Received: {json.loads(result_str).get('text', '')}")
except websockets.ConnectionClosedError as e:
print(f"Receive: WebSocket closed with code {e.code}: {e.reason}")
break
except Exception as e:
print(f"Receive: Unexpected error: {e}")
break
# Run send and receive concurrently
await asyncio.gather(send(), receive())
except Exception as e:
print(f"Connection failed: {e}")
while True:
try:
asyncio.run(send_receive())
except KeyboardInterrupt:
print("Program interrupted by user. Exiting...")
break
except Exception as e:
print(f"Unexpected error: {e}")
break
When I attempt to connect to the WebSocket server, I receive the following response in the SessionBegins message:
SessionBegins: {"error":"Not authorized"}
Steps Taken:
I verified that the API key (
auth_key) is correct and has been included properly in the request.I checked that the URL is correctly formatted with the
auth_keyappended as a query parameter.I have confirmed that the API key has the necessary permissions to access the real-time transcription service.
Why am I receiving a "Not authorized" error with WebSocket code 4001 when connecting to the AssemblyAI WebSocket endpoint, and how can I resolve it?