---
name: phoenixai
description: PhoenixAI API integration skill — generate images and call LLMs through PhoenixAI (https://ai.suzatei.com) with a single sk- model key. Use when the user wants to integrate PhoenixAI image generation (async submit + poll), call PhoenixAI's OpenAI-compatible chat API, or wire the phoenix CLI / phoenixai-mcp into a project.
---

# PhoenixAI API Integration Guide

PhoenixAI is a unified API for image generation and LLM chat. One `sk-` model key, one balance, one generation history.

## Quick start

1. Create a model key (`sk-...`) in the PhoenixAI panel: https://ai.suzatei.com
2. Export it for the current shell:

```bash
export PHOENIX_MODEL_KEY="sk-..."
export PHOENIX_BASE_URL="https://ai.suzatei.com"   # optional, this is the default
```

3. Make it permanent (zsh; use `~/.bashrc` for bash). The `phoenix` CLI deliberately never saves the key to its own config file, so the shell profile is the place for it:

```bash
echo 'export PHOENIX_MODEL_KEY="sk-..."' >> ~/.zshrc && source ~/.zshrc
chmod 600 ~/.zshrc
```

GUI apps (Cursor, Claude Desktop) do not read the shell profile — put the key in the MCP config's `env` instead. For Claude Code use `claude mcp add phoenixai --scope user -e PHOENIX_MODEL_KEY=sk-... -- phoenixai-mcp`.

**Key handling rules for the assistant:** never hardcode a user's key in source files, commit it, or echo it back in chat; read it from the `PHOENIX_MODEL_KEY` environment variable in generated code. If the user has not set a key, show them the commands above and let them run it.

## Two APIs

| API | Base URL | Purpose |
|-----|----------|---------|
| **Image generation** | `https://ai.suzatei.com/workspace/api` | Async: submit → poll record → download |
| **LLM (OpenAI-compatible)** | `https://ai.suzatei.com/v1` | `/chat/completions`, `/models` |

Auth differs by API: the **image API** takes the header `X-Model-Key: sk-...` (an `Authorization: Bearer sk-...` header is rejected with 401 there); the **LLM API** takes `Authorization: Bearer sk-...`.

### Image endpoints

| Method | Path | Description |
|--------|------|-------------|
| `GET` | `/workspace/api/generate/models` | Model catalog (series → modes → `model` id, `params`, `refs`) |
| `POST` | `/workspace/api/generate/submit` | Submit a task, returns `{generation:{id,status}}` |
| `GET` | `/workspace/api/generate/record/{id}` | Poll status/result, returns `{generation}` |
| `GET` | `/workspace/api/generate/history` | List past generations (`limit` 1-100, `offset`) |
| `DELETE` | `/workspace/api/generate/record/{id}` | Delete a record |
| `POST` | `/workspace/api/generate/upload?kind=image` | Upload a reference file (raw body), returns `{attachment:{id}}` |

Task status: `processing` → `completed` | `failed`. When completed, `generation.results` is an array of **site-relative** paths — prefix with the base URL to download. Results are purged after a retention window (default 6 hours), so download promptly.

## CRITICAL: never fabricate — always fetch

Model ids and parameters change. Before writing any request:

1. Call `GET /workspace/api/generate/models` and use a `model` id that is in the response (it lists only the models enabled for this key).
2. Build `params` only from that mode's `params[].name`; honor `options` / `default`. If a mode has `refs`, upload files first and pass `refs: {"<field>": ["<attachment id>"]}`.
3. For LLMs, call `GET /v1/models` and use an `id` from it.

Do not copy model ids from examples in docs or this file.

## Submit flow

```bash
curl -s https://ai.suzatei.com/workspace/api/generate/submit \
  -H "X-Model-Key: $PHOENIX_MODEL_KEY" -H "Content-Type: application/json" \
  -d '{"kind":"image","model":"<model id from /generate/models>","prompt":"a phoenix rising from fire","params":{}}'
```

Then poll `GET /workspace/api/generate/record/{id}` every **3 seconds** (the server throttles faster polling) until `completed` or `failed`. Time out client-side after ~180 s and keep the id so the user can query later.

## Errors and retries

| HTTP | Meaning | Action |
|------|---------|--------|
| 400 | Unknown model, bad params/refs, or `MODEL_PRICE_MISSING` | Fix the request / pick another model |
| 401 | Missing or invalid key | Check `PHOENIX_MODEL_KEY` |
| 403 | `INSUFFICIENT_QUOTA` (balance too low) | Top up in the panel |
| 403 | `MODEL_NOT_ENABLED` (model not offered to this key) | Use a model from `/generate/models` (the catalog only lists enabled models) |
| 403 | `NO_MODEL_KEY` / generation restricted by the operator | Create/enable a model key, or contact the operator |
| 500 / 503 | `BILLING_TARGET_NOT_FOUND`, `MODEL_CHECK_UNAVAILABLE` | Retry later; contact the operator if it persists |
| 429 | Rate limited (submit: 20/min, upload: 30/min by default) | Back off and retry |
| 5xx | Server/upstream error | Retry GET with backoff |

- **GET**: retry up to 3 times with exponential backoff (1s → 2s → 4s).
- **POST /submit**: do NOT auto-retry on network timeout — the task may already exist and be billed. Check `history` first. Failed generations are refunded automatically.

## CLI and MCP (no code needed)

```bash
curl -fsSL https://ai.suzatei.com/dl/install.sh | bash            # phoenix CLI
curl -fsSL https://ai.suzatei.com/dl/install.sh | bash -s -- --mcp # MCP server
phoenix generate image <model id> -p "prompt" --json
claude mcp add phoenixai -e PHOENIX_BASE_URL=https://ai.suzatei.com -e PHOENIX_MODEL_KEY=sk-... -- phoenixai-mcp
```

MCP tools: `phoenix_list_models` (slim list by default; pass `model` for one model's full params), `phoenix_generate_image`, `phoenix_get_generation`. CLI: `phoenix models` (slim), `phoenix models --model <id>` (full params), `phoenix models --full`. CLI/MCP return absolute result URLs. CLI/MCP currently support text-to-image only; reference-image (edit) modes need the HTTP API (upload → refs).

## References

- `references/image-gen.md` — full image flow with Python and Node (submit, poll, upload refs, download)
- `references/llm-chat.md` — OpenAI SDK usage, streaming, listing models
