Call chat, image/video/audio generation, and account data directly from your own server-side code.
Sign up to get an API key
The XeeChats API is a plain JSON REST API. Every request is authenticated with a
Bearer API key and every response is application/json. There's no SDK required —
any HTTP client works.
Base URL: https://xeechats.com/api/v1
Create an API key from Settings → Developer / API access (requires a Business or Business Pro plan — see Pricing). The full key is shown once, immediately after creation — copy it somewhere safe. Send it on every request as a Bearer token:
Authorization: Bearer xk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Every request is checked against your account's current plan (see Pricing) — the same rules the XeeChats web app itself follows:
403.GET /models tells you upfront which ones you can call.403 before any credits are spent.POST /upload enforces your plan's upload size limit (see GET /credits).GET /credits before large batches, and top up any time on the pricing page.Every response is a JSON object with at least a success boolean. Errors always include a human-readable error string:
{ "success": false, "error": "API access isn't included in your current plan..." }
| Status | Meaning |
|---|---|
200 | Success |
401 | Missing, malformed, or revoked API key |
402 | Insufficient credits |
403 | Not allowed on your current plan (API access, premium model, or generation category), or account suspended |
404 | Conversation/message not found (or not yours) |
405 | Wrong HTTP method for that endpoint |
422 | Invalid or missing request parameters |
500 / 502 | Unexpected server error, or the upstream AI provider failed |
Chat and generation are asynchronous: POST /chat and POST /generate return
immediately with a run_id and an assistant_message_id — poll
GET /status with that message id (every 1.5–3 seconds is plenty) until
status is completed or failed.
Every enabled category (Chat + each generation type) with its models. Each model includes is_premium and allowed (whether your plan can use it right now).
curl https://xeechats.com/api/v1/models \
-H "Authorization: Bearer $XEECHATS_KEY"
{
"success": true,
"categories": [
{
"slug": "llm",
"name": "Chat",
"is_llm": true,
"models": [
{ "node_type": "gpt-4o", "sub_model_id": null, "model": "gpt-4o|",
"name": "GPT-4o", "is_premium": true, "allowed": false }
]
},
{
"slug": "text-to-image",
"name": "Text to Image",
"is_llm": false,
"models": [
{ "node_type": "flux-pro", "sub_model_id": "v1.1", "model": "flux-pro|v1.1",
"name": "Flux Pro", "is_premium": false, "allowed": true }
]
}
]
}
Your current XeeToken balance and the plan limits applied to your account.
curl https://xeechats.com/api/v1/credits \
-H "Authorization: Bearer $XEECHATS_KEY"
{
"success": true,
"credits_balance": 1840,
"plan": {
"name": "Business", "premium_models": "full", "image_generation": "full",
"video_generation": "full", "audio_generation": "full", "file_upload_mb": 1024,
"max_team_members": 10, "commercial_use": true, "support_level": "priority"
}
}
List your conversations (or fetch one by id).
curl https://xeechats.com/api/v1/conversations \
-H "Authorization: Bearer $XEECHATS_KEY"
{ "success": true, "conversations": [
{ "id": 42, "title": "Product names", "node_type": "gpt-4o-mini", "sub_model_id": "",
"model_name": "GPT-4o mini", "updated_at": "2026-07-24 10:03:11" }
] }
Full message history for a conversation you own, oldest first.
curl "https://xeechats.com/api/v1/messages?conversation_id=42" \
-H "Authorization: Bearer $XEECHATS_KEY"
{ "success": true, "conversation_id": 42, "messages": [
{ "id": 101, "role": "user", "content": "Give me 5 product names", "status": "completed", "attachments": null },
{ "id": 102, "role": "assistant", "content": "1. Nova... ", "status": "completed", "attachments": null }
] }
Send a chat message. Omit conversation_id to start a new conversation (requires
model, formatted "nodeType|subModelId" from GET /models);
include it to continue an existing one (in which case model is ignored).
curl -X POST https://xeechats.com/api/v1/chat \
-H "Authorization: Bearer $XEECHATS_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o-mini|",
"message": "Write a haiku about the ocean"
}'
{
"success": true,
"conversation_id": 42,
"user_message_id": 101,
"assistant_message_id": 102,
"run_id": "run_abc123",
"credits_remaining": 1836
}
Body fields: message (string, required unless attaching a file), model, conversation_id, attachments (array of {url, type, name} from POST /upload), options (model-specific settings).
Start an image, video, or audio generation run.
curl -X POST https://xeechats.com/api/v1/generate \
-H "Authorization: Bearer $XEECHATS_KEY" \
-H "Content-Type: application/json" \
-d '{
"category": "text-to-image",
"model": "flux-pro|v1.1",
"prompt": "a lighthouse at sunset, cinematic"
}'
{
"success": true,
"conversation_id": 43,
"user_message_id": 201,
"assistant_message_id": 202,
"run_id": "run_xyz789",
"credits_remaining": 1801
}
Body fields: prompt, category (from GET /models, required for a new conversation), model, conversation_id, files (array of {url, kind} from POST /upload, for image/video/audio-to-X models), options.
Poll a run started by /chat or /generate.
curl "https://xeechats.com/api/v1/status?message_id=102" \
-H "Authorization: Bearer $XEECHATS_KEY"
// while running
{ "success": true, "status": "pending" }
// chat, completed
{ "success": true, "status": "completed", "content": "Waves crash on the shore...",
"attachments": [], "credits_charged": 4 }
// generation, completed
{ "success": true, "status": "completed", "content": "Generated 1 image.",
"attachments": [ { "url": "https://.../output.png", "type": "image" } ], "credits_charged": 18 }
Upload an image/video/audio input file, then pass the returned URL to /chat (attachments) or /generate (files).
curl -X POST https://xeechats.com/api/v1/upload \
-H "Authorization: Bearer $XEECHATS_KEY" \
-F "file=@photo.jpg"
{ "success": true, "url": "https://.../assets/uploads/9/ab12cd34.jpg", "name": "photo", "kind": "image", "mime": "image/jpeg" }
Subject to your plan's File Upload size limit (see GET /credits).
#!/usr/bin/env bash
KEY="xk_live_..."
BASE="https://xeechats.com/api/v1"
# 1. Send the message
RESP=$(curl -s -X POST "$BASE/chat" \
-H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d '{"model":"gpt-4o-mini|","message":"Give me a 5-word tagline for a coffee shop"}')
MSG_ID=$(echo "$RESP" | jq -r '.assistant_message_id')
# 2. Poll until it's done
until [ "$STATUS" = "completed" ] || [ "$STATUS" = "failed" ]; do
sleep 2
POLL=$(curl -s "$BASE/status?message_id=$MSG_ID" -H "Authorization: Bearer $KEY")
STATUS=$(echo "$POLL" | jq -r '.status')
done
echo "$POLL" | jq -r '.content'
#!/usr/bin/env bash
KEY="xk_live_..."
BASE="https://xeechats.com/api/v1"
RESP=$(curl -s -X POST "$BASE/generate" \
-H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d '{"category":"text-to-image","model":"flux-pro|v1.1","prompt":"a cozy reading nook, watercolor"}')
MSG_ID=$(echo "$RESP" | jq -r '.assistant_message_id')
until [ "$STATUS" = "completed" ] || [ "$STATUS" = "failed" ]; do
sleep 2
POLL=$(curl -s "$BASE/status?message_id=$MSG_ID" -H "Authorization: Bearer $KEY")
STATUS=$(echo "$POLL" | jq -r '.status')
done
echo "$POLL" | jq -r '.attachments[0].url'
Questions or found something confusing? Contact support — we're happy to help you integrate.