Archived docs Get your API Key
Get started
Tutorials
Guides
Reference
Help for coding agents
πŸ€– AI Assistant

Errors

The API surfaces errors in two places:

  1. HTTP responses β€” synchronous endpoint errors (validation, auth, quota). The response body is { "success": false, "message": "…" } with an HTTP status code in the 4xx–5xx range.
  2. Render status β€” asynchronous errors discovered while a render is being produced. The render completes with movie.status = "error" and movie.message describing what failed. The HTTP status of GET /v2/movies is still 200.

All error messages are short, descriptive strings. They are not stable identifiers β€” match on HTTP status and on the endpoint plus message family rather than on exact text.

HTTP status code summary

Status Meaning
200 Request accepted. For GET /v2/movies, also check movie.status.
400 Validation error, invalid or missing API key, or insufficient credits.
401 Quota / plan limit error.
403 Authorisation error (role, blocked storage, invalid admin token).
404 Resource (template, movie, file) not found.
405 HTTP method not supported on this endpoint.
409 Conflict (duplicate filename on upload, etc.).
413 Payload too large: a movie JSON over 2 MB (POST /v2/movies) or a media upload over 500 MB.
500 Internal error.

Authentication errors

Returned when the request lacks a valid API key or is using one without sufficient permissions. Note that an invalid or missing API key returns HTTP 400, not 401.

Status Message Endpoint
400 Error: API Key not provided All endpoints
400 Error: Invalid API Key All endpoints
403 Insufficient permissions /v2/templates, /v2/media, POST /v2/movies (admin endpoints)
403 Invalid token Admin-only query parameters

To resolve: confirm the x-api-key header is present and that the key has the right role for the action β€” Render to render videos, Editor to create / edit templates, Manager to manage Connections. See API keys β†’ Permission roles.

Quota and plan errors

Returned when the account has exhausted its plan allowance.

Status Message Endpoint
401 You exceeded the quota of movies in your plan. Please upgrade your plan to continue. POST /v2/movies
401 You exceeded the quota of drafts in your plan. Please upgrade your plan to continue. POST /v2/movies
401 Movie is larger ({w}x{h}) than your plan allowance ({w}x{h}) POST /v2/movies
400 Insufficient credits Render submission paths
403 Storage is blocked. Add credits to continue uploading. POST /v2/media/file

To resolve: top up credits or upgrade the plan. See Credits & limits.

Validation errors

Returned when the request payload is missing required fields or has the wrong shape.

The two Source URL errors below also carry "code": "media_src_required" in the response body, the AWS keys error carries "code": "aws_keys_in_movie", and the movie JSON is too large error carries "code": "movie_json_too_large". Elements at movie level are named Movie element #M instead of Scene #N, Element #M. When several elements have the problem, the message names the first one and lists the others.

Status Message Endpoint
400 No movie JSON received POST /v2/movies
400 Error parsing movie JSON or the movie was empty POST /v2/movies
400 No valid movie JSON received POST /v2/movies
400 Source URL is required: the {type} element in Scene #N, Element #M has no "src". … POST /v2/movies β€” an image, video or audio element has no src, or an empty one.
400 Source URL is invalid: the {type} element in Scene #N, Element #M has "src" set to "…", which is not a URL. … POST /v2/movies β€” src is not a URL starting with http:// or https://.
400 AWS keys cannot be sent in the movie (exports[0].destinations[0]). Save them in a connection (Dashboard β†’ Connections β†’ Output destinations) and reference it with "id", e.g. { "type": "aws-s3", "id": "my-bucket" }. If these keys are real, rotate them in AWS: they were sent in a request. POST /v2/movies β€” a destination in exports carries AWS keys (access-key-id, secret-access-key or a similar field, or an access key ID in an aws-s3 destination). Save them in an Amazon S3 destination instead. Nothing is rendered.
400 Project ID must be a 16-character string. Received ID: '…' (length: N) GET /v2/movies
400 Invalid start date / Invalid end date GET /v2/movies
400 Maximum date range is 3 months. GET /v2/movies
400 No payload provided POST /v2/templates, POST /v2/media/file, PUT /v2/media/file, DELETE /v2/media/file
400 Tags must be a string or an array POST /v2/templates
400 Payload movie must be a JSON string or JSON object POST /v2/templates
400 Template movie is not valid JSON or it's too large POST /v2/templates
400 name is required /v2/media/file
400 contentType is required POST /v2/media/file
400 size is required and must be a positive number POST /v2/media/file
400 path is required / Invalid path: no filename GET /v2/media/file
400 destination is required PUT /v2/media/file
400 folder is required / Invalid folder name /v2/media/folder
400 Cannot delete root folder / Cannot delete the temp folder DELETE /v2/media/folder
400 Folder is not empty. Delete all files first. DELETE /v2/media/folder
400 Invalid movie status Render submission
404 Template {id} not found /v2/templates, POST /v2/movies (template ref)
404 File not found /v2/media/file
404 Movie ID {id} not found Render submission
403 Template {id} is not owned by you / Movie ID {id} is not owned by you POST /v2/templates, render submission
405 Method not supported All endpoints
409 A file with this name already exists. Delete it first. POST /v2/media/file
409 A file with this name already exists in the destination folder PUT /v2/media/file
413 File exceeds maximum size of 500 MB POST /v2/media/file
413 The movie JSON is too large: 2.35 MB (2,461,234 bytes). The maximum size of a movie JSON is 2 MB (2,097,152 bytes). POST /v2/movies β€” the request body is over 2 MB. Nothing is created. Shorten media URLs or split the movie: see Create movie β†’ Size limit.

