SDK Version 0.5.4

Devabase Documentation

The complete backend SDK for building AI-powered applications. Vector storage, document processing, semantic search, RAG chat, and more.

Vector Storage

Store and query millions of embeddings with sub-millisecond latency using pgvector.

Document Processing

Upload PDFs, DOCX, and more. Automatic chunking, embedding, and indexing.

RAG Chat

Production-ready conversational AI with source attribution and streaming.

Auto REST API

Create tables and get instant CRUD endpoints. No backend code required.

Hybrid Search

Combine vector, keyword, and semantic search with reranking for best results.

User Authentication

Built-in auth system with JWT tokens, sessions, and user management.

Real-time Updates

WebSocket support for live data sync and instant notifications.

Direct SQL Access

Execute raw SQL queries when you need full database control.

Multi-Provider

OpenAI, Anthropic, Cohere, Voyage, and custom providers supported.

#Installation

Install the Devabase SDK using your preferred package manager.

npm install devabase-sdk

Requirements: Node.js 18 or higher. TypeScript 4.7+ recommended.

#Quick Start

Get up and running with Devabase in just a few lines of code.

app.ts
import { createClient } from 'devabase-sdk';

// 1. Initialize the client
const client = createClient({
  baseUrl: 'https://your-server.com',
  apiKey: 'dvb_your_api_key'
});

// 2. Set project context (required)
client.useProject('your-project-id');

// 3. Create a collection
await client.collections.create({
  name: 'knowledge-base',
  dimensions: 1536
});

// 4. Upload a document
await client.documents.upload('knowledge-base', {
  file: pdfBuffer,
  filename: 'manual.pdf'
});

// 5. Search your documents
const results = await client.search.query({
  collection: 'knowledge-base',
  query: 'How do I get started?',
  rerank: true
});

// 6. Chat with your documents (RAG)
const response = await client.chat.send({
  collection: 'knowledge-base',
  message: 'Summarize the main features'
});

console.log(response.answer);
console.log(response.sources);
Project Context Required

Always call useProject() before making any API calls. All resources are scoped to a project.

#Authentication

Devabase uses API keys for authentication. Get your API key from the dashboard.

Configuration
const client = createClient({
  baseUrl: 'https://your-server.com',  // Required
  apiKey: 'dvb_your_api_key',         // Required: starts with 'dvb_'
  timeout: 30000,                     // Optional: request timeout in ms
  headers: { 'X-Custom': 'value' }   // Optional: custom headers
});

Request Headers

All requests automatically include these headers:

Header Value
Authorization Bearer dvb_your_api_key
X-Project-ID Your project ID
Content-Type application/json

#Providers

Configure LLM and embedding providers for RAG operations. Providers are stored in project settings.

Configure LLM Provider

TypeScript
// Add an OpenAI LLM provider
await client.providers.llm.upsert({
  id: 'my-openai',
  type: 'openai',         // 'openai' | 'anthropic' | 'google' | 'custom'
  api_key: 'sk-...',
  model: 'gpt-4o-mini'
});

// Add a custom/self-hosted LLM
await client.providers.llm.upsert({
  id: 'local-llm',
  type: 'custom',
  api_key: 'key123',
  base_url: 'http://localhost:8080/v1',
  model: 'llama-3'
});

Configure Embedding Provider

TypeScript
// Add an OpenAI embedding provider
await client.providers.embedding.upsert({
  id: 'my-embeddings',
  type: 'openai',         // 'openai' | 'cohere' | 'voyage' | 'custom'
  api_key: 'sk-...',
  model: 'text-embedding-3-small',
  dimensions: 1536
});

// List all providers
const llmProviders = await client.providers.llm.list();
const embeddingProviders = await client.providers.embedding.list();

// Test a provider connection
const result = await client.providers.llm.test({
  type: 'openai',
  api_key: 'sk-...',
  model: 'gpt-4o-mini'
});
console.log(result.success, result.message);

