API Documentation

Complete API reference for the RAG-as-a-Service platform. Build powerful AI-driven applications with our REST API.

Base URL:https://api.yourdomain.com/api/v1

Quick Start

Get started with the RAG API in three simple steps:

1

Register & Login

Create an account and get your access token

2

Upload Documents

Upload your documents to build your knowledge base

3

Query with AI

Start asking questions and get intelligent answers

Authentication

All API requests require authentication using JWT (JSON Web Tokens). Include your access token in the Authorization header.

Register a New User

Create a new account and receive access tokens.

POST/auth/register
Request Body
{
  "email": "[email protected]",
  "username": "johndoe",
  "password": "SecurePassword123!",
  "workspace_name": "My Workspace"
}
Response (200 OK)
{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "bearer"
}

Login

Authenticate with email and password to receive access tokens.

POST/auth/login
Request Body
{
  "email": "[email protected]",
  "password": "SecurePassword123!"
}
Response (200 OK)
{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "bearer"
}

Refresh Access Token

Get a new access token using your refresh token when it expires.

POST/auth/refresh
Request Body
{
  "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

Get Current User Info

Retrieve information about the authenticated user.

GET/auth/me
Response (200 OK)
{
  "id": 123,
  "email": "[email protected]",
  "username": "johndoe",
  "role": "user",
  "workspace_id": 456,
  "is_active": true,
  "created_at": "2024-01-01T12:00:00Z"
}

Using Access Tokens

Include the access token in the Authorization header for all authenticated requests:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Access tokens expire after 30 minutes

Refresh tokens expire after 7 days

Use refresh endpoint to get new access tokens without re-authenticating

Documents API

Upload, manage, and query your documents. Supported formats: PDF, DOCX, TXT, MD, HTML, XLSX, PPTX.

Upload Document

Upload a document to your workspace for processing and indexing.

POST/documents/upload
Content-Type: multipart/form-data
cURL Example
curl -X POST https://api.yourdomain.com/api/v1/documents/upload \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -F "file=@/path/to/document.pdf"
Response (200 OK)
{
  "id": 789,
  "filename": "document.pdf",
  "content_type": "application/pdf",
  "size": 1048576,
  "status": "processing",
  "chunk_count": 0,
  "created_at": "2024-01-01T12:00:00Z",
  "updated_at": "2024-01-01T12:00:00Z"
}
Upload Limits
  • Maximum file size: 100 MB
  • Rate limit: 10 uploads per minute per user
  • Document status changes to ready when processing completes

List Documents

Get all documents in your workspace.

GET/documents
Response (200 OK)
{
  "documents": [
    {
      "id": 789,
      "filename": "document.pdf",
      "content_type": "application/pdf",
      "size": 1048576,
      "status": "ready",
      "chunk_count": 42,
      "created_at": "2024-01-01T12:00:00Z",
      "updated_at": "2024-01-01T12:05:00Z"
    }
  ],
  "total": 1
}

Get Document Details

Retrieve details about a specific document.

GET/documents/{document_id}
cURL Example
curl -X GET https://api.yourdomain.com/api/v1/documents/789 \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Get Document Chunks

View how a document was chunked for processing.

GET/documents/{document_id}/chunks
Response (200 OK)
{
  "document_id": 789,
  "chunk_count": 42,
  "chunks": [
    {
      "id": 1,
      "content": "This is the first chunk of the document...",
      "metadata": {
        "page": 1,
        "section": "Introduction"
      }
    }
  ]
}

Delete Document

Permanently delete a document and all its chunks.

DELETE/documents/{document_id}
cURL Example
curl -X DELETE https://api.yourdomain.com/api/v1/documents/789 \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Response (200 OK)
{
  "success": true,
  "message": "Document 789 deleted successfully"
}

Chat API

Query your documents using natural language and receive AI-powered responses with source citations.

Send Chat Message

Send a message and get an AI response based on your documents or products.

POST/chat
Request Body
{
  "message": "What are the main features of the product?",
  "session_id": "optional-session-id",
  "mode": "documents"
}

Parameters

  • message (required): Your question or message (1-4000 characters)
  • session_id (optional): Conversation ID to maintain context
  • mode (optional): Search mode - documents, products, or null for workspace default
Response (200 OK)
{
  "session_id": "abc123-def456-ghi789",
  "response": "The main features include advanced AI processing, multi-format support, and real-time collaboration.",
  "sources": [
    {
      "document_id": 789,
      "filename": "product-specs.pdf",
      "content": "Advanced AI processing capabilities...",
      "score": 0.92,
      "metadata": {
        "page": 3,
        "chunk_id": 15
      }
    }
  ]
}

List Conversations

Get all conversations in your workspace with pagination.

GET/chat/conversations?limit=20&offset=0
Response (200 OK)
{
  "conversations": [
    {
      "id": 1,
      "session_id": "abc123-def456-ghi789",
      "title": "Product Features Discussion",
      "message_count": 12,
      "created_at": "2024-01-01T12:00:00Z",
      "updated_at": "2024-01-01T12:30:00Z"
    }
  ],
  "total": 1
}

Get Conversation History

Retrieve all messages in a specific conversation.

GET/chat/conversations/{session_id}
Response (200 OK)
{
  "id": "1",
  "session_id": "abc123-def456-ghi789",
  "title": "Product Features Discussion",
  "messages": [
    {
      "role": "user",
      "content": "What are the main features?",
      "metadata": {},
      "timestamp": "2024-01-01T12:00:00Z"
    },
    {
      "role": "assistant",
      "content": "The main features include...",
      "metadata": {
        "sources": [...]
      },
      "timestamp": "2024-01-01T12:00:05Z"
    }
  ],
  "created_at": "2024-01-01T12:00:00Z",
  "updated_at": "2024-01-01T12:30:00Z"
}

Delete Conversation

Archive a conversation (soft delete).

DELETE/chat/conversations/{session_id}

Rename Conversation

Update the title of a conversation.

PATCH/chat/conversations/{session_id}
Request Body
{
  "title": "New Conversation Title"
}

Export Conversation

Export a conversation in JSON or Markdown format.

GET/chat/conversations/{session_id}/export?format=json

Query Parameters

  • format: json or markdown (default: json)

Products API

Sync and query your e-commerce products. Supports Shopify, WooCommerce, and custom integrations.

Sync Products

Trigger product synchronization from your connected source.

POST/products/sync
Request Body
{
  "product_source_id": 123,
  "source_type": "shopify",
  "limit": 100,
  "background": true
}

Parameters

  • product_source_id (required): ID of the product source to sync
  • source_type: Type of source (shopify, woocommerce, faker)
  • limit: Maximum number of products to sync
  • background: Run sync in background (default: true)
Response (200 OK)
{
  "status": "accepted",
  "product_source_id": 123,
  "message": "Sync started in background. Check product_source status for completion."
}

List Product Sources

Get all product sources connected to your workspace.

GET/products/sources
Response (200 OK)
{
  "sources": [
    {
      "id": 123,
      "name": "Shopify Store",
      "source_type": "shopify",
      "status": "active",
      "product_count": 500,
      "last_sync_at": "2024-01-01T12:00:00Z",
      "last_error": null,
      "error_count": 0,
      "has_mapping": true
    }
  ],
  "total": 1
}

Get Product Source Status

Check the sync status of a product source.

GET/products/sources/{product_source_id}/status

List Products

Get all products with filtering and search capabilities.

GET/products?limit=20&offset=0

Query Parameters

  • limit: Number of products to return (max 100, default 20)
  • offset: Number of products to skip (default 0)
  • category: Filter by category
  • in_stock: Filter by stock status (true/false)
  • product_source_id: Filter by source ID
  • search: Search in product name and description
Response (200 OK)
{
  "products": [
    {
      "id": 1,
      "external_id": "shopify-123",
      "name": "Premium Widget",
      "description": "High-quality widget for all your needs",
      "price": 29.99,
      "currency": "USD",
      "category": "Electronics",
      "sku": "WIDGET-001",
      "image_url": "https://example.com/widget.jpg",
      "product_url": "https://store.example.com/products/widget",
      "in_stock": true,
      "tags": ["premium", "electronics"],
      "last_synced_at": "2024-01-01T12:00:00Z"
    }
  ],
  "total": 500,
  "limit": 20,
  "offset": 0
}

Product Schema

Standard product object structure.

Product Object
{
  "id": 1,
  "external_id": "shopify-123",
  "name": "Product Name",
  "description": "Product description",
  "price": 29.99,
  "currency": "USD",
  "category": "Category Name",
  "sku": "SKU-001",
  "image_url": "https://example.com/image.jpg",
  "product_url": "https://store.example.com/product",
  "in_stock": true,
  "tags": ["tag1", "tag2"],
  "last_synced_at": "2024-01-01T12:00:00Z"
}

Rate Limits

API rate limits help ensure fair usage and system stability. Limits vary by endpoint and plan.

Authentication Endpoints

POST /auth/register

5 requests per minute per IP

POST /auth/login

10 requests per minute per IP

POST /auth/refresh

20 requests per minute per user

Document Endpoints

POST /documents/upload

10 requests per minute per user

GET /documents

60 requests per minute per user

DELETE /documents/{id}

30 requests per minute per user

Chat Endpoints

POST /chat

Monthly credits by plan: Free: 100 (10/day), Starter: 4,000, Premium: 50,000, Enterprise: Custom

Product Endpoints

POST /products/sync

5 requests per hour per workspace

GET /products

60 requests per minute per user

Rate Limit Headers

Every API response includes headers showing your current rate limit status:

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1704110400

Error Codes

The API uses standard HTTP status codes and returns detailed error messages in JSON format with correlation IDs for debugging.

Error Response Format

All errors follow this structured format:

{
  "error_code": "VALIDATION_ERROR",
  "message": "Invalid request data",
  "correlation_id": "abc123-def456",
  "is_retryable": false,
  "http_status": 422,
  "path": "/api/v1/auth/register",
  "validation_errors": [
    {
      "field": "password",
      "error": "Password must contain at least one digit",
      "type": "value_error"
    }
  ]
}
400

Bad Request

Invalid request parameters or malformed JSON.

{
  "error_code": "VALIDATION_ERROR",
  "message": "Email addresses with '+' are not allowed",
  "correlation_id": "abc123",
  "http_status": 400
}
401

Unauthorized

Missing or invalid authentication token.

{
  "error_code": "AUTH_FAILED",
  "message": "Invalid credentials",
  "correlation_id": "abc123",
  "http_status": 401
}
403

Forbidden

You don't have permission to access this resource.

{
  "error_code": "FORBIDDEN",
  "message": "You don't have permission to delete this document",
  "correlation_id": "abc123",
  "http_status": 403
}
404

Not Found

The requested resource doesn't exist.

{
  "error_code": "NOT_FOUND",
  "message": "Document not found",
  "correlation_id": "abc123",
  "http_status": 404
}
422

Validation Error

Request validation failed. Check the validation_errors array for details.

{
  "error_code": "VALIDATION_ERROR",
  "message": "Invalid request data. Please check the errors below.",
  "correlation_id": "abc123",
  "http_status": 422,
  "validation_errors": [
    {
      "field": "password",
      "error": "Field 'password' is too short. Minimum required: 8 characters.",
      "type": "string_too_short"
    },
    {
      "field": "username",
      "error": "Username must contain only letters, numbers, underscore and hyphen",
      "type": "value_error"
    }
  ]
}
429

Too Many Requests

Rate limit exceeded. Check Retry-After header.

{
  "error_code": "RATE_LIMIT_EXCEEDED",
  "message": "Rate limit exceeded: 5 per 1 minute",
  "correlation_id": "abc123",
  "is_retryable": true,
  "http_status": 429
}

// Response Headers:
// Retry-After: 60
// X-RateLimit-Limit: 5
// X-RateLimit-Remaining: 0
// X-RateLimit-Reset: 1704110400
500

Internal Server Error

An unexpected error occurred. Use the correlation_id for support.

{
  "error_code": "INTERNAL_ERROR",
  "message": "An unexpected error occurred",
  "correlation_id": "abc123-def456-ghi789",
  "is_retryable": false,
  "http_status": 500
}
503

Service Unavailable

External service (LLM, storage) temporarily unavailable. Retryable.

{
  "error_code": "SERVICE_UNAVAILABLE",
  "message": "LLM service temporarily unavailable",
  "correlation_id": "abc123",
  "is_retryable": true,
  "http_status": 503
}

Error Codes Reference

VALIDATION_ERRORInput validation failed
AUTH_FAILEDAuthentication failed
FORBIDDENPermission denied
NOT_FOUNDResource not found
RATE_LIMIT_EXCEEDEDToo many requests
CREDITS_EXHAUSTEDNo credits remaining
DAILY_LIMIT_REACHEDDaily usage limit reached (Free tier)
STORAGE_ERRORFile storage operation failed
LLM_ERRORAI model error
SERVICE_UNAVAILABLEExternal service down

Code Examples

Complete examples in popular programming languages to help you get started quickly.

cURL

Complete Workflow Example
# 1. Register a new user
curl -X POST https://api.yourdomain.com/api/v1/auth/register \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "username": "johndoe",
    "password": "SecurePassword123!",
    "workspace_name": "My Workspace"
  }'

