Skip to main content
AssemblyAI’s API always returns a response even when there is an error. This guide is designed to help you navigate and resolve common issues when implementing AssemblyAI.

Understanding Errors with AssemblyAI

There are primarily two types of errors you might encounter when working with AssemblyAI:
  • errors that occur when requesting a transcription (immediate HTTP 4xx / 5xx, message in the error field of the JSON body)
  • errors that occur while the transcription is processing (the submit call returns 200, but a later GET /v2/transcript/{id} shows status: error with the message in the error field)
The first category includes issues such as authentication errors, invalid request parameters, or server-related errors, which are typically flagged immediately when you attempt to initiate a request. The second category, failed transcription jobs, pertains to errors that occur during the transcription process itself. These might be due to issues with the audio file, unsupported languages, or internal errors on our end.

Handling Errors with AssemblyAI

When using any of our SDKs, both types of errors are surfaced via the error key in a transcript object. For example in Python:
if transcript.status == aai.TranscriptStatus.error:
    print(transcript.error)

Error handling with HTTPS requests

For errors when making a request for a transcription, you will have to check the status code that we respond with. For errors that occur during the transcription process, you will need to access the “error” key in the JSON response. For other HTTP errors you can print the information from the response object. Here is an example you can use:
if response.status_code != 200:
    try:
        print(response.json()['error'])
    except Exception:
        print(response.status_code, response.text, response.url)

Common errors when making a request for a transcription

Unless otherwise noted, these errors are returned from POST /v2/transcript with the message in the error field of the JSON body.

Missing audio_url

# Status code: 400
{
"error": "Transcript creation error, audio_url not found"
}
This error occurs when the request body does not include the required audio_url field.
  • Solution: Include an audio_url field that points to a publicly accessible audio file or to a URL returned by the Upload endpoint.

Unsupported language code

# Status code: 400
{
"error": "Language code <code> is not supported. See https://www.assemblyai.com/docs/concepts/supported-languages."
}
The language_code value you submitted isn’t recognized.

Invalid speech_models value

# Status code: 400
{
"error": "\"speech_models\" must be a non-empty list containing one or more of: \"universal-3-pro\", \"universal-2\""
}
The speech_models parameter must be a non-empty list of supported model names.
Accounts on a feature flag for dated universal-3-pro variants may see additional model names in the list.
  • Solution: Pass a non-empty list, for example ["universal-3-pro", "universal-2"]. See Select the speech model for guidance.

Deprecated speech_model (singular) parameter on async /v2/transcript

# Status code: 400 — POST /v2/transcript
{
"error": "speech_model is deprecated. Use \"speech_models\" instead. See documentation: https://www.assemblyai.com/docs/pre-recorded-audio/select-the-speech-model"
}
On the async pre-recorded API, the singular speech_model field no longer selects a model. Submitting a current model name (universal-2, universal-3-pro, slam-1, conformer-2) returns this 400 deprecation. Submitting a legacy value (best, nano, universal) returns 200, but the value is silently ignored and the job runs the default model (currently universal-2). Only the plural speech_models field actually selects a model on async.
Newer accounts may receive a slightly different deprecation message, but it points to the same fix.
This entry applies to the async pre-recorded API (POST /v2/transcript) only. The Streaming API is a separate system that uses its own singular speech_model field with values like universal-streaming-english and u3-rt-pro — see Streaming model selection. Don’t treat the singular speech_model field as universally deprecated.

language_detection conflicts with language_code

# Status code: 400
{
"error": "`language_detection` is not available when `language_code` is specified."
}
You cannot set both language_detection: true and a specific language_code in the same request.
The plural language_codes field returns a different (similarly worded) message.
  • Solution: Either remove language_code and let Automatic Language Detection pick the language, or remove language_detection and keep language_code.

Wrong-type validation (Boolean, etc.)

