Skip to main content

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

HeaderDescriptionExample
Content-TypeAlways application/jsonapplication/json
X-API-KEYProject API key from consolesk_live_abc123...
AuthorizationJWT token from authenticationBearer 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 TypeStructureExample Use Case
ObjectSingle JSON objectDocument retrieval, user profile
ArrayArray of objectsSearch results, list queries
PrimitiveString, number, booleanSimple operations, counts
NestedComplex object with sub-propertiesAuthentication 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 CodeMeaningDescription
200OKRequest successful
400Bad RequestInvalid request format or parameters
401UnauthorizedMissing or invalid authentication
403ForbiddenInsufficient permissions
404Not FoundResource doesn't exist
429Too Many RequestsRate limit exceeded
500Internal Server ErrorServer-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.