# Save the access_token from the response
TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

# 2. Upload a document
curl -X POST https://api.yourdomain.com/api/v1/documents/upload \
  -H "Authorization: Bearer $TOKEN" \
  -F "file=@/path/to/document.pdf"

# 3. Send a chat message
curl -X POST https://api.yourdomain.com/api/v1/chat \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "message": "What are the key points in the document?",
    "mode": "documents"
  }'

JavaScript / TypeScript

Complete SDK Example
// RAG API Client
class RAGClient {
  private baseUrl = 'https://api.yourdomain.com/api/v1';
  private accessToken: string | null = null;

  // Register and login
  async register(email: string, username: string, password: string, workspaceName: string) {
    const response = await fetch(`${this.baseUrl}/auth/register`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ email, username, password, workspace_name: workspaceName })
    });

    if (!response.ok) throw new Error('Registration failed');

    const data = await response.json();
    this.accessToken = data.access_token;
    return data;
  }

  async login(email: string, password: string) {
    const response = await fetch(`${this.baseUrl}/auth/login`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ email, password })
    });

    if (!response.ok) throw new Error('Login failed');

    const data = await response.json();
    this.accessToken = data.access_token;
    return data;
  }

  // Upload document
  async uploadDocument(file: File) {
    const formData = new FormData();
    formData.append('file', file);

    const response = await fetch(`${this.baseUrl}/documents/upload`, {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${this.accessToken}`
      },
      body: formData
    });

    if (!response.ok) throw new Error('Upload failed');
    return response.json();
  }

  // List documents
  async listDocuments() {
    const response = await fetch(`${this.baseUrl}/documents`, {
      headers: {
        'Authorization': `Bearer ${this.accessToken}`
      }
    });

    if (!response.ok) throw new Error('Failed to fetch documents');
    return response.json();
  }

  // Send chat message
  async chat(message: string, sessionId?: string, mode?: 'documents' | 'products') {
    const response = await fetch(`${this.baseUrl}/chat`, {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${this.accessToken}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ message, session_id: sessionId, mode })
    });

    if (!response.ok) throw new Error('Chat request failed');
    return response.json();
  }

  // List products
  async listProducts(params?: {
    limit?: number;
    offset?: number;
    category?: string;
    search?: string;
  }) {
    const queryParams = new URLSearchParams();
    if (params?.limit) queryParams.set('limit', params.limit.toString());
    if (params?.offset) queryParams.set('offset', params.offset.toString());
    if (params?.category) queryParams.set('category', params.category);
    if (params?.search) queryParams.set('search', params.search);

    const response = await fetch(
      `${this.baseUrl}/products?${queryParams}`,
      {
        headers: {
          'Authorization': `Bearer ${this.accessToken}`
        }
      }
    );

    if (!response.ok) throw new Error('Failed to fetch products');
    return response.json();
  }
}

// Usage
const client = new RAGClient();

// Login
await client.login('[email protected]', 'password');

// Upload a document
const fileInput = document.querySelector('input[type="file"]');
const file = fileInput.files[0];
const document = await client.uploadDocument(file);

// Chat with documents
const response = await client.chat(
  'What are the main features?',
  undefined,
  'documents'
);
console.log(response.response);
console.log(response.sources);

Python

Complete SDK Example
import requests
from typing import Optional, Dict, Any, List

class RAGClient:
    def __init__(self, base_url: str = "https://api.yourdomain.com/api/v1"):
        self.base_url = base_url
        self.access_token: Optional[str] = None
        self.refresh_token: Optional[str] = None

    def register(self, email: str, username: str, password: str, workspace_name: str) -> Dict[str, Any]:
        """Register a new user"""
        response = requests.post(
            f"{self.base_url}/auth/register",
            json={
                "email": email,
                "username": username,
                "password": password,
                "workspace_name": workspace_name
            }
        )
        response.raise_for_status()
        data = response.json()
        self.access_token = data["access_token"]
        self.refresh_token = data["refresh_token"]
        return data

    def login(self, email: str, password: str) -> Dict[str, Any]:
        """Login with email and password"""
        response = requests.post(
            f"{self.base_url}/auth/login",
            json={"email": email, "password": password}
        )
        response.raise_for_status()
        data = response.json()
        self.access_token = data["access_token"]
        self.refresh_token = data["refresh_token"]
        return data

    def _get_headers(self) -> Dict[str, str]:
        """Get authorization headers"""
        if not self.access_token:
            raise ValueError("Not authenticated. Call login() first.")
        return {"Authorization": f"Bearer {self.access_token}"}

    def upload_document(self, file_path: str) -> Dict[str, Any]:
        """Upload a document"""
        with open(file_path, 'rb') as f:
            files = {'file': f}
            response = requests.post(
                f"{self.base_url}/documents/upload",
                headers=self._get_headers(),
                files=files
            )
        response.raise_for_status()
        return response.json()

    def list_documents(self) -> Dict[str, Any]:
        """List all documents"""
        response = requests.get(
            f"{self.base_url}/documents",
            headers=self._get_headers()
        )
        response.raise_for_status()
        return response.json()

    def delete_document(self, document_id: int) -> Dict[str, Any]:
        """Delete a document"""
        response = requests.delete(
            f"{self.base_url}/documents/{document_id}",
            headers=self._get_headers()
        )
        response.raise_for_status()
        return response.json()

    def chat(
        self,
        message: str,
        session_id: Optional[str] = None,
        mode: Optional[str] = None
    ) -> Dict[str, Any]:
        """Send a chat message"""
        payload = {"message": message}
        if session_id:
            payload["session_id"] = session_id
        if mode:
            payload["mode"] = mode

        response = requests.post(
            f"{self.base_url}/chat",
            headers=self._get_headers(),
            json=payload
        )
        response.raise_for_status()
        return response.json()

    def list_conversations(
        self,
        limit: int = 20,
        offset: int = 0,
        include_archived: bool = False
    ) -> Dict[str, Any]:
        """List conversations"""
        params = {
            "limit": limit,
            "offset": offset,
            "include_archived": include_archived
        }
        response = requests.get(
            f"{self.base_url}/chat/conversations",
            headers=self._get_headers(),
            params=params
        )
        response.raise_for_status()
        return response.json()

    def list_products(
        self,
        limit: int = 20,
        offset: int = 0,
        category: Optional[str] = None,
        search: Optional[str] = None
    ) -> Dict[str, Any]:
        """List products"""
        params = {"limit": limit, "offset": offset}
        if category:
            params["category"] = category
        if search:
            params["search"] = search

        response = requests.get(
            f"{self.base_url}/products",
            headers=self._get_headers(),
            params=params
        )
        response.raise_for_status()
        return response.json()

    def sync_products(
        self,
        product_source_id: int,
        source_type: str = "faker",
        limit: Optional[int] = None,
        background: bool = True
    ) -> Dict[str, Any]:
        """Sync products from source"""
        payload = {
            "product_source_id": product_source_id,
            "source_type": source_type,
            "background": background
        }
        if limit:
            payload["limit"] = limit

        response = requests.post(
            f"{self.base_url}/products/sync",
            headers=self._get_headers(),
            json=payload
        )
        response.raise_for_status()
        return response.json()


# Usage Example
if __name__ == "__main__":
    # Initialize client
    client = RAGClient()

    # Login
    client.login("[email protected]", "password")

    # Upload a document
    doc = client.upload_document("/path/to/document.pdf")
    print(f"Uploaded: {doc['filename']}")

    # Wait for processing
    import time
    time.sleep(5)

    # Chat with the document
    response = client.chat(
        "What are the main points in the document?",
        mode="documents"
    )
    print(f"AI: {response['response']}")
    print(f"Sources: {len(response['sources'])} documents used")

    # List all documents
    docs = client.list_documents()
    print(f"Total documents: {docs['total']}")

    # List products
    products = client.list_products(limit=10, search="widget")
    print(f"Found {products['total']} products")

Need Help?

If you have questions or run into issues, check our guides or contact support.