Errors

What a failure looks like.

Application errors use the HTTP status and a JSON detail object. Show message to a person. Branch on code.

{
  "detail": {
    "code": "text_too_long",
    "message": "5,001 characters is over the 5,000 limit for one run."
  }
}

Some errors add details. A low balance looks like this:

{
  "detail": {
    "code": "insufficient_balance",
    "message": "Available balance is 0.01 USD. This run needs about 0.05 USD reserved until the final cost is known.",
    "details": {
      "available_usd": "0.010000",
      "hold_required_usd": "0.050000",
      "is_estimate": true
    }
  }
}

Status codes

HTTPCodeWhen
400invalid_requestThe body is missing prose, quality is not low, standard, or high, or an estimate has neither text nor word_count.
400text_too_longThe draft is over max_chars_per_run (5,000 characters).
400confirmation_requiredDELETE /v1/runs without ?confirm=true.
401unauthenticatedMissing or unknown API key, or no session.
402insufficient_balanceThe available balance cannot cover the hold. Nothing is queued.
403account_suspendedThe account cannot call the API.
403forbiddenAn API key tried to create another API key.
404not_foundThat run or key is not yours, or does not exist.
409run_in_progressDelete was called on a queued or running run. Cancel it first.
422The JSON shape is wrong. Unknown fields such as model or mode are rejected here. The body is a validation list, not a code.
429rate_limitedToo many creates. Wait for the Retry-After header. details.retry_after_seconds says the same thing.
503provider_unavailableThe account is not ready to run yet. Try again shortly, and check can_run_reason on GET /v1/me.

Validation errors

A 422 means the request never reached a run. The usual cause is a field the API no longer accepts.

{
  "detail": [
    {
      "type": "extra_forbidden",
      "loc": ["body", "model"],
      "msg": "Extra inputs are not permitted"
    }
  ]
}