Provider Types

Category Supported Types
LLMopenai, anthropic, google, custom
Embeddingopenai, cohere, voyage, custom
Rerankcohere, jina, custom

#Collections

Collections are containers for your documents and their vector embeddings. Each collection has a fixed dimension that must match your embedding model.

Create Collection

TypeScript
const collection = await client.collections.create({
  name: 'my-docs',        // Unique name
  dimensions: 1536,      // Must match embedding model
  metric: 'cosine'        // 'cosine' | 'l2' | 'ip'
});

Parameters

name string required
Unique identifier for the collection. Use lowercase letters, numbers, and hyphens.
dimensions number optional
Vector dimensions. Must match your embedding model (1536 for OpenAI, 384 for MiniLM). Defaults to 1536.
metric 'cosine' | 'l2' | 'ip' optional
Distance metric for similarity search. Defaults to cosine.

Embedding Dimensions Reference

Provider Model Dimensions
OpenAI text-embedding-3-small 1536
OpenAI text-embedding-3-large 3072
Cohere embed-english-v3.0 1024
Local all-MiniLM-L6-v2 384

Other Operations

TypeScript
// List all collections
const { data, pagination } = await client.collections.list({ limit: 50 });

// Get a single collection
const collection = await client.collections.get('my-docs');

// Get collection statistics
const stats = await client.collections.stats('my-docs');
// { name, document_count, chunk_count, total_size_bytes }

// Delete collection (and all documents)
await client.collections.delete('my-docs');

// Update collection RAG config
await client.collections.updateRagConfig('my-docs', {
  llm_provider_id: 'my-llm',
  model: 'gpt-4o-mini',
  system_prompt: 'You are a helpful assistant.'
});

#Documents

Upload and manage documents for RAG. Supported formats: PDF, DOCX, TXT, Markdown.

Upload Document

TypeScript
import { readFileSync } from 'fs';

const doc = await client.documents.upload('my-docs', {
  file: readFileSync('document.pdf'),  // Buffer, Blob, or ReadableStream
  filename: 'document.pdf',           // Original filename
  metadata: { author: 'John' }        // Optional metadata
});

// Document status: 'pending' | 'processing' | 'processed' | 'failed'
console.log(doc.status);
Async Processing

Document processing happens in the background. Poll the document status or use webhooks to know when processing completes.

Wait for Processing

TypeScript
// Poll until processed
let doc = await client.documents.upload('my-docs', { file, filename });

while (doc.status === 'pending' || doc.status === 'processing') {
  await new Promise(r => setTimeout(r, 2000));
  doc = await client.documents.get(doc.id);
}

if (doc.status === 'failed') {
  throw new Error(doc.error_message);
}

console.log('Processed!', doc.chunk_count, 'chunks');

Other Operations

TypeScript
// Upload multiple documents
const docs = await client.documents.uploadMany('my-docs', [
  { file: buffer1, filename: 'doc1.pdf' },
  { file: buffer2, filename: 'doc2.pdf' }
]);

// List documents
const { data } = await client.documents.list('my-docs', {
  status: 'processed',
  limit: 50
});

// Get document chunks
const chunks = await client.documents.chunks('document-id');

// Reprocess document (re-chunk and re-embed)
await client.documents.reprocess('document-id');

// Delete document
await client.documents.delete('document-id');

// List all documents across collections
const allDocs = await client.documents.listAll({ status: 'processed' });

#RAG Chat

Conversational AI with document context, source attribution, and streaming support.

Basic Chat

TypeScript
const response = await client.chat.send({
  collection: 'my-docs',              // string or string[]
  message: 'How do I implement OAuth?',
  include_sources: true,
  top_k: 5
});

console.log(response.answer);
console.log(response.sources);
console.log(response.tokens_used);

Streaming Response

