Request and Response
Singlebase uses a unified API architecture with consistent request and response patterns across all services. This document explains the standardized communication format used throughout the platform.
Unified API Endpoint
All Singlebase operations use a single API endpoint:
[POST] https://cloud.singlebaseapis.com/api/<$PROJECT-ID>
Unlike traditional REST APIs with multiple endpoints (e.g., /users
, /orders
, /files
), Singlebase routes all operations through one URL. The specific operation is determined by the op
parameter in the request body, called DDO.
Why Single Endpoint?
- Consistency: Same URL for all operations
- Simplicity: No need to memorize multiple endpoints
- Flexibility: Easy to add new operations without URL changes
- Unified Authentication: Same headers for all requests
DDO
DDO (Data Directive Object) is a powerful, intuitive unified language dictionary for modern applications. It combines the familiar concepts of MongoDB with a streamlined syntax that makes complex operations simple and readable across multiple domains.
DDO uses a core data structure - a simple dictionary/JSON that describes what you want to do across your application. Whether you're querying and mutating document-based databases, handling authentication, managing file uploads, performing vector database operations, integrating AI services, or executing other application functions, you express your intentions through these structured objects that form the foundation of all DDO operations.
Request Format
Standard HTTP Request
POST https://cloud.singlebaseapis.com/api/{$PROJECT-ID}
Content-Type: application/json
X-API-KEY: your_project_api_key
Authorization: Bearer your_jwt_token
{
"op": "collection.find",
"collection": "users",
"match": { "status": "active" },
"limit": 50
}
Required Headers
Header | Description | Example |
---|---|---|
Content-Type | Always application/json | application/json |
X-API-KEY | Project API key from console | sk_live_abc123... |
Authorization | JWT token from authentication | Bearer eyJhbGciOiJS... |
DDO Examples by API
Datastore API:
{
"op": "collection.insert",
"collection": "products",
"data": {
"name": "Wireless Headphones",
"price": 199.99,
"category": "electronics"
}
}
Auth API:
{
"op": "auth.signin",
"grant_type": "password",
"email": "user@example.com",
"password": "userPassword"
}
Storage API:
{
"op": "file.info",
"_key": "file_abc123xyz789",
"signed_ttl": 3600
}
VectorStore API:
{
"op": "vdb.search",
"query": "machine learning algorithms",
"collection": "knowledge_base"
}
XAI API:
{
"op": "xai.generate",
"user_input": "Write a product description for wireless headphones",
"options": {
"content_length": 200,
"content_style": "marketing"
}
}
Response Format
Standard Response Structure
All Singlebase APIs return responses in a consistent format:
{
"data": {
// Operation result data
},
"meta": {
// Optional metadata about the operation
}
}
Success Response Examples
Simple Data Response:
{
"data": {
"_key": "550e8400e29b41d4a716446655440000",
"_userkey": "user_abc123",
"_created_at": "2024-01-15T10:30:00.000Z",
"_modified_at": "2024-01-15T10:30:00.000Z",
"name": "John Doe",
"email": "john@example.com"
}
}
Array Data Response:
{
"data": [
{
"_key": "550e8400e29b41d4a716446655440000",
"name": "Product 1",
"price": 29.99
},
{
"_key": "f47ac10b58cc4372a5670e02b2c3d479",
"name": "Product 2",
"price": 39.99
}
],
"meta": {
"pagination": {
"page": 1,
"per_page": 50,
"total_pages": 5,
"size": 250,
"count": 50,
"has_next": true,
"next_page": 2
}
}
}
Authentication Response:
{
"data": {
"id_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh_token": "refresh_abc123xyz789",
"token_type": "bearer",
"token_info": {
"ttl": 3600,
"exp": 1705651200,
"iat": 1705647600
},
"user_profile": {
"_userkey": "user_new123",
"email": "user@example.com",
"display_name": "John Doe"
}
}
}
Response Data Types
Data Type | Structure | Example Use Case |
---|---|---|
Object | Single JSON object | Document retrieval, user profile |
Array | Array of objects | Search results, list queries |
Primitive | String, number, boolean | Simple operations, counts |
Nested | Complex object with sub-properties | Authentication tokens, file info |
Meta Information
The meta
object provides additional context about the operation:
{
"meta": {
"pagination": { /* pagination info */ },
}
}
Error Response Format
Standard Error Structure
{
"error": {
"code": "ERROR_CODE",
"message": "Human-readable error description",
"details": {
// Additional error context
}
}
}
Error Response Examples
Validation Error:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Missing required field: email",
"details": {
"field": "email",
"required": true
}
}
}
Authentication Error:
{
"error": {
"code": "AUTHENTICATION_FAILED",
"message": "Invalid API key or JWT token",
"details": {
"reason": "token_expired"
}
}
}
Rate Limit Error:
{
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Too many requests. Try again in 60 seconds.",
"details": {
"limit": 1000,
"remaining": 0,
"reset_at": 1705651200,
"retry_after": 60
}
}
}
HTTP Status Codes
Status Code | Meaning | Description |
---|---|---|
200 | OK | Request successful |
400 | Bad Request | Invalid request format or parameters |
401 | Unauthorized | Missing or invalid authentication |
403 | Forbidden | Insufficient permissions |
404 | Not Found | Resource doesn't exist |
429 | Too Many Requests | Rate limit exceeded |
500 | Internal Server Error | Server-side error |
DDO Query Operators
Comparison Operators
{
"match": {
"age:$gt": 18, // Greater than
"age:$gte": 21, // Greater than or equal
"price:$lt": 100, // Less than
"score:$lte": 95, // Less than or equal
"status:$ne": "deleted" // Not equal
}
}
Array Operators
{
"match": {
"category:$in": ["electronics", "computers"], // Value in array
"status:$nin": ["deleted", "archived"], // Value not in array
"tags:$all": ["featured", "bestseller"] // All values present
}
}
Text Operators
{
"match": {
"name:$regex": "^John", // Regular expression
"description:$contains": "AI", // Contains text
"email:$exists": true // Field exists
}
}
Complex Queries
{
"match": {
"$or": [
{ "category": "electronics" },
{ "price:$lt": 50 }
],
"$and": [
{ "status": "active" },
{ "inventory:$gt": 0 }
]
}
}
Request Examples
Complete Request Flow
// 1. Prepare the DDO
const ddo = {
op: 'collection.find',
collection: 'products',
match: {
category: 'electronics',
'price:$lte': 500
},
sort: 'price asc',
limit: 25
};
// 2. Make the request
const response = await fetch('https://cloud.singlebaseapis.com/api/$PROJECT-ID', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-KEY': 'your-api-key',
'Authorization': 'Bearer your-jwt-token'
},
body: JSON.stringify(ddo)
});
// 3. Handle the response
if (response.ok) {
const result = await response.json();
console.log('Found products:', result.data.length);
console.log('Pagination:', result.meta.pagination);
} else {
const error = await response.json();
console.error('Error:', error.error.message);
}
Batch Operations
Some operations support multiple items in a single request:
{
"op": "collection.insert",
"collection": "users",
"data": [
{ "name": "John", "email": "john@example.com" },
{ "name": "Jane", "email": "jane@example.com" },
{ "name": "Bob", "email": "bob@example.com" }
]
}
Best Practices
Request Optimization
Use Specific Queries:
// Good: Specific match criteria
{
"op": "collection.find",
"collection": "users",
"match": { "status": "active", "role": "admin" },
"limit": 10
}
// Avoid: Overly broad queries
{
"op": "collection.find",
"collection": "users",
"limit": 1000
}
Include Only Necessary Fields:
{
"op": "collection.find",
"collection": "users",
"match": { "status": "active" },
"filter": { "name": 1, "email": 1, "_key": 1 } // Only return these fields
}
Error Handling
async function safeDDORequest(ddo) {
try {
const response = await fetch('https://cloud.singlebaseapis.com/api/$PROJECT-ID', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-KEY': process.env.SINGLEBASE_API_KEY,
'Authorization': `Bearer ${getJWTToken()}`
},
body: JSON.stringify(ddo)
});
if (!response.ok) {
const error = await response.json();
throw new Error(`${error.error.code}: ${error.error.message}`);
}
return await response.json();
} catch (error) {
console.error('DDO Request failed:', error.message);
throw error;
}
}
Response Processing
function processDDOResponse(response, operation) {
// Check if response has expected structure
if (!response.data) {
throw new Error('Invalid response format');
}
// Handle different response types
switch (operation) {
case 'collection.find':
return {
items: response.data,
pagination: response.meta?.pagination,
total: response.meta?.pagination?.size || response.data.length
};
case 'collection.insert':
return {
created: response.data,
count: Array.isArray(response.data) ? response.data.length : 1
};
default:
return response.data;
}
}
The unified API endpoint and DDO format provide a consistent, powerful way to interact with all Singlebase services while maintaining simplicity and flexibility for complex operations.