Server errors

Status Message Endpoint
500 Error creating movie: the movie JSON could not be stored. No movie was created; please try again. POST /v2/movies β€” a temporary storage error; "code": "movie_json_not_stored". Nothing was created or charged. Retry.
413 Error creating movie: the movie record is larger than the database limit … POST /v2/movies β€” "code": "movie_record_too_large". Should not happen with a body under 2 MB; contact support.
500 Error creating movie: … POST /v2/movies β€” any other failure to save the movie. Retry.

Older integrations may have seen 500 Error creating movie: Item size has exceeded the maximum allowed size for a movie JSON above roughly 200 KB. That limit is gone: bodies up to 2 MB are accepted.

Rendering errors

Surfaced asynchronously via GET /v2/movies when movie.status = "error". The movie.message field contains the underlying error. Examples seen in production:

Family Example message Trigger
Element validation Source URL is required for video element in Scene #1, Element #2 An image, video or audio element's src came from a variable ("{{video_url}}") that resolved to an empty value or to something that is not a URL. A src that is missing or invalid in the JSON you send is rejected earlier, by POST /v2/movies (see Validation errors).
Positioning / sizing /Movie/scenes[0]/elements[1]: 'x' has an invalid value "auto". Use a number in pixels, a percentage of the canvas like "30%", one of: left, center, right x, y, width or height held a value that is neither a number nor one of the accepted strings. See Positioning and sizing values.
Asset download Asset fetch errors propagate from the downloader. The element src URL is unreachable, requires authentication, or returns an unsupported media type.
Webpage capture Errors from the HTML / webpage renderer. An html element pointed at a URL that timed out, returned non-2xx, or required interaction.
Voice synthesis Errors from the speech provider. Invalid voice ID, unsupported language, rate-limit, or a transient 5xx. For voices on your own ElevenLabs key, see below.
Subtitles Speech-to-text transcription error. Source audio was missing or unreadable.

For rendering errors, the movie.success field is false even though the HTTP status is 200.

Voices on your own API key

When an ElevenLabs voice runs on your own key β€” your default key (β˜…) or a key chosen with connection β€” a failure never falls back to JSON2Video's key. The render fails with one of these messages (prefixed with Scene #n, element #m: ):

Message Cause Fix
Voice "<voice>" was not found in your ElevenLabs account. Use a voice ID from your ElevenLabs account, or a voice listed at https://json2video.com/ai-voices/elevenlabs/. The key works, but the voice is not in the ElevenLabs account the key belongs to. Add the voice to that ElevenLabs account, or use another voice.
Voice "<voice>" cannot be used with your ElevenLabs account: <reason>. … The ElevenLabs account has no access to that voice. Use another voice, or check the voice in ElevenLabs.
Your default ElevenLabs key (connection "<id>") failed: <reason>. Update it in Dashboard β†’ Connections, or remove its star (β˜…) there. To use JSON2Video's key in one render, set "connection": "none". Your default key was rejected, is out of quota or credits, has a payment problem or lacks a permission β€” or the connection was deleted while the render ran. Replace the key in Dashboard β†’ Connections, remove its star, or set "connection": "none" on the voice.
The ElevenLabs key in connection "<id>" failed: <reason>. Update it in Dashboard β†’ Connections. The same, for a key chosen with connection. Replace the key, or reference another connection.
Connection <id> not found in your list of connections. Add your connection from the dashboard. No connection has the ID in connection. IDs are case-sensitive. Fix the ID or create the connection.
Could not read your connections to check for a default API key. Please try the render again. A temporary error while looking up your default key. Render again.

Any other ElevenLabs error is shown with the reason ElevenLabs gives. See the voice element's connection property.

