Reference

Errors

Every reelsdk error is JSON with a stable code and a readable message. A bad request fails with a 4xx before any job starts, and a job that fails answers 422 when the inputs are the problem or 500 when we are, with the job attached.

This page lists every code the API returns, with its HTTP status and what to do about it.

Error shape#

Branch on error.code, which never changes, and show or log error.message, which is written for people. INVALID_REQUEST also lists each bad field in issues, as a path and a message.

400 Bad Request
{
  "error": {
    "code": "INVALID_REQUEST",
    "message": "video_url: must be an http(s) URL; style: style must be a preset name or a style object",
    "issues": [
      { "path": "video_url", "message": "must be an http(s) URL" },
      {
        "path": "style",
        "message": "style must be a preset name or a style object"
      }
    ]
  }
}

When a job fails, the response carries the job next to the error. Webhooks and GET /v1/jobs/{id} report the same job.error.

422 Unprocessable Content
{
  "error": {
    "code": "INPUT_FETCH_FAILED",
    "message": "Could not fetch video_url: HTTP 404"
  },
  "job": {
    "id": "job_0hf8no7i1xqwngpyj317",
    "op": "captions",
    "status": "failed",
    "stage": null,
    "created_at": "2026-10-26T01:15:26.416Z",
    "finished_at": "2026-10-26T01:15:29.195Z",
    "outputs": {},
    "result": null,
    "duration_s": null,
    "error": {
      "code": "INPUT_FETCH_FAILED",
      "message": "Could not fetch video_url: HTTP 404"
    },
    "usage": {
      "output_seconds": 0,
      "audio_seconds": 0,
      "tts_characters": 0,
      "images": 0
    },
    "poll_url": "https://api.reelsdk.com/v1/jobs/job_0hf8no7i1xqwngpyj317"
  }
}

Request errors#

These come back before a job starts. Requests rejected with a 4xx never count toward your daily jobs.

CodeHTTPWhen it happens and how to fix it
INVALID_JSON400The body is empty or isn't valid JSON. Send a JSON object with Content-Type: application/json.
INVALID_REQUEST400A field failed validation, wait is outside 0 to 300, or an upload has no filename or an empty body. Fix the fields in issues.
UNSUPPORTED_LANGUAGE400A short asked for a language other than en, es, fr, ja, zh or ko.
UNSUPPORTED_FILE_TYPE400An upload's extension isn't one we serve. See file types.
CONTENT_LENGTH_REQUIRED400An upload had no usable Content-Length. Send the whole file instead of a stream.
UNAUTHORIZED401The Authorization: Bearer header is missing or malformed, the key is unknown (invalid API key) or it was revoked.
NOT_FOUND404The job id doesn't exist or belongs to another key (unknown job), a file expired after 7 days, or the route doesn't exist.
METHOD_NOT_ALLOWED405Create endpoints take POST. File URLs take GET or HEAD.
PAYLOAD_TOO_LARGE413A JSON body is over 2 MB or an upload is over 100 MB.
RATE_LIMITED429The key hit a limit, or your IP sent too many bad keys. Wait Retry-After seconds.
INTERNAL500Something broke on our side before the job started. Retry with backoff.

Job errors: 422#

A 422 means the job ran but its inputs can't produce a video. We don't retry these, and sending the same request again fails the same way.

CodeHTTPWhen it happens and how to fix it
INPUT_FETCH_FAILED422We couldn't download an input, as in Could not fetch images[2]: HTTP 403. Check that the URL is public and still valid.
INPUT_TOO_LARGE422An input is over 500 MB, or all inputs together are over 1,000 MB.
INPUT_UNSUPPORTED422A file isn't readable media, an image is over 100 megapixels, a video has no audio to transcribe, or audio or video runs over 15 minutes.
INVALID_SPEC422The request can't be rendered as asked, such as a slideshow that would run past 15 minutes.
OUTPUT_TOO_LARGE422The job wrote more than 8 GB, or its outputs add up to more than 2 GB. Lower the resolution or length.
CONTENT_REJECTED422Shorts only: the image safety filter flagged the scenes. Try a less graphic topic or script.
FFMPEG_FAILED422FFmpeg only: your command exited with an error. The message is the last useful line ffmpeg printed.
OUTPUT_MISSING422A file in ffmpeg outputs wasn't written or is empty.
TIMEOUT422FFmpeg only: the command ran past timeout_s or the 10 minute job limit.

Job errors: 500#

A 500 means something failed on our side. We already retried the job once before you see it, except after a TIMEOUT, so wait a little before you send it again.

CodeHTTPWhen it happens and how to fix it
PLAN_FAILED500Shorts: writing the script failed.
IMAGES_FAILED500Shorts: no scene image could be drawn.
TTS_FAILED500Text to speech failed, or the voiceover's words couldn't be timed for captions.
TRANSCRIBE_FAILED500Transcribing the audio for captions failed.
FFMPEG_FAILED500A slideshow, captions or shorts render failed in ffmpeg.
TIMEOUT500The job hit the 10 minute limit. Split the work or make it shorter.
CONTAINER_UNAVAILABLE500No video worker could start.
BUSY500The video worker was still busy with another job.
ENGINE_UNREACHABLE500The video worker stopped answering.
ENGINE_ERROR500The video worker sent back a response we couldn't read.
STORE_FAILED500Saving the inputs or outputs failed.
INTERNAL500Anything unexpected, including a job interrupted more often than its one retry allows.

When to retry#

StatusWhat to do
400, 401, 404, 405, 413Don't retry. Fix the request, the key or the id first.
422Don't retry as is. Change the inputs, the command or the topic.
429Wait the number of seconds in Retry-After, then send it again.
500Retry with exponential backoff, starting at a few seconds.

Last updated 26 October 2026