code is stable and safe to branch on. message is for humans and may change. details
is present when we can name the offending field.
Codes
400 is for a request we cannot parse or understand. 422 is reserved for a request that
is perfectly well-formed but that we cannot process right now — today that means
REGION_UNAVAILABLE alone. Branching on error.code is more durable than branching on
the status.Region unavailability
CHATGPT and CLAUDE draw on pools of real accounts that are bound to a region. Before
queuing, the API checks whether it can actually serve payload.country (defaulting to
US) and rejects up front if it cannot:
GET /capacity to see what each
region can currently serve.
Every other engine is stateless from an account perspective and is never rejected this way.
Batch failures are per-item
A well-formed batch always returns200, even if every task inside it failed. The HTTP
status describes the request; results[].success describes each task.
A batch item can fail with
REGION_UNAVAILABLE or ENQUEUE_ERROR, neither of which
appears in Cloro’s documented per-item error enum. Both are additions, not replacements —
VALIDATION_ERROR and RESOURCE_ALREADY_EXISTS behave as Cloro specifies.Task-level failures
A task that fails after being queued does not produce an HTTP error at all. You learn about it from the terminal status:error is a string, not the {code, message, timestamp} object used by request-level errors. It is the last engine error recorded
before the task gave up. The same task delivers a webhook with task.status === "FAILED".