Errors & idempotency

Status codes, error envelope, safe retries.

All errors share a single envelope:

{
  "error": {
    "code": "rate_limited",
    "message": "Rate limit exceeded (5 req/s). Retry after 7s."
  }
}

Codes

HTTPcodeMeaning
400unknown_toolTool slug not found in the registry.
400missing_inputinput.url or input.fileId required.
401unauthorizedMissing or malformed bearer token.
401invalid_keyKey not recognized.
401revokedKey has been revoked.
401expiredKey has expired.
402insufficient_creditsAccount balance is below the cost of this job.
402spend_cap_reachedPer-key daily/monthly spend cap reached.
403plan_not_eligibleOwner is not on Pro or Max.
403ip_not_allowedSource IP not in this key's allowlist.
403insufficient_scopeKey lacks the required scope.
404not_foundJob not found, or not owned by this key.
409cannot_cancelJob is already running or finished.
413file_too_largeUpload exceeds plan size limit.
429rate_limitedPer-key RPS exceeded.
429concurrency_exceededToo many concurrent in-flight jobs.
500enqueue_failedJob submission failed before reaching the queue.

Idempotency

Pass idempotencyKey on POST /v1/jobs. If the same key + value combination is replayed within 24 hours we return the original response without enqueueing a new job. Use a UUID per logical request.

POST /v1/jobs
{ "tool": "...", "input": {...}, "idempotencyKey": "0f...uuid" }