# Status code: 400
{
"error": "`punctuate` must be a Boolean"
}
This is a generic wrong-type validation message. The field name changes depending on which parameter was submitted with the wrong type — any Boolean parameter sent as a non-Boolean value will trigger an equivalent message.
  • Solution: Send the parameter with the correct JSON type (true/false for Booleans, an integer for integer fields, a string for string fields, etc.).

Invalid webhook_url

# Status code: 400
{
"error": "Invalid `webhook_url`, `webhook_url` should start with http."
}
The webhook_url field must be a valid URL beginning with http:// or https://.
  • Solution: Submit a fully-qualified webhook URL. See Webhooks for details.

Missing redact_pii_policies

# Status code: 400
{
"error": "You must explicitly define 'redact_pii_policies'"
}
This error fires when PII Redaction is enabled but redact_pii_policies is missing.
This only applies to accounts created after redact_pii_policies became required. Older accounts auto-fill defaults and do not error.
  • Solution: Provide an explicit list of policies, for example "redact_pii_policies": ["person_name", "phone_number"]. See Redact PII for the full list of supported policy names.

Unsupported policy name in redact_pii_policies

# Status code: 400
{
"error": "Unsupported policy name in 'redact_pii_policies', supported policy names are [...]"
}
One of the values in redact_pii_policies isn’t a recognized policy.
  • Solution: Use only policies from the list in the error message and in the Redact PII docs.

Invalid redact_pii_audio_quality

# Status code: 400
{
"error": "Invalid `redact_pii_audio_quality` value, choose 'mp3' or 'wav'"
}
redact_pii_audio_quality only accepts "mp3" or "wav".
  • Solution: Set redact_pii_audio_quality to "mp3" or "wav".

Malformed JSON body

# Status code: 400
{
"error": "Error processing request, json data invalid"
}
The request body could not be parsed as JSON.
  • Solution: Verify the body is valid JSON, the Content-Type: application/json header is set, and that no stray trailing commas, comments, or unescaped characters are present.

Models are not supported for a particular language

# Status code: 400
{
"error": "The following models are not available in this language: speaker_labels"
}
This error occurs when you set language_code explicitly and enable a feature that isn’t supported for that language. The API validates feature compatibility upfront and rejects the request.
This error only applies when using language_code. If you use Automatic Language Detection instead, the request will complete successfully, but any unsupported features will be silently omitted from the response. See Unsupported feature behavior for more details.

Insufficient Funds

# Status code: 400
{
"error": "Your current account balance is negative. Please top up to continue using the API."
}
Solution:
  • Auto-pay: Enable auto-pay in your account settings to automatically add funds when your balance runs low.
  • Check Funds: Regularly check your account balance to ensure you have sufficient funds for your transcription requests.
  • Add Funds: If needed, add funds to your account to continue using our services without interruption.

Invalid API Token

# Status code: 401
{
"error": "Authentication error, API token missing/invalid."
}
An invalid API token will prevent you from making successful requests. Solution:
  • Double-check that the API token you’re using matches exactly with the token shown in your dashboard. Even a small typo can lead to authentication errors.

Transcript ID not found

# Status code: 400
{
"error": "Transcript lookup error, transcript id not found"
}
Solution:
  • Verify the endpoint and method that you are using: Check that you are making a POST request to http://api.assemblyai.com/v2/transcriptor a GET request to http://api.assemblyai.com/v2/transcript/{transcript_id} and not http://api.assemblyai.com/v2/transcript/
  • Token Verification: Double-check that the API token you’re using matches exactly with the token used to make the original request.
  • If you’re using Postman, ensure that Encode URL automatically under Settings is disabled.

Server Errors

# Status code: 500
{
"error": "Internal server error. Please retry your request. If the error persists, please contact support@assemblyai.com for more information."
}
Server errors rarely happen but can occasionally occur on our side. Solution:
  • Retries: Implement retries in your code for when our server returns a 500 code response. See Implement Retry Server Error Logic for a worked example.
  • Automatic Retries: Enable automatic retries for your transcription jobs under Account > Settings on your dashboard. This ensures that if a job fails due to a temporary server issue, it will automatically be retried.
  • Check our Status page to verify that we are not currently undergoing an incident
  • Reach out to Support: Remember to provide the transcript ID, audio file used, and parameters used in your request or the full JSON response in your message. You can also email support@assemblyai.com for help!

