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.
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);
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.
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
// 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
// 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 |
|---|---|
| LLM | openai, anthropic, google, custom |
| Embedding | openai, cohere, voyage, custom |
| Rerank | cohere, 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
const collection = await client.collections.create({
name: 'my-docs', // Unique name
dimensions: 1536, // Must match embedding model
metric: 'cosine' // 'cosine' | 'l2' | 'ip'
});
Parameters
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
// 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
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);
Document processing happens in the background. Poll the document status or use webhooks to know when processing completes.
Wait for Processing
// 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
// 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' });
#Search
Semantic search with multiple retrieval modes: vector search, keyword search, and hybrid.
Vector Search
const results = await client.search.query({
collection: 'my-docs',
query: 'authentication best practices',
top_k: 10,
rerank: true,
filter: { category: 'security' }
});
// Results: Array<{ id, content, score, document_id, document_name, metadata }>
Hybrid Search
Combine vector similarity with keyword matching for best results.
const results = await client.search.hybrid({
collection: 'my-docs',
query: 'JWT refresh tokens',
vector_weight: 0.7, // 70% vector similarity
keyword_weight: 0.3, // 30% keyword matching
rerank: true
});
Keyword Search (BM25)
const results = await client.search.keyword({
collection: 'my-docs',
query: 'authentication',
top_k: 10
});
Multi-Collection Search
// Search across ALL collections in the project
const results = await client.search.global('authentication', {
top_k: 20,
rerank: true
});
#RAG Chat
Conversational AI with document context, source attribution, and streaming support.
Basic Chat
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
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
// 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
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()' }
]
});
For string default values, use "'value'" (with inner quotes). SQL functions like now() don't need them.
Supported Column Types
| Type | Description |
|---|---|
uuid | UUID identifier |
text, varchar(n) | Text/string |
integer, bigint | Integer numbers |
real, double | Floating-point numbers |
boolean | True/false |
jsonb | JSON data |
timestamptz | Timestamp with timezone |
date, time | Date and time |
#Row Operations
Full CRUD operations on table rows.
Insert
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
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
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 |
|---|---|---|
eq | Equals | status.eq=active |
neq | Not equals | status.neq=deleted |
gt | Greater than | age.gt=18 |
gte | Greater or equal | age.gte=18 |
lt | Less than | price.lt=100 |
lte | Less or equal | price.lte=100 |
like | Contains (case-insensitive) | name.like=john |
is | Is null/true/false | deleted_at.is=null |
Combining Filters
// Multiple conditions with &
filter: 'age.gte=18&status.eq=active&name.like=john'
#Pagination
Multiple pagination styles supported.
// 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
// 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
// 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
// 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.
// 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.
http://localhost:9002/v1Authentication:
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.
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 |
|---|---|---|
AuthenticationError | 401 | Invalid or expired credentials |
AuthorizationError | 403 | Insufficient permissions |
NotFoundError | 404 | Resource not found |
ValidationError | 400 | Invalid input data |
RateLimitError | 429 | Too many requests |
DatabaseError | 400 | Database constraint violation |
ConfigurationError | 422 | Missing or invalid configuration |
ExternalServiceError | 502 | LLM/embedding provider error |
#TypeScript
The SDK includes full TypeScript definitions. Import types directly:
import type {
Collection,
Document,
SearchResult,
RagChatResponse,
Table,
AppUser,
PaginatedResponse,
QueryOptions,
RagStreamCallbacks
} from 'devabase-sdk';
#Examples
RAG Chatbot
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
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);