# 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 (