QuillAIQuillAIDocs
Sign in
ReferenceErrors

Errors

Every API error uses the same envelope — retry only on 5xx, never on 4xx.

Envelope

All HTTP errors return a single JSON object with an error field. The shape is stable across every endpoint — type is machine-readable, message is for humans, and request_id is always included.

error.jsonjson
{
  "error": {
    "type": "invalid_request_error",
    "code": "missing_field",
    "message": "url is required",
    "param": "url",
    "request_id": "req_01HZX5T9Y2R7Q8KMPF3VZABCDE"
  }
}

Types

The type field narrows to one of six values. The HTTP status always matches the type, so you can branch on either.

TypeHTTPMeaning
invalid_request_error400Malformed body, missing required field, or invalid enum value.
authentication_error401Missing, invalid, or revoked Bearer token.
permission_error403Key lacks the required scope, or the account is suspended.
not_found_error404The resource you asked for doesn't exist.
rate_limit_error429Reserved for future use — not yet enforced.
api_error500A bug on our side. Contact support with the request_id.

Common codes

The code field is machine-readable and stable. Branch on code, not on message.

  • missing_fieldA required field was not provided (see param for which one).
  • invalid_valueA field was present but outside the allowed range, format, or enum.
  • invalid_urlThe url you submitted is not a valid URL.
  • unsupported_sourceThe source host is recognised but not supported (e.g. a private video).
  • invalid_api_keyThe Bearer token is malformed or doesn't match any key.
  • key_revokedThe key was revoked — rotate from the Developers dashboard.
  • insufficient_pointsAccount balance is too low to start the job. Top up and retry.
  • duration_too_longFile exceeds the ~10h per-file duration limit. Split and submit in parts.
  • transcription_failedUpstream processing failed. Appears on the Transcription object, not the create response.
  • internal_errorUnhandled server error. Safe to retry with backoff; if it persists, contact support.

Request ID

Every response — success or failure — includes a request_id in the error envelope and in the X-Request-Id header. Always include it when reporting a problem; it lets us pull the full trace in seconds.

Retries

Retry only on 5xx. Use exponential backoff starting at 1s (1s, 2s, 4s, 8s, cap at 30s) with jitter. Never retry a 4xx automatically — the request will fail again the same way. For 429 responses, respect the Retry-After header if present; otherwise back off at least 1s.

Transcription-level errors

Async failures don't surface as an HTTP error on the create call — that call returns 200 with a job ID. Instead, the job's final state is status: "failed" with an error field on the Transcription object. Poll or subscribe to the transcription.failed webhook to handle them.

transcription.jsonjson
{
  "id": "trs_01HZX5T9Y2R7Q8KMPF3VZABCDE",
  "status": "failed",
  "error": {
    "code": "transcription_failed",
    "message": "Upstream transcription provider returned an error after 3 attempts."
  }
}