TypeScript
await client.chat.stream({
  collection: 'my-docs',
  message: 'Explain the architecture in detail'
}, {
  onSources: (sources) => {
    console.log('Found', sources.length, 'sources');
  },
  onThinking: (text) => {
    console.log('Thinking:', text);
  },
  onContent: (chunk) => {
    process.stdout.write(chunk);
  },
  onDone: (conversationId, tokensUsed) => {
    console.log('\nDone!', tokensUsed, 'tokens');
  },
  onError: (error) => {
    console.error('Error:', error);
  }
});

Multi-Turn Conversation

TypeScript
// Start a conversation
const response1 = await client.chat.send({
  collection: 'my-docs',
  message: 'What is authentication?'
});

// Continue the conversation
const response2 = await client.chat.continue(
  response1.conversation_id,
  'How do I implement it in Node.js?'
);

// List all conversations
const conversations = await client.chat.listConversations({ limit: 20 });

// Delete a conversation
await client.chat.deleteConversation('conversation-id');

#Tables

Create PostgreSQL tables with auto-generated REST API endpoints.

Create Table

TypeScript
await client.tables.create({
  name: 'users',
  columns: [
    { name: 'id', type: 'uuid', primary: true, default: 'gen_random_uuid()' },
    { name: 'email', type: 'varchar(255)', nullable: false, unique: true },
    { name: 'name', type: 'varchar(255)' },
    { name: 'role', type: 'varchar(50)', default: "'user'" },  // Note: inner quotes!
    { name: 'metadata', type: 'jsonb' },
    { name: 'created_at', type: 'timestamptz', default: 'now()' }
  ]
});
String Defaults Need Inner Quotes

For string default values, use "'value'" (with inner quotes). SQL functions like now() don't need them.

Supported Column Types

Type Description
uuidUUID identifier
text, varchar(n)Text/string
integer, bigintInteger numbers
real, doubleFloating-point numbers
booleanTrue/false
jsonbJSON data
timestamptzTimestamp with timezone
date, timeDate and time

#Row Operations

Full CRUD operations on table rows.

Insert

TypeScript
const rows = client.tables.rows('users');

// Insert single row
const user = await rows.insert({
  email: 'user@example.com',
  name: 'John Doe',
  metadata: { plan: 'pro' }
});

// Insert multiple rows
const users = await rows.insertMany([
  { email: 'a@b.com', name: 'User A' },
  { email: 'c@d.com', name: 'User B' }
]);

Query

TypeScript
const { rows, pagination } = await client.tables.rows('users').query({
  filter: 'role.eq=admin&created_at.gte=2024-01-01',
  order: 'created_at:desc',
  select: 'id,name,email',
  limit: 20
});

Read, Update, Delete

TypeScript
const rows = client.tables.rows('users');

// Get by ID
const user = await rows.get('user-id');

// Find first matching
const admin = await rows.findFirst('email.eq=admin@example.com');

// Update
const updated = await rows.update('user-id', {
  name: 'Jane Doe',
  updated_at: new Date().toISOString()  // Manual timestamp
});

// Delete
await rows.delete('user-id');

// Count
const count = await rows.count('role.eq=admin');

// Check existence
const exists = await rows.exists('user-id');

// Get all (auto-paginated)
const allUsers = await rows.all({ filter: 'role.eq=user' });

#Filtering

Filter rows using a simple query string syntax.

Filter Operators

Operator Description Example
eqEqualsstatus.eq=active
neqNot equalsstatus.neq=deleted
gtGreater thanage.gt=18
gteGreater or equalage.gte=18
ltLess thanprice.lt=100
lteLess or equalprice.lte=100
likeContains (case-insensitive)name.like=john
isIs null/true/falsedeleted_at.is=null

Combining Filters

TypeScript
// Multiple conditions with &
filter: 'age.gte=18&status.eq=active&name.like=john'

#Pagination

Multiple pagination styles supported.

