Browse Docs
On This Page

Error Codes

All Tools.FAST APIs use a consistent error response format. The same error codes and structure apply across Convert.FAST, Compress.FAST, and every tool in the network.

Error envelope

Every error response returns a JSON object with at least two fields:

{
  "error": "machine.readable_code",
  "detail": "Human-readable explanation."
}

Some errors include additional context fields (e.g., sourceFormat, supportedTargets, megabytes).

HTTP status codes

400 Bad Request

Invalid request payload, parameters, or content type.

Invalid content type
{
  "error": "request.invalid_content_type",
  "detail": "multipart/form-data required."
}
No files provided
{
  "error": "request.no_files",
  "detail": "No files were provided in the request."
}
Empty file
{
  "error": "request.empty_file",
  "detail": "Uploaded file is empty."
}
Invalid extension
{
  "error": "request.invalid_extension",
  "detail": "File extension not accepted by converter."
}
Invalid parameter
{
  "error": "request.invalid_parameter",
  "detail": "Invalid value for parameter 'quality'."
}

401 Unauthorized

The API key is missing, invalid, or not allowed from the caller's IP.

{
  "error": "api_key.invalid_or_ip_not_allowed",
  "detail": "X-Fast-Api-Key was provided but is invalid for this request (or IP not allowlisted)."
}

402 Payment Required

The caller's account does not have enough credits or has exceeded a usage limit.

Insufficient credits
{
  "error": "entitlements.insufficient_credits",
  "detail": "Insufficient credits. Required: 5, Available: 2"
}
Daily limit exceeded (free/guest)
{
  "error": "usage.daily_limit_exceeded",
  "detail": "Daily usage limit exceeded. Used: 100/100"
}

403 Forbidden

The resource exists but the caller does not own it.

{
  "error": "batch.forbidden",
  "detail": "You do not have access to this batch."
}

404 Not Found

The requested job or batch does not exist.

Job not found
{
  "error": "jobs.not_found",
  "detail": null
}
Batch not found
{
  "error": "batch.not_found",
  "detail": null
}

409 Conflict

The request conflicts with the current state of the resource.

Job not ready
{
  "error": "jobs.not_ready",
  "detail": "Job is still processing or waiting to start."
}
Not cancellable
{
  "error": "jobs.not_cancellable",
  "detail": "Cannot cancel completed/failed jobs."
}

410 Gone

The job completed but its output artifacts have expired and been cleaned up.

{
  "error": "jobs.expired",
  "detail": "Job output has expired and is no longer available for download."
}

413 Payload Too Large

The uploaded file exceeds the per-converter or global size limit.

{
  "error": "request.file_too_large",
  "detail": "File exceeds the maximum allowed size.",
  "megabytes": 50
}

429 Too Many Requests

The caller has been throttled. Check the Retry-After header.

Rate limited
{
  "error": "rate_limited",
  "detail": "Too many requests. Retry after 12 seconds."
}
Queue limit exceeded
{
  "error": "queue.limit_exceeded",
  "detail": "Too many queued jobs. Wait for existing jobs to complete."
}
Pool saturated
{
  "error": "queue.pool_saturated",
  "detail": "Worker pool is at capacity. Try again shortly."
}

Headers on 429 responses:

Header Description
Retry-After Seconds until you can retry

Best practice: implement exponential backoff in your client, or honour the Retry-After value directly.

Complete error codes reference

Request errors

Code Status Description
request.invalid_content_type 400 Must use multipart/form-data
request.no_files 400 No file attached to the request
request.empty_file 400 Uploaded file has zero bytes
request.invalid_extension 400 File extension not accepted by the converter
request.invalid_parameter 400 A request parameter has an invalid value
request.multiple_files 400 Only one file per request is allowed
request.image_too_large 413 Image dimensions exceed the maximum
request.file_too_large 413 File exceeds the size limit for this converter/tier

Authentication errors

Code Status Description
api_key.invalid_or_ip_not_allowed 401 API key is missing, invalid, or IP not in allowlist

Entitlements errors

Code Status Description
entitlements.insufficient_credits 402 Not enough credits to process this job
entitlements.queue_limit_exceeded 402 Maximum queued jobs reached for this tier
entitlements.invalid_user 402 User account is not in a valid state
entitlements.error 500 Internal entitlements service error

Batch errors

Code Status Description
batch.not_found 404 Batch ID does not exist
batch.forbidden 403 Batch belongs to another user
batch.limit_exceeded 429 Too many active batches
batch.zip_limit_exceeded 400 ZIP download exceeds size limit
batch.output_limit_exceeded 400 Batch output exceeds limit
batch.empty 400 Batch contains no jobs
batch.expired 410 Batch artifacts have been cleaned up

Job errors

Code Status Description
jobs.not_found 404 Job ID does not exist
jobs.not_ready 409 Job is still processing; download not available yet
jobs.expired 410 Job output has been cleaned up
jobs.forbidden 403 Job belongs to another user
jobs.timeout 500 Job exceeded the processing time limit
jobs.not_deletable 409 Job cannot be deleted in its current state

Queue errors

Code Status Description
queue.limit_exceeded 429 Too many queued jobs; wait for existing jobs to finish
queue.pool_saturated 429 Worker pool is at capacity
rate_limited 429 IP-level rate limit exceeded

Usage errors

Code Status Description
usage.daily_limit_exceeded 402 Free/guest daily credit cap reached

Tool-specific errors

Individual tools may define additional error codes under their own namespace. See each tool's API documentation for converter-specific errors:

Handling errors in code

cURL
RESPONSE=$(curl -sS -w "\n%{http_code}" -X POST "https://api.tools.fast/convert" \
  -H "X-Fast-Api-Key: $API_KEY" \
  -F "file=@photo.heic" \
  -F "targetFormat=jpg")

HTTP_CODE=$(echo "$RESPONSE" | tail -1)
BODY=$(echo "$RESPONSE" | sed '$d')

if [ "$HTTP_CODE" -ge 400 ]; then
  ERROR=$(echo "$BODY" | jq -r '.error')
  DETAIL=$(echo "$BODY" | jq -r '.detail')
  echo "Error $HTTP_CODE: [$ERROR] $DETAIL"

  if [ "$HTTP_CODE" = "429" ]; then
    echo "Rate limited. Retry after delay."
  fi

  exit 1
fi

JOB_ID=$(echo "$BODY" | jq -r '.id')
echo "Job submitted: $JOB_ID"
PowerShell
try {
  $job = Invoke-RestMethod -Method Post "https://api.tools.fast/convert" `
    -Headers @{ "X-Fast-Api-Key" = $env:API_KEY } `
    -Form @{ file = Get-Item "photo.heic"; targetFormat = "jpg" }

  Write-Host "Job submitted: $($job.id)"
}
catch {
  $statusCode = $_.Exception.Response.StatusCode.value__
  $body = $_.ErrorDetails.Message | ConvertFrom-Json

  Write-Host "Error ${statusCode}: [$($body.error)] $($body.detail)"

  if ($statusCode -eq 429) {
    Write-Host "Rate limited. Retry after delay."
  }

  exit 1
}
Copied.