> ## Documentation Index
> Fetch the complete documentation index at: https://docs.spatius.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Spatius API Errors and Limits

> Spatius API error envelope, HTTP status mapping, avatar job failure codes, and per-account rate limits.

## Error envelope

Every Spatius API error returns the same JSON envelope, regardless of which endpoint failed:

```json theme={null}
{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Open API rate limit exceeded",
    "requestId": "b3f0c2d1-4a5b-4c6d-8e9f-0a1b2c3d4e5f"
  }
}
```

* `code` is a stable machine-readable string. Program against `code`, not `message`.
* `message` is a human-readable explanation specific to this occurrence.
* `requestId` uniquely identifies the request. It is also returned in the `X-Request-ID` response header. Quote it when contacting support.

## HTTP status and error code mapping

| HTTP status | `code`                       | Meaning                                                                                                                                                               |
| ----------- | ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `400`       | `invalid_request`            | Malformed request: missing `imageUrl`, an invalid ID in the path, a page token that is invalid or does not match `pageSize`, or no active avatar pipeline configured. |
| `401`       | `unauthorized`               | Missing or mismatched `X-App-ID` / `X-API-Key` pair. See [Authentication](/api-reference/authentication).                                                             |
| `402`       | `insufficient_avatar_units`  | The account has no Avatar Creations left. View your balance at [app.spatius.ai/avatars/creations](https://app.spatius.ai/avatars/creations).                          |
| `403`       | `forbidden`                  | API access is not configured (`Open API access is not configured`), or avatar creation is disabled for the account (`API Avatar creation is disabled`).               |
| `404`       | `not_found`                  | The avatar or job does not exist, or belongs to another account.                                                                                                      |
| `429`       | `rate_limit_exceeded`        | A rate limit or the rolling 24-hour creation quota was exceeded.                                                                                                      |
| `429`       | `concurrency_limit_exceeded` | Too many jobs are queued or processing at once. Wait for an active job to finish.                                                                                     |
| `500`       | `internal_error`             | An unexpected server error. Retry with backoff; quote `requestId` if it persists.                                                                                     |
| `501`       | `unsupported_input`          | The request uses an input that this API version does not support yet.                                                                                                 |
| `503`       | `service_unavailable`        | A transient backend failure, for example reservation contention. Retry the request.                                                                                   |

## Job failure codes

When a creation job reaches `failed`, the job's `error` object carries one of these codes:

| Code                       | Message                                                                      | Meaning                                                                                                                                             |
| -------------------------- | ---------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `source_download_failed`   | `The source image could not be downloaded.`                                  | The image URL could not be fetched or stored. Host the image on fast, reliable storage and resubmit.                                                |
| `invalid_image`            | `The source image is not a supported opaque JPEG or PNG of sufficient size.` | The file is not a valid JPEG or PNG, exceeds 5 MiB, is smaller than 340 px on its shorter side, or is a non-opaque PNG. Fix the image and resubmit. |
| `image_quality_rejected`   | `The source image did not pass Avatar image requirements.`                   | The image passed format validation but was rejected by content checks, for example because it does not contain exactly one clearly visible face.    |
| `preprocess_failed`        | `The source image could not be preprocessed.`                                | Preprocessing failed after download. Retry; contact support if it persists.                                                                         |
| `avatar_generation_failed` | `Avatar generation failed.`                                                  | Avatar generation failed or could not be started. Retry; contact support if it persists.                                                            |
| `internal_error`           | —                                                                            | An unexpected failure. Retry; quote the job ID when contacting support.                                                                             |

The `retryable` flag on the error indicates whether resubmitting the same request may succeed.

## Rate limits

Limits are enforced per account. Your account may be configured below these hard caps:

| Limit                                   | Hard cap     |
| --------------------------------------- | ------------ |
| Avatar creations per minute             | 20           |
| Avatar creations per hour               | 200          |
| Avatar creations per rolling 24 hours   | 2,000        |
| Concurrent active creation jobs         | 10           |
| Read requests per second (token bucket) | 20, burst 40 |
| Read requests per minute                | 1,200        |

Read limits apply to the `GET` endpoints; creation limits apply to `POST /avatars`. When a limit is hit, the API returns `429` with `rate_limit_exceeded` (or `concurrency_limit_exceeded` when the concurrency cap is the binding constraint). Back off and retry — for job polling, an interval of 5–10 seconds stays comfortably within the read limits.

## Pagination

Both list endpoints (`GET /avatars` and `GET /avatar-jobs`) paginate the same way. They accept `pagination.pageSize` and `pagination.pageToken`, and return `pagination.nextPageToken` and `pagination.totalCount`.

`pageSize` defaults to 20 and has a maximum of 99.

<Warning>
  A `pageSize` above 99 does not return 99 items — it falls back to the default of 20. Request at most 99 to avoid receiving fewer items than you expect.
</Warning>

To page through results, pass the previous response's `pagination.nextPageToken` as `pagination.pageToken`. An empty `nextPageToken` means there are no more pages. Treat the token as opaque and pass back exactly what you received; do not construct or increment it yourself. An invalid page token is rejected with `400` and `invalid_request`.

<Warning>
  Keep `pageSize` the same for every request in a pagination sequence. A token is only valid for the `pageSize` it was issued with, and reusing it with a different `pageSize` is rejected with `400` and `invalid_request`. To change the page size, start again from the first page with no `pageToken`.
</Warning>

## Next steps

<CardGroup cols={2}>
  <Card title="Overview" icon="book-open" href="/api-reference/overview">
    The asynchronous avatar creation flow, end to end.
  </Card>

  <Card title="Authentication" icon="key" href="/api-reference/authentication">
    The X-App-ID and X-API-Key header pair.
  </Card>
</CardGroup>