TypeScript
// Offset-based pagination
const page1 = await rows.query({ limit: 20, offset: 0 });
const page2 = await rows.query({ limit: 20, offset: 20 });

// Cursor-based pagination (recommended for large datasets)
const page1 = await rows.query({ limit: 50 });
const page2 = await rows.query({
  cursor: page1.pagination.next_cursor
});

// Pagination metadata
// { total, count, limit, offset, has_next, has_previous, next_cursor, prev_cursor }

#App Authentication

Complete authentication system for your application's end-users.

User Registration & Login

TypeScript
// Register
const auth = await client.appAuth.register({
  email: 'user@example.com',
  password: 'securePassword123',
  name: 'John Doe',
  metadata: { plan: 'free' }
});
// Returns: { user, access_token, refresh_token, expires_in }

// Login
const auth = await client.appAuth.login({
  email: 'user@example.com',
  password: 'securePassword123'
});

// Get current user
const user = await client.appAuth.me();

// Update profile
await client.appAuth.updateProfile({ name: 'Jane Doe' });

// Logout
await client.appAuth.logout();

Password Reset

TypeScript
// Request password reset
await client.appAuth.forgotPassword('user@example.com');

// Reset password with token
await client.appAuth.resetPassword(token, 'newPassword123');

// Change password (when logged in)
await client.appAuth.changePassword({
  current_password: 'oldPassword',
  new_password: 'newPassword123'
});

Token Management

TypeScript
// Refresh token
const newAuth = await client.appAuth.refresh(refreshToken);

// Set token manually
client.appAuth.setToken(accessToken);

#User Management (Admin)

Admin operations for managing your application's users.

TypeScript
// List users
const { data } = await client.appAuth.users.list({ limit: 20 });

// Get user
const user = await client.appAuth.users.get('user-id');

// Update user
await client.appAuth.users.update('user-id', {
  status: 'suspended',
  email_verified: true
});

// Delete user
await client.appAuth.users.delete('user-id');

#REST API Reference

All API endpoints use JSON and require authentication via Bearer token or API key.

Base URL: http://localhost:9002/v1
Authentication: Authorization: Bearer <token> or X-API-Key: <key>

Authentication

Method Endpoint Description
POST /auth/register Register new user
POST /auth/login Login user
GET /auth/me Get current user

Projects

Method Endpoint Description
GET /projects List all projects
POST /projects Create project
GET /projects/:id Get project
PATCH /projects/:id Update project
DELETE /projects/:id Delete project

Collections

Method Endpoint Description
GET /collections List collections
POST /collections Create collection
GET /collections/:name Get collection
DELETE /collections/:name Delete collection
GET /collections/:name/stats Get collection stats

Documents

Method Endpoint Description
POST /collections/:name/documents Upload document (multipart)
GET /collections/:name/documents List documents
GET /documents/:id Get document
DELETE /documents/:id Delete document

Search

Method Endpoint Description
POST /search Vector search
POST /search/hybrid Hybrid search (vector + keyword)
POST /search/keyword Keyword search

RAG Chat

Method Endpoint Description
POST /rag Send RAG chat message
GET /rag/conversations List conversations
GET /rag/conversations/:id Get conversation
DELETE /rag/conversations/:id Delete conversation

Tables

Method Endpoint Description
GET /tables List tables
POST /tables Create table
GET /tables/:name Get table schema
DELETE /tables/:name Delete table
POST /tables/:name/rows Insert row
GET /tables/:name/rows Query rows
GET /tables/:name/rows/:id Get row
PATCH /tables/:name/rows/:id Update row
DELETE /tables/:name/rows/:id Delete row

Prompts

Method Endpoint Description
GET /prompts List prompts
POST /prompts Create prompt
GET /prompts/:name Get prompt
PATCH /prompts/:name Update prompt
DELETE /prompts/:name Delete prompt

SQL

Method Endpoint Description
POST /sql Execute SQL query
GET /sql/schema Get database schema

