Overview
BundleAI exposes a fully OpenAI-compatible REST API so you can use any existing OpenAI SDK, library, or integration with zero code changes. Just update the base URL and your API key.
All endpoints return JSON. Dates are ISO 8601 strings. Token counts follow the same tiktoken-compatible rules as OpenAI.
Supported Capabilities
- Chat Completions — streaming and non-streaming
- Model listing
- AI Skills (curated system prompt presets)
- Tool use — web search, calculator, weather, URL fetch, summarizer
- RAG document upload and retrieval
- User API key management
- Token balance tracking
/v1/chat/completions endpoint is fully compatible with the openai Python/Node library. BundleAI-specific parameters (skill, use_tools) are optional extensions.
Authentication
BundleAI supports two authentication methods depending on your use case.
Method 1 — API Key (Recommended for code)
Create an API key from your account dashboard. Keys are prefixed with bai_ and carry full chat access. Pass the key as a Bearer token in the Authorization header.
Authorization: Bearer bai_xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Method 2 — JWT Cookie (Web UI)
When you log in through the BundleAI web interface, a JWT cookie (token) is automatically set. All browser-based API calls include this cookie automatically. No action needed for web users.
# Using an API key
curl https://bundleai.cloud/v1/models \
-H "Authorization: Bearer bai_your_api_key_here"
Chat Completions
The primary endpoint. Compatible with the OpenAI Chat Completions API. Supports streaming via server-sent events.
Request Body
| Parameter | Type | Description |
|---|---|---|
| model required | string | Model identifier, e.g. deepseek-r1:14b. Use GET /v1/models to list available models. |
| messages required | array | Array of message objects. Each object has role (system, user, assistant) and content (string). |
| stream optional | boolean | If true, stream the response as server-sent events. Default: false. |
| temperature optional | number | Sampling temperature 0.0–2.0. Default: 0.7. Higher = more creative. |
| max_tokens optional | integer | Maximum number of tokens in the response. Default: model maximum. |
| skill optional | string | BundleAI skill preset. One of: general, researcher, coder, writer, data-analyst, web-analyst. Default: general. |
| use_tools optional | boolean | If true, the AI may invoke built-in tools (web search, calculator, etc.) to answer the query. Default: false. |
Examples
curl https://bundleai.cloud/v1/chat/completions \
-H "Authorization: Bearer bai_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek-r1:14b",
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Explain quantum entanglement simply."}
],
"stream": false,
"skill": "researcher",
"use_tools": true
}'
from openai import OpenAI
client = OpenAI(
base_url="https://bundleai.cloud/v1",
api_key="bai_your_key_here",
)
response = client.chat.completions.create(
model="deepseek-r1:14b",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Explain quantum entanglement simply."},
],
extra_body={
"skill": "researcher",
"use_tools": True,
},
)
print(response.choices[0].message.content)
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://bundleai.cloud/v1",
apiKey: "bai_your_key_here",
});
const response = await client.chat.completions.create({
model: "deepseek-r1:14b",
messages: [
{ role: "system", content: "You are a helpful assistant." },
{ role: "user", content: "Explain quantum entanglement simply." },
],
});
console.log(response.choices[0].message.content);
Response
{
"id": "chatcmpl-abc123",
"object": "chat.completion",
"created": 1712345678,
"model": "deepseek-r1:14b",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Quantum entanglement is a phenomenon where..."
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 28,
"completion_tokens": 214,
"total_tokens": 242
}
}
Models
List all AI models currently available on the platform.
curl https://bundleai.cloud/v1/models \
-H "Authorization: Bearer bai_your_key_here"
{
"object": "list",
"data": [
{
"id": "deepseek-r1:14b",
"object": "model",
"created": 1712000000,
"owned_by": "bundleai"
}
]
}
The available model list is configured by the server administrator and may include additional Ollama-compatible models. Always check this endpoint at runtime rather than hardcoding model names.
Skills
Skills are curated system prompt configurations optimized for specific tasks. Passing a skill parameter in a chat request activates the corresponding preset.
curl https://bundleai.cloud/skills \
-H "Authorization: Bearer bai_your_key_here"
{
"skills": [
{ "id": "general", "name": "General Assistant", "description": "Balanced everyday assistant" },
{ "id": "researcher", "name": "Researcher", "description": "Deep research and analysis" },
{ "id": "coder", "name": "Coder", "description": "Code generation and debugging" },
{ "id": "writer", "name": "Writer", "description": "Professional writing and editing" },
{ "id": "data-analyst", "name": "Data Analyst", "description": "Data interpretation and stats" },
{ "id": "web-analyst", "name": "Web Analyst", "description": "Web research and competitive analysis" }
]
}
User API Keys
Manage API keys for your account. Keys have read/write permissions scoped to your own user and token balance.
Create API Key
curl -X POST https://bundleai.cloud/user/apikeys \
-H "Authorization: Bearer bai_your_key" \
-H "Content-Type: application/json" \
-d '{"label": "My App"}'
{
"id": 42,
"key": "bai_newlygeneratedkeyvalue",
"label": "My App",
"created_at": "2026-04-09T12:00:00Z"
}
List API Keys
curl https://bundleai.cloud/user/apikeys \
-H "Authorization: Bearer bai_your_key"
Revoke API Key
curl -X DELETE https://bundleai.cloud/user/apikeys/42 \
-H "Authorization: Bearer bai_your_key"
Token Balance
Retrieve the current token balance and account info for the authenticated user.
curl https://bundleai.cloud/auth/me \
-H "Authorization: Bearer bai_your_key_here"
{
"id": 7,
"email": "user@example.com",
"first_name": "Alice",
"last_name": "Smith",
"role": "user",
"token_balance": 2847500,
"created_at": "2026-01-15T09:30:00Z"
}
Rate Limits
To ensure platform stability, API requests are rate-limited per authenticated user.
| Header | Value | Description |
|---|---|---|
| X-RateLimit-Limit | 60 | Maximum requests allowed in the window. |
| X-RateLimit-Remaining | integer | Requests remaining in the current window. |
| X-RateLimit-Window | 60s | Duration of the rate limit window (60 seconds). |
| Retry-After | integer | Seconds to wait before retrying (only present when rate limited). |
When you exceed the rate limit, the API returns a 429 Too Many Requests response. Implement exponential backoff in production applications.
Errors
BundleAI uses standard HTTP status codes and a consistent error response body.
{
"error": {
"message": "Insufficient token balance to complete this request.",
"type": "insufficient_tokens",
"code": 402
}
}
| Status | error.type | Description |
|---|---|---|
| 400 | invalid_request | Missing or malformed request parameters. |
| 401 | unauthorized | Missing or invalid API key / JWT cookie. |
| 402 | insufficient_tokens | Token balance too low to complete the request. |
| 404 | not_found | The requested resource does not exist. |
| 429 | rate_limit_exceeded | Too many requests. See Retry-After header. |
| 500 | server_error | An unexpected internal error occurred. |
Python SDK Example
A complete working Python script using the official openai library with BundleAI as the backend.
"""
BundleAI — Python SDK Example
Requires: pip install openai
"""
import os
from openai import OpenAI
# Initialize the client pointing to BundleAI
client = OpenAI(
base_url="https://bundleai.cloud/v1",
api_key=os.environ["BUNDLEAI_API_KEY"], # bai_xxxx
)
# ── Non-streaming request ──────────────────────────────────────────
response = client.chat.completions.create(
model="deepseek-r1:14b",
messages=[
{"role": "system", "content": "You are a senior Python developer."},
{"role": "user", "content": "Write a binary search function with type hints."},
],
temperature=0.3,
extra_body={"skill": "coder"},
)
print("Assistant:", response.choices[0].message.content)
print("Tokens used:", response.usage.total_tokens)
# ── Streaming request ──────────────────────────────────────────────
print("\n--- Streaming ---")
stream = client.chat.completions.create(
model="deepseek-r1:14b",
messages=[{"role": "user", "content": "What is 42 * 1337?"}],
stream=True,
extra_body={"use_tools": True},
)
for chunk in stream:
delta = chunk.choices[0].delta.content or ""
print(delta, end="", flush=True)
print() # newline after stream
JavaScript / Node.js Example
A complete working Node.js script using the official openai npm package.
/**
* BundleAI — Node.js SDK Example
* Install: npm install openai
*/
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://bundleai.cloud/v1",
apiKey: process.env.BUNDLEAI_API_KEY, // bai_xxxx
});
// ── Non-streaming ─────────────────────────────────────────────────
async function askQuestion(question) {
const response = await client.chat.completions.create({
model: "deepseek-r1:14b",
messages: [
{ role: "system", content: "You are a helpful research assistant." },
{ role: "user", content: question },
],
// BundleAI extensions
"skill": "researcher",
"use_tools": true,
});
return response.choices[0].message.content;
}
// ── Streaming ────────────────────────────────────────────────────
async function streamAnswer(prompt) {
const stream = await client.chat.completions.create({
model: "deepseek-r1:14b",
stream: true,
messages: [{ role: "user", content: prompt }],
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
}
console.log();
}
// Run examples
askQuestion("What are the latest advances in fusion energy?")
.then(answer => console.log("Answer:", answer))
.catch(console.error);
streamAnswer("Write a haiku about the ocean.")
.catch(console.error);