On JSON2Video's key, voices are limited to the ElevenLabs catalog: an unknown voice fails with Voice "<voice>" is not found in the list of supported voices for ElevenLabs. …, and a catalog voice with a higher credit cost with Voice "<voice>" has a credit cost of <n>x. Only 1x voices are supported with JSON2Video API keys. Use your own ElevenLabs API key to generate this voice.

Delivery errors

Output destinations (webhooks, FTP, SFTP, Amazon S3, email) run after the render. A failed delivery does not change the movie's status: it is recorded in movie.destinations_result (Get movie status) and in the dashboard under Render logs β†’ the render β†’ Deliveries. Examples of message:

Status Example message Meaning
ok Delivered to https://example.com (HTTP 200, 3 attempts). Delivered, here after two retries.
error The receiver at https://example.com answered HTTP 404. Not retried. Your receiver answered with a 3xx or 4xx status.
error The receiver at https://example.com answered HTTP 503 (3 attempts). Your receiver kept answering with a 5xx status.
error No response from https://example.com within 30 s (1 attempt). The receiver may still have processed the request, so it was not sent again. Your receiver took more than 30 seconds to answer.
error Could not reach https://example.com: … (3 attempts). DNS, connection or TLS error.
error Not delivered: https://example.com resolves to a private, loopback or link-local network address. JSON2Video only connects to public internet addresses. The host points at a non-public address. Nothing was sent.
error Connection "<id>" was not found. Create it in Dashboard β†’ Connections, or remove it from the movie. The destination id does not exist.
error The password of connection "<id>" could not be read. Save the connection again in Dashboard β†’ Connections. Enter the password again in the dashboard.
error A movie can deliver through one export only, and this one has 2. Nothing was delivered. Put every destination in a single exports object.
error … Stopped retrying: the delivery ran out of time. / Not attempted: the delivery ran out of time. All destinations share a budget of about 5 minutes.
skipped Nothing to upload: the render did not produce a video. FTP, SFTP, Amazon S3 and email destinations of a failed render.

Amazon S3 deliveries

The same messages are shown by the Test button of an Amazon S3 destination (see below). my-videos, videos and the regions stand for your own values. Causes and fixes: Amazon S3 delivery β†’ Troubleshooting.

