# Cuadra AI > Build custom AI assistants powered by your documents. Connect data sources, configure behavior with modular prompts, and deploy via REST APIs or React components. Cuadra AI is a multi-provider AI platform that lets you train custom AI models on your proprietary data and deploy them via API, embeddable widgets, messaging channels (SMS, WhatsApp, Telegram, Slack), or team workspaces. Enterprise-ready with SOC 2 Type II, GDPR compliance, TLS 1.3, and AES-256 encryption. - Website: https://cuadra.ai - Dashboard: https://dashboard.cuadra.ai - API Base URL: https://api.cuadra.ai/v1 - Documentation: https://cuadra.ai/docs - OpenAPI Spec: https://api.cuadra.ai/v1/openapi.json - React UI Kit: npm install @cuadra-ai/uikit --- ## What Cuadra AI Does Cuadra AI solves three problems with using generic AI: 1. Generic AI doesn't know YOUR business data — Cuadra lets you upload documents and build knowledge bases for RAG. 2. You're locked into one provider — Cuadra is multi-provider (GPT-4, Claude, Gemini, Mistral, and more). Switch models without code changes. 3. Building from scratch takes months — Cuadra provides production-ready APIs, UI components, and deployment channels out of the box. ### Core Concepts - **Models**: AI assistant configurations that reference a base LLM, linked datasets (for RAG), and a system prompt. - **Datasets**: Collections of uploaded documents (PDF, DOCX, TXT, CSV, JSON, MD). Automatically chunked and embedded for vector search. - **Particles**: Reusable, versioned building blocks for system prompts. Categories include role, tone, guardrails, and output formatting. - **System Prompts**: Compositions of particles that define AI behavior. Version-controlled with audit trail. - **Channels**: Deploy assistants via SMS, WhatsApp, Telegram, Slack. - **Workspace**: Team collaboration environment for using AI assistants. - **Monetize**: Publish AI-powered expert assistants and earn revenue. --- ## Quick Start Deploy your first AI assistant in under 5 minutes. ### Step 1: Create Account Sign up at https://dashboard.cuadra.ai (free, no credit card required). ### Step 2: Create a Model Dashboard → Models → Create Model. Choose a name and select a base LLM from the catalog. ### Step 3: Add Knowledge (Optional) Dashboard → Datasets → Create Dataset → Upload documents (PDF, DOCX, TXT, MD). Link the dataset to your model: Models → Select model → Datasets → Link. ### Step 4: Get Your API Key For backend/scripts: Create M2M credentials in Settings → API Access. For frontend apps: Use JWT session tokens from Stytch B2B auth. ### Step 5: Make Your First Request ```bash curl -X POST https://api.cuadra.ai/v1/chats \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "modelId": "YOUR_MODEL_ID", "messages": [{"role": "user", "content": "Hello!"}] }' ``` ```python import httpx response = httpx.post( "https://api.cuadra.ai/v1/chats", headers={"Authorization": "Bearer YOUR_TOKEN"}, json={ "modelId": "YOUR_MODEL_ID", "messages": [{"role": "user", "content": "Hello!"}] } ) print(response.json()["message"]["content"]) ``` ```typescript const response = await fetch('https://api.cuadra.ai/v1/chats', { method: 'POST', headers: { 'Authorization': 'Bearer YOUR_TOKEN', 'Content-Type': 'application/json' }, body: JSON.stringify({ modelId: 'YOUR_MODEL_ID', messages: [{ role: 'user', content: 'Hello!' }] }) }); const { message } = await response.json(); console.log(message.content); ``` --- ## API Reference ### Base URL ``` https://api.cuadra.ai/v1 ``` ### Authentication All requests require Bearer token authentication. | Method | Use Case | |--------|----------| | JWT Sessions | Frontend apps (from Stytch B2B auth) | | M2M OAuth 2.0 | Backend services (client credentials flow) | M2M token exchange: ```bash curl -X POST "https://auth.cuadra.ai/v1/oauth2/token" \ -H "Content-Type: application/json" \ -d '{ "client_id": "m2m-client-xxx", "client_secret": "secret-xxx", "grant_type": "client_credentials" }' ``` Response: `{ "access_token": "eyJ...", "token_type": "bearer", "expires_in": 3600 }` ### Available Scopes | Scope | Permission | |-------|------------| | chat:invoke | Create chat completions (billable) | | chat:read | Read chat history | | chat:write | Create, update, delete chats | | models:read | List and view models | | models:write | Create, update, delete models | | datasets:read | View datasets | | datasets:write | Create, update, delete datasets | | files:read | View and download files | | files:write | Upload, update, delete files | | particles:read | View particles | | particles:write | Create, update, delete particles | | system-prompts:read | View system prompts | | system-prompts:write | Create, update, delete system prompts | | usage:read | View usage and credit balance | | org:admin | Organization admin access | ### Rate Limits | Scope | Limit | |-------|-------| | Per organization | 300 requests/minute | | Per user | 60 requests/minute | Rate-limited requests return HTTP 429 with a `Retry-After` header. ### Pagination List endpoints use cursor-based pagination: ```json { "data": [...], "nextCursor": "cursor_abc123", "hasMore": true } ``` ### Error Format (RFC 7807) ```json { "type": "about:blank", "title": "Unauthorized", "status": 401, "detail": "Invalid or expired token." } ``` --- ## Endpoints ### Chat | Method | Endpoint | Description | |--------|----------|-------------| | POST | /v1/chats | Create or continue a chat completion | | GET | /v1/chats | List chats for authenticated user | | GET | /v1/chats/{id} | Get a specific chat | | PATCH | /v1/chats/{id} | Update chat metadata | | DELETE | /v1/chats/{id} | Soft delete a chat | #### Create Chat Completion ```json POST /v1/chats { "modelId": "model_abc123", "messages": [{"role": "user", "content": "Hello!"}], "stream": false } ``` Response: ```json { "id": "chat_xyz789", "message": { "role": "assistant", "content": "Hello! How can I help?" }, "usage": { "inputTokens": 15, "outputTokens": 8, "totalTokens": 23 } } ``` #### Streaming Set `stream: true` for Server-Sent Events: ``` data: {"id":"chat_xyz","delta":"Once","finished":false} data: {"id":"chat_xyz","delta":" upon","finished":false} data: {"id":"chat_xyz","delta":"","finished":true,"usage":{...}} data: [DONE] ``` For Vercel AI SDK compatibility, add header: `X-Stream-Format: ai-sdk` #### Structured Outputs (JSON Mode) ```json { "modelId": "model_abc", "messages": [{"role": "user", "content": "Extract: iPhone 15 Pro costs $999"}], "responseFormat": { "type": "json_schema", "json_schema": { "name": "product", "strict": true, "schema": { "type": "object", "properties": { "name": {"type": "string"}, "price": {"type": "number"} }, "required": ["name", "price"] } } } } ``` #### Tool Calling (Function Calling) ```json { "modelId": "model_abc", "messages": [{"role": "user", "content": "Weather in Paris?"}], "tools": [{ "type": "function", "function": { "name": "get_weather", "description": "Get current weather", "parameters": { "type": "object", "properties": {"location": {"type": "string"}}, "required": ["location"] } } }] } ``` #### Reasoning (Extended Thinking) ```json { "modelId": "model_claude", "messages": [...], "enableReasoning": true, "reasoningBudget": 10000 } ``` #### Continue Conversation ```json { "chatId": "chat_xyz789", "messages": [{"role": "user", "content": "Tell me more"}] } ``` ### Models | Method | Endpoint | Description | |--------|----------|-------------| | GET | /v1/models | List models | | POST | /v1/models | Create model | | GET | /v1/models/catalog | List available base models | | GET | /v1/models/{id} | Get model details | | PATCH | /v1/models/{id} | Update model | | DELETE | /v1/models/{id} | Soft-delete model | | GET | /v1/models/{id}/datasets | List model datasets | | POST | /v1/models/{id}/datasets | Associate dataset with model | | DELETE | /v1/models/{id}/datasets/{datasetId} | Dissociate dataset | #### Create Model ```json POST /v1/models { "parentModelId": "PARENT_MODEL_ID_FROM_CATALOG", "displayName": "Support Bot" } ``` #### Associate Dataset for RAG ```json POST /v1/models/{modelId}/datasets { "datasetId": "ds_xyz", "usageType": "rag" } ``` ### Datasets | Method | Endpoint | Description | |--------|----------|-------------| | GET | /v1/datasets | List datasets | | POST | /v1/datasets | Create dataset | | GET | /v1/datasets/{id} | Get dataset (supports expand[]=items, expand[]=snapshots) | | PATCH | /v1/datasets/{id} | Update dataset metadata | | DELETE | /v1/datasets/{id} | Delete dataset | | GET | /v1/datasets/{id}/snapshots | List snapshots | | POST | /v1/datasets/{id}/snapshots | Create snapshot | | DELETE | /v1/datasets/{id}/snapshots/{version} | Delete snapshot | #### Create Dataset ```json POST /v1/datasets { "name": "Product Docs" } ``` ### Files | Method | Endpoint | Description | |--------|----------|-------------| | GET | /v1/files | List files (filter by resourceType, resourceId) | | POST | /v1/files | Upload file (multipart/form-data) | | GET | /v1/files/{id} | Get file metadata | | DELETE | /v1/files/{id} | Delete file | | POST | /v1/files/{id}/associations | Associate file with resource | | POST | /v1/files/{id}/reprocess | Retry failed processing | Supported formats: PDF, DOCX, TXT, CSV, JSON, Markdown. Max 50MB per file. ### Particles | Method | Endpoint | Description | |--------|----------|-------------| | GET | /v1/particles | List particles | | POST | /v1/particles | Create particle | | GET | /v1/particles/{id} | Get particle | | PATCH | /v1/particles/{id} | Update particle (creates new version if content changes) | | DELETE | /v1/particles/{id} | Soft-delete particle | | GET | /v1/particles/{id}/versions | List versions | | GET | /v1/particles/{id}/versions/{version} | Get specific version | #### Create Particle ```json POST /v1/particles { "name": "Support Role", "category": "role", "content": "You are a helpful support agent. Answer questions based on the provided documentation." } ``` ### System Prompts | Method | Endpoint | Description | |--------|----------|-------------| | GET | /v1/system-prompts | List system prompts | | POST | /v1/system-prompts | Create system prompt | | GET | /v1/system-prompts/{id} | Get system prompt | | PATCH | /v1/system-prompts/{id} | Update system prompt metadata | | DELETE | /v1/system-prompts/{id} | Soft-delete system prompt | | POST | /v1/system-prompts/{id}/copy | Copy system prompt | | GET | /v1/system-prompts/{id}/compose | Generate composed prompt text | | POST | /v1/system-prompts/{id}/particles | Add particle to prompt | | DELETE | /v1/system-prompts/{id}/particles/{particleId} | Remove particle | | PATCH | /v1/system-prompts/{id}/particles/{particleId} | Update particle order/pinning | ### Usage | Method | Endpoint | Description | |--------|----------|-------------| | GET | /v1/usage | Get organization usage and billing info | ### Health | Method | Endpoint | Description | |--------|----------|-------------| | GET | /health/live | Liveness check | | GET | /health/ready | Readiness check | | GET | /health/ai-providers | AI provider status | --- ## React UI Kit Install: `npm install @cuadra-ai/uikit` Requires React 18+. Styles are bundled automatically. ### Basic Usage ```tsx import { CuadraChat } from '@cuadra-ai/uikit'; function App() { return (
); } ``` ### Props | Prop Group | Prop | Type | Description | |------------|------|------|-------------| | connection | baseUrl | string | API URL (https://api.cuadra.ai) | | connection | proxyUrl | string | Backend proxy URL (alternative to baseUrl) | | connection | sessionToken | string | JWT session token | | chat | modelId | string | Model ID (required if modelMode='fixed') | | chat | mode | 'singleChat' or 'multiChat' | Chat mode (default: 'multiChat') | | chat | modelMode | 'fixed' or 'selector' | Model selection mode (default: 'fixed') | | chat | systemPrompt | string | Override system prompt | | chat | ephemeral | boolean | Auto-delete chats on close | | chat | enableReasoning | boolean | Show AI thinking process | | chat | enableAttachments | boolean | Enable file uploads | | ui | theme | 'light' or 'dark' or 'system' | Color scheme (default: 'system') | | ui | welcomeTitle | string | Welcome screen heading | | ui | suggestions | {prompt: string}[] | Pre-made prompts | | callbacks | onChatCreated | (id: string) => void | New chat created | | callbacks | onError | (error: Error) => void | Error occurred | ### Proxy Mode (Production) Route requests through your backend to protect tokens: ```tsx ``` ### Widget Mode (No React Required) Embed via script tag in any HTML page: ```html
``` ### External Controls ```tsx import { CuadraChat, CuadraChatProvider, useCuadraChat } from '@cuadra-ai/uikit'; function SendButton() { const { controls, isReady } = useCuadraChat(); return ( ); } function App() { return ( ); } ``` ### Theming Override CSS variables: ```css :root { --cuadra-primary: #6366f1; --cuadra-background: #ffffff; --cuadra-text: #1f2937; } ``` --- ## Knowledge Bases (RAG) ### How RAG Works in Cuadra AI 1. Create a dataset and upload documents. 2. Documents are automatically chunked and converted to vector embeddings. 3. Link the dataset to a model. 4. When you send a chat request, the Chat API automatically searches your documents for relevant content and includes it in the LLM context. 5. The response includes source citations. ### Supported File Formats PDF, DOCX, TXT, CSV, JSON, Markdown. Max 50MB per file. ### Dataset Snapshots Capture the current state of a dataset for: - Rollback to previous knowledge base states - A/B testing different knowledge bases - Compliance and audit requirements --- ## Particles (Modular System Prompts) Particles are reusable, versioned building blocks for system prompts. ### Categories | Category | Purpose | Example | |----------|---------|---------| | role | Define the AI's persona | "You are a customer support agent" | | tone | Set communication style | "Be professional and concise" | | guardrails | Set boundaries | "Never share pricing details" | | output | Format requirements | "Always respond in JSON format" | ### Why Particles? - **Reusable**: Use the same particle across multiple models. - **Versioned**: Every content change creates a new version. Pin specific versions per model. - **Composable**: Combine particles to build complex system prompts. - **Auditable**: Full version history for compliance. --- ## Pricing | Plan | Price | Credits | API Access | Storage | |------|-------|---------|------------|---------| | Free | €0/month | 500/day | No | 1 GB | | Pro | €16.58/seat/month (annual) | 50,000/month | Yes | 50 GB | | Enterprise | €41.58/seat/month (annual) | 75,000/month | Yes | 100 GB | ### Rate Limits by Plan | Plan | Rate Limit | |------|------------| | Free | 30 RPM | | Pro | 300 RPM | | Enterprise | 600 RPM | ### Add-ons - Extra Storage: 10 GB (€5/mo), 50 GB (€20/mo), 100 GB (€35/mo) - Credit Packs: 100K (€10), 500K (€45), 1M (€80) — one-time purchase - Monetize: €99/month or €999/year Free plan: no credit card required. Pro plan: 14-day free trial. --- ## Security & Compliance | Standard | Status | |----------|--------| | SOC 2 Type II | Enterprise plan | | GDPR | Enterprise plan | | TLS 1.3 | All API traffic | | AES-256 | Data at rest | | SSO/SAML | Enterprise plan | | SCIM Provisioning | Enterprise plan | | Audit Logs | Enterprise plan | --- ## Platform Capabilities | Feature | Description | |---------|-------------| | Multi-Provider LLMs | GPT-4, Claude, Gemini, Mistral, and more. Switch without code changes. | | Knowledge Bases | Upload documents for automatic chunking and vector embeddings for RAG. | | System Prompts | Modular "particles" for role, tone, and guardrails. Version-controlled. | | Streaming | Real-time SSE responses. Vercel AI SDK compatible. | | Tool Calling | Define functions the AI can invoke. Supports parallel execution. | | Structured Outputs | Enforce JSON Schema compliance for programmatic responses. | | Extended Thinking | Reasoning tokens with configurable budget. | | Idempotency | Built-in request deduplication via Idempotency-Key header. | | Channels | Deploy via SMS, WhatsApp, Telegram, Slack. | | Monetize | Publish and sell AI-powered expert assistants. | | Workspace | Team collaboration for AI assistants. | --- ## Full Tutorial: Build a Customer Support Chatbot Time: 30 minutes. Prerequisites: Cuadra AI account, Node.js 18+. ### 1. Create a Model ```python import httpx ACCESS_TOKEN = "your-m2m-token" catalog = httpx.get( "https://api.cuadra.ai/v1/models/catalog", headers={"Authorization": f"Bearer {ACCESS_TOKEN}"} ).json() parent_id = catalog["items"][0]["id"] model = httpx.post( "https://api.cuadra.ai/v1/models", headers={"Authorization": f"Bearer {ACCESS_TOKEN}", "Idempotency-Key": "create-model-001"}, json={"parentModelId": parent_id, "displayName": "Support Bot"} ).json() model_id = model["id"] ``` ### 2. Create a Knowledge Base ```python dataset = httpx.post( "https://api.cuadra.ai/v1/datasets", headers={"Authorization": f"Bearer {ACCESS_TOKEN}", "Idempotency-Key": "create-dataset-001"}, json={"name": "Product Docs"} ).json() with open("docs/getting-started.pdf", "rb") as f: file = httpx.post( "https://api.cuadra.ai/v1/files", headers={"Authorization": f"Bearer {ACCESS_TOKEN}", "Idempotency-Key": "upload-doc-001"}, files={"file": f} ).json() httpx.post( f"https://api.cuadra.ai/v1/files/{file['id']}/associations", headers={"Authorization": f"Bearer {ACCESS_TOKEN}"}, json={"datasetId": dataset["id"]} ) ``` ### 3. Link Dataset to Model ```python httpx.post( f"https://api.cuadra.ai/v1/models/{model_id}/datasets", headers={"Authorization": f"Bearer {ACCESS_TOKEN}", "Idempotency-Key": "link-dataset-001"}, json={"datasetId": dataset["id"], "usageType": "rag"} ) ``` ### 4. Configure System Prompt ```python particle = httpx.post( "https://api.cuadra.ai/v1/particles", headers={"Authorization": f"Bearer {ACCESS_TOKEN}", "Idempotency-Key": "create-particle-001"}, json={ "name": "Support Role", "category": "role", "content": "You are a helpful support agent. Answer from documentation. If unsure, suggest contacting support." } ).json() system_prompt = httpx.post( "https://api.cuadra.ai/v1/system-prompts", headers={"Authorization": f"Bearer {ACCESS_TOKEN}", "Idempotency-Key": "create-sysprompt-001"}, json={"name": "Support Prompt", "particles": [{"particleId": particle["id"], "order": 1}]} ).json() httpx.patch( f"https://api.cuadra.ai/v1/models/{model_id}", headers={"Authorization": f"Bearer {ACCESS_TOKEN}"}, json={"systemPromptId": system_prompt["id"]} ) ``` ### 5. Test ```python result = httpx.post( "https://api.cuadra.ai/v1/chats", headers={"Authorization": f"Bearer {ACCESS_TOKEN}", "Idempotency-Key": "test-chat-001"}, json={"modelId": model_id, "messages": [{"role": "user", "content": "How do I get started?"}]} ).json() print(result["message"]["content"]) if result.get("sources"): for source in result["sources"]: print(f" Source: {source['filename']} (score: {source['score']:.2f})") ``` ### 6. Deploy React UI ```tsx import { CuadraChat } from '@cuadra-ai/uikit'; export function SupportChat({ sessionToken }: { sessionToken: string }) { return ( ); } ``` --- ## FAQ ### What is Cuadra AI? Cuadra AI is a platform for building custom AI assistants powered by your documents. Upload files, build knowledge bases, and deploy chatbots via REST API, React components, or messaging channels. ### How does RAG work in Cuadra AI? When you link a dataset to a model, the Chat API automatically searches your documents for relevant content and includes it in the LLM context. The response includes source citations. ### Which LLM providers are supported? Cuadra AI supports multiple leading AI providers including OpenAI, Anthropic, Google, and Mistral. Browse available models via `GET /v1/models/catalog`. Switch providers without code changes. ### Is Cuadra AI enterprise-ready? Yes. SOC 2 Type II certification available on Enterprise plan. All plans include GDPR compliance, TLS 1.3 encryption, and AES-256 data-at-rest encryption. ### What file formats are supported? PDF, DOCX, TXT, CSV, JSON, and Markdown. Max 50MB per file. ### How does authentication work? Two methods: JWT session tokens for frontend apps (via Stytch B2B), and M2M OAuth 2.0 client credentials for backend services. Both use Bearer token in the Authorization header. ### Is there an OpenAPI spec? Yes. Download at https://api.cuadra.ai/v1/openapi.json (OpenAPI 3.1). ### What's the latency? Typical first-token latency is 200-500ms. Use `stream: true` for real-time SSE responses. ### Can I use this with Vercel AI SDK? Yes. Add the `X-Stream-Format: ai-sdk` header to get Vercel AI SDK compatible streaming events. --- ## Documentation Pages - Quick Start: https://cuadra.ai/docs/quickstart - API Overview: https://cuadra.ai/docs/api-reference/overview - Authentication: https://cuadra.ai/docs/api-reference/authentication - Chat API: https://cuadra.ai/docs/api-reference/chat - Models API: https://cuadra.ai/docs/api-reference/models - Datasets API: https://cuadra.ai/docs/api-reference/datasets - Files API: https://cuadra.ai/docs/api-reference/files - Particles API: https://cuadra.ai/docs/api-reference/particles - System Prompts API: https://cuadra.ai/docs/api-reference/system-prompts - Usage API: https://cuadra.ai/docs/api-reference/usage - Errors: https://cuadra.ai/docs/api-reference/errors - OpenAPI Spec: https://cuadra.ai/docs/api-reference/openapi - Knowledge Bases Guide: https://cuadra.ai/docs/guides/knowledge-bases - System Prompts Guide: https://cuadra.ai/docs/guides/system-prompts - Particles Guide: https://cuadra.ai/docs/guides/particles - React UI Kit: https://cuadra.ai/docs/guides/uikit-react - Widget Embed: https://cuadra.ai/docs/guides/uikit-widget - Build a Chatbot Tutorial: https://cuadra.ai/docs/guides/tutorial-chatbot - Credits & Billing: https://cuadra.ai/docs/billing/credits