cloro WebsiteAPI Get an API key
API Reference › Guides › Error handling

Error handling

A practical reference for interpreting failures from the cloro API: the status codes we return, the shape of every error payload, how automatic retries work, and what to check when a request does not behave as expected.

Overview

Every cloro endpoint reports outcomes through conventional HTTP status codes paired with a predictable JSON body. A 2xx code means the request was accepted and processed; a 4xx code points to something in the request itself that needs correcting; and a 5xx code signals a problem on our side or in an upstream provider. Because the envelope is uniform across endpoints, a single handler in your client can parse and branch on any error we send.

HTTP status codes

FieldTypeDescription
200SuccessThe request completed and a result was returned.
400Bad RequestOne or more parameters failed validation.
401UnauthorizedThe API key was absent, malformed, or no longer valid.
403ForbiddenThe key lacks the required scope, or the account is out of credits.
404Not FoundThe requested route does not exist.
409ConflictThe operation clashed with the current state of a resource.
429Too Many RequestsA concurrency or rate ceiling was reached; which one depends on the endpoint.
499Client Closed RequestThe caller aborted the connection before the response was sent.
500Internal Server ErrorAn unexpected condition arose while processing the request.
502Bad GatewayAn upstream provider returned an error or timed out.

Error response formats

Most failures arrive as a nested error object carrying a machine-readable code, a human-readable message, an optional details map, and an ISO 8601 timestamp. Validation failures use a flatter shape with a success flag and a per-field details array. Treat the code value as the stable contract; the message text is meant for humans and may be reworded over time.

Standard error

{
  "error": {
    "code": "ERROR_CODE",
    "message": "Human-readable explanation of what went wrong",
    "details": {
      "context": "endpoint-specific fields appear here"
    },
    "timestamp": "2026-08-14T09:30:00.000Z"
  }
}

Validation error (400)

{
  "success": false,
  "error": "Request validation failed",
  "details": [
    {
      "field": "prompt",
      "message": "Prompt cannot be empty"
    }
  ]
}

Canceled request (499)

{
  "success": false,
  "error": {
    "code": "REQUEST_CANCELED",
    "message": "Request was canceled by client",
    "timestamp": "2026-08-14T09:30:00.000Z"
  }
}

Rate limiting (429)

Monitor endpoints under /v1/monitor/* enforce a concurrency ceiling and return CONCURRENT_LIMIT_EXCEEDED. All endpoints under /v1/* additionally enforce a sliding request rate and return RATE_LIMIT_EXCEEDED.

{
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Rate limit exceeded",
    "details": {
      "limit": 500,
      "window": "1s"
    },
    "timestamp": "2026-08-14T09:30:00.000Z"
  }
}

Common error codes

FieldTypeDescription
MISSING_API_KEY401No API key was supplied on the request.
INVALID_API_KEY_FORMAT401The key did not match the expected format.
INVALID_OR_EXPIRED_API_KEY401The key is unrecognized or has expired.
INSUFFICIENT_PERMISSIONS403The key does not carry the scope this endpoint requires.
INSUFFICIENT_CREDITS403The account balance cannot cover the request.
CONCURRENT_LIMIT_EXCEEDED429Too many monitor requests are in flight at once.
RATE_LIMIT_EXCEEDED429Requests arrived faster than the allowed rate window.
EXTERNAL_SERVICE_ERROR502An upstream AI provider failed to respond correctly.
INTERNAL_SERVER_ERROR500An unexpected server-side fault occurred.

Retry and cancellation

cloro automatically re-attempts transient failures on the server side, making up to ten attempts before giving up. Retrying stops as soon as the request succeeds or the attempt budget is exhausted, so you rarely need your own timeout logic for momentary glitches. For 500 and 502 responses, layering a client-side retry with exponential backoff on top of our built-in mechanism adds useful resilience against network hiccups and upstream slowdowns.

Notes

Canceling a request after submission does not refund it: you are billed for the work already performed, since charges reflect resources consumed rather than only completed results. Batch task creation follows a partial-success model, so individual entries may fail with per-item codes such as VALIDATION_ERROR or RESOURCE_ALREADY_EXISTS inside an overall 200 response. Prompts must be between 1 and 10,000 characters, country codes must be valid ISO 3166-1 alpha-2 values, and boolean include.* flags reject any non-boolean value. If failures persist after these checks, reach out at [email protected].