Status Example message Meaning
ok Uploaded abc123.mp4 to bucket my-videos, folder videos/2026. Delivered. At the root of the bucket: Uploaded abc123.mp4 to bucket my-videos.
ok … The bucket is in eu-west-1, not us-east-1: edit the connection. Delivered, but the destination's region is wrong. Edit it.
error AWS does not know this access key ID: it was deleted, deactivated or mistyped. Check it in IAM (the user β†’ Security credentials) and edit the connection. Unknown, deleted or deactivated access key.
error The secret access key does not match the access key ID. Paste the secret access key again in the connection. Wrong secret access key.
error The access key may not write to bucket my-videos, folder videos. Allow s3:PutObject on arn:aws:s3:::my-videos/videos/* in the IAM user's policy. AWS denied the upload: the IAM policy, a bucket policy, an SCP or a permissions boundary. At the root of the bucket: …to the root of bucket my-videos. Allow s3:PutObject on arn:aws:s3:::my-videos/* …
error Bucket my-videos encrypts objects with an AWS KMS key this access key may not use. Allow kms:GenerateDataKey and kms:Decrypt on that key for the IAM user. SSE-KMS bucket; the IAM user may not use the key.
error Bucket my-videos does not exist. Check its name in the S3 console and edit the connection. Wrong bucket name.
error Bucket my-videos is in region eu-west-1, not us-east-1. Edit the connection and choose eu-west-1. Wrong region, not corrected. Also Bucket my-videos is not in region us-east-1. Check its region (S3 console β†’ the bucket β†’ Properties β†’ AWS Region) and edit the connection.
error Amazon S3 is not available in region <region>. Check the bucket's region (S3 console β†’ the bucket β†’ Properties β†’ AWS Region) and edit the connection. The region does not exist.
error The connection to Amazon S3 (region eu-west-1) failed: <reason>. Network error or timeout.
error Amazon S3 answered <code> (HTTP <status>): <reason>. Any other AWS error.
error Stopped: the delivery ran out of time. The upload did not finish within the render's delivery budget (about 5 minutes for all destinations). It was cancelled.
error An aws-s3 destination needs the ID of a saved connection (Dashboard β†’ Connections β†’ Output destinations). An aws-s3 destination without id. There is no inline form.
error In an aws-s3 destination the movie can only set remote-path and file. Bucket, region and keys come from the connection. The movie's destination has other fields next to id. Nothing was delivered.
error Connection "<id>" is of type aws-s3, not ftp. Remove "type" from the movie or use another connection. The movie's type does not match the saved destination.
error The secret-access-key of connection "<id>" could not be read. Save the connection again in Dashboard β†’ Connections. Enter the secret access key again in the dashboard.
error The object key is … bytes long; Amazon S3 allows at most 1024. Shorten remote-path or file. / The object key cannot contain a ".." folder. Edit remote-path or file. Fix the folder or the file name.

Connections (dashboard)

Messages shown in Dashboard β†’ Connections when saving or testing:

Message Cause
You can run up to 20 tests per hour. Try again after HH:MM UTC. More than 20 tests (keys and destinations together) in the current hour. Tests refused before contacting anything do not count.
ElevenLabs API keys start with "sk_". Check that you copied the whole key. The key does not look like an ElevenLabs key.
A connection with this ID already exists. Choose another ID. IDs are unique per account.
"none" is reserved: "connection": "none" tells a render to use JSON2Video's own key. Choose another ID. none cannot be used as an ID.
The ID looks like an API key. IDs are not encrypted: … Don't put secrets in IDs.
The ID can only contain lowercase letters, numbers, "-" and "_", and must start with a letter or a number. See Connection IDs.
The webhook URL must start with https:// Webhooks are saved with https:// URLs only.
The webhook URL cannot point at localhost: JSON2Video calls it from the internet. Also for private IP addresses and JSON2Video's own API.
Enter only the host name, without ftp:// or sftp:// FTP/SFTP host must be a bare host name or IP.
The port must be a whole number between 1 and 65535 (21 for FTP, 22 for SFTP). Invalid port.

Amazon S3 connections

When you save or test an Amazon S3 destination, its fields are checked first. The API answers 400 with a code and the field:

code field Message
missing_field bucket Enter the bucket name, e.g. my-videos.
invalid_bucket bucket Enter only the bucket name, without s3://, a URL or a folder. Put the folder in the remote path.
invalid_bucket bucket A bucket name can only contain lowercase letters, numbers, dots (.) and hyphens (-). β€” also …is 3 to 63 characters long., …must start and end with a lowercase letter or a number., …cannot contain two dots in a row., …cannot be an IP address., and names with a prefix or suffix that AWS reserves (xn--, -s3alias, …).
blocked_bucket bucket This bucket belongs to JSON2Video. Enter the name of a bucket in your own AWS account.
missing_field region Choose the bucket's region, e.g. eu-west-1.
invalid_region region Choose the bucket's region, e.g. eu-west-1. You find it in the S3 console: your bucket β†’ Properties β†’ AWS Region.
unsupported_region region AWS regions in China (cn-…) are not supported: they are a separate AWS partition. Use a bucket in another region. β€” also for GovCloud (us-gov-…) and isolated regions.
missing_field access-key-id Paste the access key ID of an IAM user. It starts with AKIA.
temporary_access_key access-key-id This is a temporary access key (it starts with ASIA): it stops working within hours. Create an access key for an IAM user (it starts with AKIA).
invalid_access_key_id access-key-id An access key ID has 20 characters and starts with AKIA. Check that you copied all of it, and that it is the access key ID, not the secret access key.
missing_field secret-access-key "secret-access-key" is required for an aws-s3 connection.
invalid_secret_access_key secret-access-key The secret access key is 40 characters long. Check that you copied all of it. β€” also The secret access key only contains letters, numbers, "/" and "+". … and This is the access key ID, not the secret access key. …

The Test button of an Amazon S3 destination writes json2video-test.txt to the folder and answers Wrote json2video-test.txt to bucket my-videos, folder videos. JSON2Video does not delete it: you can. when it works. Other test messages: the Amazon S3 deliveries table, plus No answer from Amazon S3 for bucket my-videos (region eu-west-1) within 10 s. Try again in a moment. and The secret-access-key of this connection could not be read. Enter it again and save the connection, then test again.

Timeouts

When a render is running for more than 15 minutes, GET /v2/movies returns movie.status = "timeout" with message = "Movie took too long to render". The original render may still eventually complete; treat timeout the same as error for client code paths.

Retry guidance

Class Retry strategy
400 validation Do not retry. Fix the payload.
401 quota Do not retry until credits are topped up.
403 auth Do not retry. Fix the key or role.
404 not found Do not retry. Confirm the ID.
409 conflict Do not retry blindly. Resolve the conflict (rename, delete the existing file).
413 payload too large Do not retry the same payload. Make it smaller.
500 internal Retry with exponential backoff, up to 3–5 attempts.
movie.status = "error" Inspect the message. Re-submit a fixed payload if the cause was client-side.
movie.status = "timeout" Re-submit the same job; treat as a transient failure.