Overview
The Chat Cactus public API lets you talk to any published agent from your own backend, mobile app, or frontend. All endpoints accept and return JSON; streaming endpoints use Server-Sent Events.
Bearer API key
JSON in/out
SSE (text/event-stream)
https://chatcactus.com/api/v1All code samples below are copy-paste ready against the hosted platform. Self-hosted deployments: substitute your own domain — the routes are identical and relative to /api/v1.
Authentication
Every request must include an Authorization: Bearer cc_live_… header. Generate keys in the dashboard under Settings → API Keys. The full secret is shown exactly once at creation — store it in a secret manager and never ship it to a browser unless the request also goes through your own backend.
Authorization: Bearer cc_live_abc123…Keys are workspace-scoped. An agent must be PUBLISHED and belong to the same workspace as the key. Draft agents return 403.
POST /chat
One request, one reply. Use this when you want the whole response in a single JSON blob.
| Field | Type | Required | Description |
|---|---|---|---|
| agentId | string | yes | UUID of a published agent in this workspace. |
| message | string | yes | The user message. Max 8000 chars. |
| conversationId | string | no | Resume a prior session for memory. Omit to start fresh. |
| endUserId | string | no | Your end-user identifier (account id, hashed email, etc.). |
curl -X POST https://chatcactus.com/api/v1/chat \
-H "Authorization: Bearer cc_live_..." \
-H "Content-Type: application/json" \
-d '{
"agentId": "AGENT_UUID",
"message": "Hello!",
"endUserId": "visitor_42"
}'Response
{
"reply": "Hi! How can I help?",
"conversationId": "f7b5…",
"model": "<the agent's configured model, e.g. gpt-4o>",
"provider": "openai",
"mocked": false,
"sources": [
{ "chunk_id": "…", "filename": "pricing.pdf", "score": 0.84 }
],
"usage": { "inputTokens": 312, "outputTokens": 28 }
}POST /chat/stream
Same payload as /chat. The response is a text/event-stream of these events, in order:
curl -N -X POST https://chatcactus.com/api/v1/chat/stream \
-H "Authorization: Bearer cc_live_..." \
-H "Content-Type: application/json" \
-d '{"agentId":"AGENT_UUID","message":"Stream me a haiku."}'Conversation memory
Memory is keyed by conversationId. The first response (in the JSON body for /chat, or in the meta event for /chat/stream) contains the session id. Send it back on every subsequent request to keep the agent's working memory.
- The server loads the last 10 messages of that conversation and prepends them to the LLM call.
- Omit
conversationId(or pass a new one) to start a fresh session. - Pass a stable
endUserIdacross sessions if you want per-visitor analytics in the Logs and Analytics tabs.
Error model
Every error response is JSON with an error field. Validation errors additionally include issues (the Zod flatten() output).
| Status | Code | When |
|---|---|---|
| 400 | Invalid input | Missing fields or message too long. |
| 401 | Missing or invalid API key | Authorization header missing, wrong format, or revoked. |
| 403 | Not authorized / not published | Key→workspace mismatch, or the agent is still DRAFT. |
| 404 | Agent not found | No agent with that id. |
| 502 | AI service unavailable | Upstream model or AI service errored. |
Rate limits
Two layers of limits are enforced:
Per API key: 60 requests per minute (token-bucket window), applied to /chat and /chat/stream. Exceeding it returns 429 with a Retry-After header; every rate-limited response also carries X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset (unix seconds).
Per workspace: your plan's monthly message quota. When it is exhausted, requests return 429 with quota headers until the next calendar month or an upgrade.
Back off on 429 using Retry-After rather than immediately retrying.
OpenAPI spec
A machine-readable OpenAPI 3.1 document lives at /api/v1/openapi. Paste it into Postman, Stoplight, Redoc, or run openapi-generator to scaffold a typed client in any language.
curl https://chatcactus.com/api/v1/openapi > chatcactus.openapi.json