Log In Sign Up

Docs

Errors

Every error response is JSON. Validation errors follow Laravel's standard format. Status codes are conventional.

All error responses are JSON. Validation errors follow Laravel’s standard format:

{
  "message": "The output format field must be one of: png, jpg, jpeg, ...",
  "errors": {
    "output_format": [
      "The output format field must be one of: png, jpg, jpeg, ..."
    ]
  }
}

Status codes

StatusWhen
401Missing or unrecognized API key.
403API key recognized but not authorized to act on the resource.
404Task or job ID not found, or not visible to this API key.
422Validation failure (bad format, missing field, invalid option value).
429Rate limit exceeded (600/min/account). The Retry-After header gives the wait in seconds.
5xxInternal failure. Retry with exponential backoff.

Processing errors (creation_failed)

A job lands in creation_failed when something went wrong producing the output: an unreachable URL, a bad input file, an unsupported codec combination, and so on. The API response for GET /convert/{id} and GET /jobs/{id} only reports the status; the underlying tool error (typically an ffmpeg, magick, or LibreOffice stderr message) is visible in the dashboard for that specific job.

Common causes:

  • Bad inputs: corrupt or truncated source file.
  • Unsupported codec combination: the output container can’t carry the input streams without re-encoding, and the chosen codec couldn’t produce a valid result.
  • Unreachable URL (website capture only): the source URL returned 4xx/5xx or didn’t respond. If http_success: true was set on the request, any 4xx/5xx response forces this state.
  • Validation that snuck past the synchronous response: rare, but possible if an option only proves invalid mid-job.

Resubmit the same request after fixing the input. If the job consistently fails, check the dashboard log for that job ID, the underlying tool stderr is recorded there.

Delivery errors (delivery_failed)

delivery_failed indicates the conversion succeeded but the upload to your destination’s storage didn’t. Common causes:

  • Storage credentials revoked or rotated.
  • Bucket permissions changed.
  • Destination misconfigured (e.g. region mismatch).

Check your destination configuration in the dashboard, then resubmit.

Rate limiting

When you hit 429, the response includes a Retry-After header with the recommended wait time in seconds. The simplest correct behaviour:

import time, requests
r = requests.post(url, auth=auth, files=...)
if r.status_code == 429:
    time.sleep(int(r.headers.get("Retry-After", 60)))
    r = requests.post(url, auth=auth, files=...)

For high-volume use, implement a token bucket on your side at 10 requests per second (the per-minute average of the 600/min limit) and you won’t see 429s in normal operation.