Errors on export, sub-resource, and upload endpoints

Requesting captions, sentences, or paragraphs before the transcript completes

# Status code: 400 — GET /v2/transcript/{id}/srt (or /vtt, /sentences, /paragraphs)
{
"error": "This transcript has a status of '<status>'. Transcripts must have a status of 'completed' before requesting captions."
}
The export endpoints can only be called after the transcript reaches status: completed. On the /sentences and /paragraphs endpoints the word captions in the message is replaced with sentences or paragraphs respectively.
  • Solution: Poll GET /v2/transcript/{id} (or use a webhook) and only request captions/sentences/paragraphs once status is completed.

word-search called without words

# Status code: 400 — GET /v2/transcript/{id}/word-search
{
"error": "`words` is a required query parameter"
}
The /word-search endpoint requires the words query parameter.
  • Solution: Pass a comma-separated list of search terms, for example ?words=foo,bar. See the Word Search reference.

Redacted audio not available

# Status code: 400 — GET /v2/transcript/{id}/redacted-audio
{
"error": "A redacted audio file for this transcript ID doesn't exist. Try submitting the transcript again with`redact_pii_audio`set to`true`."
}
The redacted audio file is only generated when PII Audio Redaction was enabled at submission time.
  • Solution: Resubmit the audio with redact_pii: true and redact_pii_audio: true. Set redact_pii_policies and (optionally) redact_pii_audio_quality to control what is redacted and the output format.

Invalid subtitle format

# Status code: 404 — GET /v2/transcript/{id}/<invalid-subtitle-format>
404: Not Found
When you request an unsupported subtitle format (anything other than srt or vtt), the API returns an HTML 404 page. The response body is the literal string 404: Not Foundnot JSON.
This is the only documented endpoint where a 404 does not come back as a JSON object with an error field. A “handled” 404 — for example, looking up an unknown transcript ID — still returns JSON in the usual shape.

Empty upload body

# Status code: 422 — POST /v2/upload
Upload failed, please try again. If you continue to have issues please reach out to support@assemblyai.com
Posting an empty body to /v2/upload returns a 422. The response body is plain text, not JSON.
  • Solution: Stream the file bytes as the request body. See the Upload endpoint reference.

Out-of-range limit when listing transcripts

# Status code: 400 — GET /v2/transcript
{
"error": "'limit' must be greater than or equal to 1"
}
The limit query parameter on GET /v2/transcript must be >= 1.

Common transcription processing errors

These errors come back from GET /v2/transcript/{id} after the submit call returned 200. The transcript has status: error and the message is in the error field.

Audio File URL Errors

Attempting to transcribe webpages or non-audio URLs
{
  "status": "error",
  "audio_url": "https://www.youtube.com/watch?v=r8KTOBOMm0A",
  "error": "Transcoding failed. File type <mime> (<detail>) may be unsupported or an unexpected error occurred. See supported formats at https://www.assemblyai.com/docs/faq/what-audio-and-video-file-types-are-supported-by-your-api. If your file format is supported and you're still encountering this error, contact us at support@assemblyai.com.",
  ...
}
Our API requires a publicly accessible URL that points to an audio or video file. If the URL points to a webpage, an unsupported file type, or transcoding otherwise fails, this error is returned. To transcribe a YouTube video, check out this Cookbook.
No audio stream in the file
{
  "status": "error",
  "error": "No audio stream found in the file. File type is <mime> (<detail>)."
}
The file downloaded successfully but contains no audio stream (for example, an image, a PDF, or a video file whose audio track has been stripped).
  • Solution: Verify the file actually contains audio (for example with ffprobe). Re-encode or replace the file before resubmitting.