Real-time

Method Endpoint Description
WS /realtime WebSocket connection for real-time updates

Health

Method Endpoint Description
GET /health Health check (no /v1 prefix)

#Error Handling

The SDK provides typed errors for different failure scenarios.

TypeScript
import {
  DevabaseError,
  AuthenticationError,
  AuthorizationError,
  NotFoundError,
  ValidationError,
  RateLimitError,
  DatabaseError,
  ConfigurationError,
  ExternalServiceError
} from 'devabase-sdk';

try {
  await client.collections.get('non-existent');
} catch (error) {
  if (error instanceof NotFoundError) {
    // Resource not found (404)
  } else if (error instanceof AuthenticationError) {
    // Invalid credentials (401)
  } else if (error instanceof AuthorizationError) {
    // Insufficient permissions (403)
  } else if (error instanceof ValidationError) {
    // Invalid input (400)
    console.log(error.details);
  } else if (error instanceof RateLimitError) {
    // Too many requests (429)
    console.log('Retry after:', error.retryAfter);
  } else if (error instanceof DevabaseError) {
    // Other API error
    console.log(error.code, error.status, error.message);
  }
}

Error Types

Error Class HTTP Status Description
AuthenticationError401Invalid or expired credentials
AuthorizationError403Insufficient permissions
NotFoundError404Resource not found
ValidationError400Invalid input data
RateLimitError429Too many requests
DatabaseError400Database constraint violation
ConfigurationError422Missing or invalid configuration
ExternalServiceError502LLM/embedding provider error

#TypeScript

The SDK includes full TypeScript definitions. Import types directly:

TypeScript
import type {
  Collection,
  Document,
  SearchResult,
  RagChatResponse,
  Table,
  AppUser,
  PaginatedResponse,
  QueryOptions,
  RagStreamCallbacks
} from 'devabase-sdk';

#Examples

RAG Chatbot

chatbot.ts
import { createClient } from 'devabase-sdk';
import { readFileSync } from 'fs';

const client = createClient({
  baseUrl: process.env.DEVABASE_URL!,
  apiKey: process.env.DEVABASE_API_KEY!
});
client.useProject(process.env.PROJECT_ID!);

// Setup: Create collection and upload docs
async function setup() {
  await client.collections.create({
    name: 'support-docs',
    dimensions: 1536
  });

  await client.documents.upload('support-docs', {
    file: readFileSync('./docs/faq.pdf'),
    filename: 'faq.pdf'
  });
}

// Chat function
async function chat(message: string, conversationId?: string) {
  return client.chat.send({
    collection: 'support-docs',
    message,
    conversation_id: conversationId,
    include_sources: true
  });
}

// Usage
const response = await chat('How do I reset my password?');
console.log(response.answer);

REST API Backend

api.ts
import { createClient } from 'devabase-sdk';

const client = createClient({ baseUrl: URL, apiKey: KEY });
client.useProject(PROJECT_ID);

// Create posts table
await client.tables.create({
  name: 'posts',
  columns: [
    { name: 'id', type: 'uuid', primary: true, default: 'gen_random_uuid()' },
    { name: 'title', type: 'text', nullable: false },
    { name: 'content', type: 'text' },
    { name: 'author_id', type: 'uuid' },
    { name: 'published', type: 'boolean', default: 'false' },
    { name: 'created_at', type: 'timestamptz', default: 'now()' }
  ]
});

// CRUD operations
const posts = client.tables.rows('posts');

// Create
const post = await posts.insert({
  title: 'Hello World',
  content: 'My first post'
});

// Read
const { rows } = await posts.query({
  filter: 'published.eq=true',
  order: 'created_at:desc',
  limit: 10
});

// Update
await posts.update(post.id, { published: true });

// Delete
await posts.delete(post.id);

Devabase SDK v0.5.4 · GitHub · npm · MIT License