Developer Documentation
API Reference
Everything you need to integrate Corthex into your application. Manage bots, stream AI-powered chat responses, and embed widgets on any website.
Introduction
The Corthex REST API lets you programmatically manage your AI assistants and send chat messages with RAG-powered responses. All API endpoints are served from https://www.corthex.app/api/v1.
API access requires a Pro plan or higher. View plans
Authentication
All API requests require a valid API key passed as a Bearer token in the Authorization header.
Authorization: Bearer ctx_your_api_keyCreating an API key
- Go to Settings → API Keys in your dashboard
- Click "Create API Key" and give it a name
- Copy the key immediately (it is only shown once)
Key format
API keys use the prefix ctx_ followed by 64 hexadecimal characters. Keys are hashed with SHA-256 before storage. Corthex never stores your key in plaintext.
API Endpoints
List Bots
/api/v1/botsReturns all bots belonging to your organization.
Response
{
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Support Bot",
"slug": "support-bot",
"model": "gemini-2.0-flash-exp",
"isActive": true,
"createdAt": "2025-01-15T10:30:00.000Z"
}
]
}Errors
| Status | Description |
|---|---|
| 401 | Invalid or missing API key |
Examples
curl https://www.corthex.app/api/v1/bots \
-H "Authorization: Bearer ctx_your_api_key"const res = await fetch("https://www.corthex.app/api/v1/bots", {
headers: {
Authorization: "Bearer ctx_your_api_key",
},
});
const { data } = await res.json();
console.log(data); // [{ id, name, slug, model, ... }]Get Bot
/api/v1/bots/:botIdReturns details for a single bot. The bot must belong to your organization.
Response
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Support Bot",
"slug": "support-bot",
"model": "gemini-2.0-flash-exp",
"isActive": true,
"welcomeMessage": "Hello! How can I help you?",
"createdAt": "2025-01-15T10:30:00.000Z"
}
}Errors
| Status | Description |
|---|---|
| 401 | Invalid or missing API key |
| 404 | Bot not found or not owned by your organization |
Examples
curl https://www.corthex.app/api/v1/bots/BOT_ID \
-H "Authorization: Bearer ctx_your_api_key"const botId = "550e8400-e29b-41d4-a716-446655440000";
const res = await fetch(`https://www.corthex.app/api/v1/bots/${botId}`, {
headers: {
Authorization: "Bearer ctx_your_api_key",
},
});
const { data } = await res.json();
console.log(data.name); // "Support Bot"Chat
/api/v1/chatSend messages to a bot and receive a streaming AI response grounded in the bot's knowledge base. If no conversationId is provided, a new conversation is created automatically.
Request Body
{
"botId": "550e8400-e29b-41d4-a716-446655440000",
"conversationId": "optional-uuid", // omit to auto-create
"messages": [
{ "role": "user", "content": "What is your refund policy?" }
]
}Response
// Streaming response (text/event-stream)
// Each chunk contains the assistant's response text
// The full response is grounded in the bot's knowledge baseErrors
| Status | Description |
|---|---|
| 400 | Invalid request body (missing fields, wrong types) |
| 401 | Invalid or missing API key |
| 404 | Bot not found or inactive |
| 429 | Rate limit exceeded (60/min) or monthly message limit reached |
| 500 | Internal server error |
Examples
curl -X POST https://www.corthex.app/api/v1/chat \
-H "Authorization: Bearer ctx_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"botId": "BOT_ID",
"messages": [
{ "role": "user", "content": "Hello!" }
]
}'const res = await fetch("https://www.corthex.app/api/v1/chat", {
method: "POST",
headers: {
Authorization: "Bearer ctx_your_api_key",
"Content-Type": "application/json",
},
body: JSON.stringify({
botId: "BOT_ID",
messages: [{ role: "user", content: "Hello!" }],
}),
});
// Read the streaming response
const reader = res.body.getReader();
const decoder = new TextDecoder();
while (true) {
const { done, value } = await reader.read();
if (done) break;
process.stdout.write(decoder.decode(value));
}Message roles
user- Messages from the end userassistant- Previous bot responses (for multi-turn context)system- System instructions (appended to bot's system prompt)
Widget Integration
Embed a chat widget on any website with a single script tag. The widget creates a floating chat button that opens an iframe with your bot's chat interface. No API key required. The widget uses a public endpoint.
<script
src="https://www.corthex.app/widget.js"
data-bot-id="YOUR_BOT_ID"
data-accent-color="#3A82FF"
></script>Attributes
| Attribute | Required | Description |
|---|---|---|
| data-bot-id | Yes | Your bot's UUID (from the dashboard or API) |
| data-accent-color | No | Hex color for the chat button and theme. Defaults to #3A82FF |
Behavior
- Floating button appears at the bottom-right corner of the page
- The iframe is lazy-loaded on first click for optimal performance
- On mobile screens (<480px), the widget opens full-screen
- Each visitor gets their own isolated conversation
- The widget respects the branding configured in your bot settings (display name, icon, accent color, tone)
Full example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>My Website</title>
</head>
<body>
<h1>Welcome to my site</h1>
<!-- Corthex Chat Widget -->
<script
src="https://www.corthex.app/widget.js"
data-bot-id="550e8400-e29b-41d4-a716-446655440000"
data-accent-color="#3A82FF"
></script>
</body>
</html>Rate Limits
Rate limits are enforced per API key using a sliding window algorithm. When a limit is reached, the API returns a 429 status code.
| Endpoint | Limit | Scope |
|---|---|---|
| POST /api/v1/chat | 60 requests / minute | Per API key |
| POST /api/embed/chat | 20 requests / minute | Per IP address |
Monthly message limits
In addition to per-minute rate limits, each organization has a monthly message quota based on their plan. When the quota is reached, the API returns a 429 with a message to upgrade.
| Plan | Messages / month | API access |
|---|---|---|
| Free | 50 | No |
| Pro | 5,000 | Yes |
| Business | 20,000 | Yes |
| Enterprise | 100,000 | Yes |
Error Handling
All error responses follow a consistent JSON format:
{
"error": "Human-readable error message",
"details": [...] // Optional: Zod validation issues for 400 errors
}HTTP status codes
| Code | Meaning | Common cause |
|---|---|---|
| 400 | Bad Request | Missing required fields, invalid UUID format, empty messages array |
| 401 | Unauthorized | Missing Authorization header, invalid API key, revoked key |
| 404 | Not Found | Bot ID doesn't exist, bot belongs to another org, bot is inactive |
| 429 | Too Many Requests | Rate limit exceeded (60/min) or monthly message quota reached |
| 500 | Internal Server Error | Unexpected server error. Retry or contact support |
Quickstart
Get up and running in three steps: create an API key, list your bots, and send a chat message.
1. Create an API key
Go to Settings → API Keys and create a new key. Save it somewhere safe.
2. List your bots
curl https://www.corthex.app/api/v1/bots \
-H "Authorization: Bearer ctx_your_api_key"3. Send a message
curl -X POST https://www.corthex.app/api/v1/chat \
-H "Authorization: Bearer ctx_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"botId": "YOUR_BOT_ID",
"messages": [
{ "role": "user", "content": "What can you help me with?" }
]
}'Full JavaScript example
const API_KEY = "ctx_your_api_key";
const BASE = "https://www.corthex.app/api/v1";
// 1. List bots
const botsRes = await fetch(`${BASE}/bots`, {
headers: { Authorization: `Bearer ${API_KEY}` },
});
const { data: bots } = await botsRes.json();
const botId = bots[0].id;
// 2. Send a chat message (streaming)
const chatRes = await fetch(`${BASE}/chat`, {
method: "POST",
headers: {
Authorization: `Bearer ${API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
botId,
messages: [{ role: "user", content: "Hello!" }],
}),
});
// 3. Read the stream
const reader = chatRes.body.getReader();
const decoder = new TextDecoder();
while (true) {
const { done, value } = await reader.read();
if (done) break;
process.stdout.write(decoder.decode(value));
}Need help integrating? Contact support or visit the pricing page to unlock API access.