File exceeds the 5.5 GB maximum
{
  "status": "error",
  "error": "<audio_url> length=<bytes> exceeds max_content_length=5500000000"
}
The file is larger than the 5.5 GB cap. The size is read from the Content-Length header before download, so this error fires almost immediately.
URL returns an empty body
{
  "status": "error",
  "error": "No content found at <url>. Please make sure the file exists and is not empty."
}
The URL was reachable but returned an empty response body.
  • Solution: Confirm the file is actually present at the URL and the server returns a non-zero Content-Length. Re-upload the file if necessary.
Uploaded file not found / region mismatch
{
  "status": "error",
  "error": "File not found at <url>. Make sure the file was uploaded recently and that you're transcribing from the same region."
}
The URL returned by POST /v2/upload could not be resolved. This usually means the upload has been garbage-collected, or the upload was made to one region (e.g. US) and the transcript was submitted in another region (e.g. EU).
  • Solution: Re-upload the file and submit the transcript using the same regional base URL. See Do you offer servers in the EU? for the per-region endpoints.
Attempting to transcribe audio files that are not accessible
{
  "status": "error",
  "audio_url": "https://foo.bar",
  "error": "Download error, unable to download https://foo.bar. Please make sure the file exists and is accessible from the internet."
}
Solution:
  • Public Access: Verify that the audio file URL is publicly accessible. Our servers cannot transcribe audio from private or restricted URLs.
  • Google Drive URLs: For audio stored on Google Drive, consult our Google Drive Transcription Cookbook to correctly format your URLs for access.
  • Direct Upload: Utilize the AssemblyAI Upload endpoint to upload files directly from your device, eliminating the need for a public URL.
  • AWS S3 Pre-signed URLs: This Cookbook shows you how to use pre-signed URLs for AWS S3 storage to provide secure, temporary access for transcription without making your files public.
Time-limited URLs (presigned URLs, CDN tokens, etc.) must be fresh when you submit them. URLs from services like AWS S3 presigned URLs, Azure Blob Storage SAS tokens, GCP signed URLs, and social media CDNs (e.g., TikTok, Instagram) expire after a set duration. If the URL expires before AssemblyAI downloads the file, the origin server returns a 403 or 404 and you will see this download error.To avoid this:
  1. Generate the time-limited URL immediately before submitting your transcription request — do not cache or store URLs for later use.
  2. Ensure the URL expiration window is long enough for the file to be downloaded (at least a few minutes).
  3. If you cannot control the URL lifetime, use the Upload endpoint to upload the file directly to AssemblyAI instead.

Audio File Errors

Attempting to transcribe audio files that are too short
{
  "status": "error",
  "audio_url": "https://foo.bar",
  "error": "Audio duration is too short."
}
The minimum audio duration for a file submitted to our API is 160ms. Solution:
  • Add error handling for this error message: When this error occurs, handle it safely by checking the error string and returning the error.
  • Add pre-submit checks for the duration of the audio file: Prior to submitting a file for transcription, check the duration using a tool like soxi (part of the SoX package): soxi -D audio.mp3

Language Detection Errors

No spoken audio detected
{
  "status": "error",
  "error": "language_detection cannot be performed on files with no spoken audio."
}
Automatic Language Detection requires spoken audio to analyze. Files that are silent, music-only, or otherwise contain no speech can’t be language-detected.
  • Solution: Disable language_detection and set language_code explicitly for files where speech may be absent, or skip transcription for files that are known to be non-speech.
Detected language confidence below the threshold
{
  "status": "error",
  "error": "detected language '<code>', confidence <c>, is below the requested confidence threshold value of '<threshold>'"
}
This fires when language_detection is enabled and the detected language’s confidence is below the language_confidence_threshold you set. Erroring is the default behavior when the threshold isn’t met.
  • Solution: Set language_detection_options.on_low_language_confidence to fallback to fall back to a language you specify instead of erroring. Alternatively, lower the language_confidence_threshold. See Automatic Language Detection for details.