# Eliza Cloud API (from eliza-cloud-v2 source) Reference: [elizaOS/eliza-cloud-v2](https://github.com/elizaOS/eliza-cloud-v2) (or current deployment) for endpoints and auth. ## Base URL - **Production:** `https://elizacloud.ai/api/v1` (or `https://cloud.elizaos.com/api/v1` depending on deployment) - PRR uses: `https://elizacloud.ai/api/v1` (see `ELIZACLOUD_API_BASE_URL` in `src/constants.ts`) ## Auth - **Header:** Production elizacloud.ai accepts **`X-API-Key: `** for chat/completions. The codebase also supports `Authorization: Bearer `; if chat returns 401 with Bearer, use X-API-Key. - **PRR** sends `X-API-Key` for all Eliza Cloud requests (models and chat) so it works with production. - **Key format:** `eliza_` + 64 hex chars (e.g. `eliza_...75`), generated by Eliza Cloud and stored by hash in the app DB. - Keys are validated by `apiKeysService.validateApiKey()` (hash lookup); the key must exist in the `api_keys` table and be active. ## Endpoints ### GET /api/v1/models - **Auth:** Optional. Uses `requireAuthOrApiKey(request)` but **on failure falls back to anonymous** and still returns 200 with the model list. - So a missing or invalid key does **not** cause 401 here; you get the list as an anonymous user. - **Response:** OpenAI-compatible `{ object: "list", data: [ { id, ... }, ... ] }`. ### POST /api/v1/chat/completions - **Auth:** Required. Uses `requireAuthOrApiKeyWithOrg(request)` — **no anonymous fallback**. - Requirements: 1. Valid API key (Bearer or X-API-Key) that exists in the DB and is active. 2. The user linked to that key must have **`organization_id`** and **`organization`** (used for credits/billing). - If the key is invalid → 401. - If the key is valid but the user has no organization → error: *"Forbidden: This feature requires a full account. Please sign up to continue."* (can surface as 401 depending on handling). - **Rate limit (production):** **10 requests per 60 seconds** per API key (or per user/session). The route uses `RateLimitPresets.STRICT`. Development uses 10000/min. Keys are from `getDefaultKey` (X-API-Key, Bearer `eliza_*`, or user/session). 429 when exceeded. ## Why GET /models can “work” but POST /chat/completions returns 401 1. **GET /models** If your key is invalid or not in the DB, the route catches the auth error and serves the model list to an **anonymous** user. So you see 200 and a list even when the key is not accepted. 2. **POST /chat/completions** There is no fallback. The key must: - Be present in the Eliza Cloud DB (valid, active, not expired), and - Belong to a user that has an organization (for billing). So “models works, chat returns 401” usually means either: - The key is **not** in the Eliza Cloud database (wrong env, different deployment, or key created elsewhere), or - The key **is** valid but the associated user has **no organization** (account not fully set up for paid features). ## What to do 1. **Confirm the key** was created in the same Eliza Cloud deployment you’re calling (e.g. elizacloud.ai) and is shown as active in the dashboard. 2. **Confirm the account** has an organization (full account, not anonymous) so chat/completions can bill. 3. **Optional:** Try `X-API-Key: ` instead of `Authorization: Bearer ` in case the server treats them differently (both are supported in `lib/auth.ts`). ## Rate limits (eliza-cloud-v2) From `lib/middleware/rate-limit.ts` and `app/api/v1/chat/completions/route.ts`: | Preset | Window | Production | Used by | |-----------|---------|------------|--------| | STANDARD | 1 min | 60 req/min | `/api/v1/chat` (Vercel AI responses) | | **STRICT**| **1 min** | **10 req/min** | **POST /api/v1/chat/completions** (OpenAI-compatible) | | CRITICAL | 5 min | 5 req/5min | Deployments, payments | | BURST | 1 s | 10 req/s | Real-time features | - **Chat completions** uses **STRICT**: **10 requests per minute per API key** in production. Development: 10000/min. - Limit is applied per key from `getDefaultKey`: X-API-Key, or `Authorization: Bearer` when token is `eliza_*`, or user/session. - Production uses Redis-backed rate limiting when `REDIS_RATE_LIMITING=true`; otherwise in-memory (not suitable for multi-instance). **PRR:** To stay under 10/min, PRR uses at most 1 concurrent request and a minimum delay of 6s between starts (`ELIZACLOUD_MIN_DELAY_MS`), plus 429 retries with 60s backoff. All phases (dedup, batch analysis, fix, verify) share the same global limit. ## Source locations (eliza-cloud-v2) | What | Path | |------------|------| | Models route | `app/api/v1/models/route.ts` | | Chat route | `app/api/v1/chat/completions/route.ts` | | Rate limit | `lib/middleware/rate-limit.ts` (`RateLimitPresets`), `lib/middleware/rate-limit-redis.ts` | | Auth | `lib/auth.ts` (`requireAuthOrApiKey`, `requireAuthOrApiKeyWithOrg`) | | API key svc | `lib/services/api-keys.ts` (`validateApiKey`) |