AssemblyAI Not Working?
API 401 (lowercase authorization header), audio URL not accessible, transcription stuck in processing, webhook not firing, or LeMUR not responding? Check live status and fix it fast.
AssemblyAI — live status
Updated every 5 minutes. Full history at prismix.dev/service/assemblyai.
What's wrong? Diagnose fast
API 401 — non-standard auth header
AssemblyAI uses a lowercase header with no "Bearer": authorization: YOUR_KEY (not "Authorization: Bearer"). This trips up many developers. Python SDK: aai.settings.api_key = "YOUR_KEY". Generate key at assemblyai.com/app/account.
Audio URL not accessible (400)
AssemblyAI fetches your audio from the URL you provide. Localhost URLs fail. Fix: upload your file to AssemblyAI first: POST to /v2/upload with the file binary (authorization header required). Response gives upload_url — use that in your transcript POST. Valid 24 hours.
Transcription stuck in queued or processing
Poll GET /v2/transcript/ID every 3-5s until status = "completed" or "error". "error" = check the error field for the message. Common causes: audio URL expired or restricted, unsupported format (use WAV/MP3/MP4/WebM/FLAC), or corrupted audio file.
Webhook not receiving calls
webhook_url must be a public HTTPS URL (not localhost). AssemblyAI sends a POST when transcription completes or fails. Must respond with HTTP 200 in under 10 seconds. Test your endpoint with webhook.site. If not firing, check the transcript status via polling as fallback.
LeMUR not responding or failing
LeMUR requires a completed transcript_id — you cannot call LeMUR on a pending transcript. Check transcript.status = "completed" before calling LeMUR. LeMUR max input: ~100k tokens from transcripts. If context is too long, use context_window=short in the request or split transcripts.
Realtime streaming issues
AssemblyAI Realtime uses WebSocket (wss://api.assemblyai.com/v2/realtime/ws?sample_rate=16000). Key in the URL query param: ?token=YOUR_KEY. Audio must be 16-bit PCM raw bytes, 16kHz sample rate. If connection drops: VPNs block WebSocket — test without VPN. Also: token expires after 24h.
AssemblyAI API quick reference
Upload local file + transcribe (curl)
# Step 1: Upload local file — authorization is LOWERCASE, no Bearer
curl -X POST "https://api.assemblyai.com/v2/upload" \
-H "authorization: YOUR_API_KEY" \
-H "content-type: application/octet-stream" \
--data-binary @/path/to/audio.mp3
# Returns: {"upload_url":"https://cdn.assemblyai.com/upload/..."}
# Step 2: Start transcription
curl -X POST "https://api.assemblyai.com/v2/transcript" \
-H "authorization: YOUR_API_KEY" \
-H "content-type: application/json" \
-d '{"audio_url": "https://cdn.assemblyai.com/upload/..."}'
# Returns: {"id":"TRANSCRIPT_ID","status":"queued"} Poll for completion + get result
# Poll every 3-5 seconds curl "https://api.assemblyai.com/v2/transcript/TRANSCRIPT_ID" \ -H "authorization: YOUR_API_KEY" # status: "queued" → "processing" → "completed" | "error" # If "error": check the "error" field in the response
Python SDK (recommended for production)
import assemblyai as aai
aai.settings.api_key = "YOUR_API_KEY"
transcriber = aai.Transcriber()
transcript = transcriber.transcribe("https://public-url/audio.mp3")
# OR for local file:
transcript = transcriber.transcribe("/local/path/audio.mp3")
if transcript.status == aai.TranscriptStatus.error:
print(transcript.error)
else:
print(transcript.text) Step-by-step fix
- 1
Check live AssemblyAI status
Visit prismix.dev/service/assemblyai. Also assemblyai.statuspage.io. Transcription, LeMUR, and Realtime can have independent status.
- 2
Fix API 401
AssemblyAI uses a non-standard header:
authorization: YOUR_KEY(lowercase, no "Bearer" prefix). This differs from most APIs. Python SDK:aai.settings.api_key = "YOUR_KEY". Key at assemblyai.com/app/account. - 3
Fix audio URL not accessible
Your audio_url must be publicly reachable. For local files: upload to AssemblyAI first with
POST /v2/upload(binary body, authorization header). Use the returnedupload_urlas your audio_url. Upload URLs are valid 24 hours. - 4
Fix transcription stuck
Poll
GET /v2/transcript/IDevery 3-5 seconds untilstatus = "completed"or"error". For production: usewebhook_urlin the transcript POST to receive a callback instead of polling. - 5
Fix webhook not firing
Webhook URL must be a public HTTPS endpoint. If developing locally, use ngrok or webhook.site to expose a local URL. Your endpoint must respond with HTTP 200 within 10 seconds. AssemblyAI sends:
{"transcript_id": "...", "status": "completed"}.
Get alerted when AssemblyAI goes down
Star AssemblyAI on Prismix and get emailed the moment status changes. Free, no credit card.
Frequently asked questions
Why is AssemblyAI not working?
AssemblyAI issues: (1) 401 — auth header is lowercase "authorization: YOUR_KEY" with no Bearer prefix; (2) audio URL error — URL must be public HTTPS, upload local files via /v2/upload first; (3) transcription stuck — poll GET /v2/transcript/ID until status = completed or error; (4) webhook not firing — URL must be public HTTPS, respond 200 in 10s; (5) outage — prismix.dev/service/assemblyai.
Is AssemblyAI down right now?
Check prismix.dev/service/assemblyai for live status. Also assemblyai.statuspage.io.
AssemblyAI API 401 — how to fix?
AssemblyAI uses a non-standard auth header: authorization: YOUR_API_KEY (lowercase "authorization", no "Bearer" prefix, no colon-space after "Bearer"). curl: -H "authorization: YOUR_KEY". Python: aai.settings.api_key = "YOUR_KEY". JavaScript: {"authorization": "YOUR_KEY"}. This is different from OpenAI / Anthropic.
AssemblyAI cannot access audio URL — how to upload local files?
POST your file binary to https://api.assemblyai.com/v2/upload with header authorization: YOUR_KEY and content-type: application/octet-stream. The response gives upload_url. Use that URL as audio_url in your transcript POST. Upload URLs are valid for 24 hours. The Python SDK handles local file upload automatically: transcriber.transcribe("/local/file.mp3").
How to use AssemblyAI LeMUR?
LeMUR requires a completed transcript first. Post to /v2/transcript, poll until status = "completed", then POST to /lemur/v3/transcript/action: {"transcript_ids": ["TRANSCRIPT_ID"], "prompt": "Summarize this meeting"}. If the LeMUR call fails with "transcript not ready", your polling logic is not waiting for completion. LeMUR max context: ~100k tokens from transcripts.