API Reference
Complete API reference for Business-as-Code on apis.do
Business-as-Code API Reference
Complete API reference for building autonomous businesses with the Business-as-Code API on apis.do.
Overview
The Business-as-Code API provides a comprehensive REST API for managing business entities, workflows, agents, and operations through semantic patterns. The API enables you to:
- Execute business functions with type-safe inputs and outputs
- Orchestrate workflows with event-driven triggers
- Deploy autonomous agents for automated decision-making
- Manage resources (nouns/entities) with full CRUD operations
- Execute actions (verbs) with Subject-Verb-Object patterns
- Publish and consume events for event-driven architectures
- Search semantically with text and vector search
- Track metrics (KPIs, OKRs) for business intelligence
Base URL
All API endpoints are relative to this base URL.
Authentication
API Keys
Authentication is performed using API keys passed in the Authorization header:
Authorization: Bearer your-api-key-hereGetting an API Key
- Sign up at platform.do
- Navigate to Settings > API Keys
- Click Create API Key
- Copy your API key (it will only be shown once)
Using API Keys
import { createBusinessApi } from 'business-as-code'
const api = createBusinessApi({
apiKey: process.env.APIS_DO_KEY,
})Security Best Practices:
- Store API keys in environment variables, never in code
- Use different keys for development, staging, and production
- Rotate keys regularly
- Revoke compromised keys immediately
- Use the minimum required permissions
Quick Start
Installation
npm install business-as-codepnpm add business-as-codeyarn add business-as-codeBasic Usage
import { createBusinessApi } from 'business-as-code'
// Initialize the API client
const api = createBusinessApi({
apiKey: process.env.APIS_DO_KEY
})
// Execute a business function
const result = await api.functions.execute('calculate-revenue', {
transactions: [...],
period: 'Q4-2024'
})
console.log('Revenue:', result.total)Full Example: Order Processing
import { createBusinessApi } from 'business-as-code'
const api = createBusinessApi({
apiKey: process.env.APIS_DO_KEY,
})
// Create a customer resource
const customer = await api.resources.create({
$type: 'Customer',
$id: 'cust-123',
name: 'Jane Smith',
email: '[email protected]',
phone: '+1-555-0100',
})
// Create an order
const order = await api.resources.create({
$type: 'Order',
$id: 'order-456',
customer: customer.$id,
items: [{ product: 'prod-789', quantity: 2, price: 29.99 }],
total: 59.98,
status: 'pending',
})
// Trigger order processing workflow
const execution = await api.workflows.trigger('process-order', {
orderId: order.$id,
})
// Check workflow status
const status = await api.workflows.status(execution.executionId)
console.log('Workflow status:', status.status)
// Publish order created event
await api.events.publish({
type: 'order.created',
timestamp: new Date().toISOString(),
source: 'order-service',
data: { order },
})
// Track revenue metric
await api.metrics.record({
name: 'Revenue',
type: 'counter',
value: order.total,
unit: 'USD',
timestamp: new Date().toISOString(),
})Error Handling
Error Types
The API uses two error types:
ApiError - HTTP errors from the API:
class ApiError extends Error {
statusCode: number
body: any
message: string
}ValidationError - Client-side validation errors:
class ValidationError extends Error {
field: string
message: string
}Handling Errors
import { ApiError, ValidationError } from 'business-as-code'
try {
const result = await api.functions.execute('my-function', input)
} catch (error) {
if (error instanceof ValidationError) {
console.error(`Validation error in ${error.field}: ${error.message}`)
// Handle validation error (e.g., show user feedback)
} else if (error instanceof ApiError) {
console.error(`API error [${error.statusCode}]: ${error.message}`)
console.error('Response body:', error.body)
// Handle specific status codes
if (error.statusCode === 401) {
// Unauthorized - check API key
} else if (error.statusCode === 404) {
// Not found
} else if (error.statusCode === 429) {
// Rate limited - implement backoff
} else if (error.statusCode >= 500) {
// Server error - retry with exponential backoff
}
} else {
// Unknown error
console.error('Unexpected error:', error)
}
}Common Error Codes
| Status Code | Meaning | Solution |
|---|---|---|
| 400 | Bad Request | Check request parameters and body |
| 401 | Unauthorized | Verify API key is valid |
| 403 | Forbidden | Check API key permissions |
| 404 | Not Found | Verify resource ID exists |
| 422 | Unprocessable Entity | Fix validation errors in request |
| 429 | Too Many Requests | Implement rate limiting/backoff |
| 500 | Internal Server Error | Contact support if persists |
| 503 | Service Unavailable | Retry with exponential backoff |
Retry Strategy
Implement exponential backoff for transient errors:
async function executeWithRetry<T>(fn: () => Promise<T>, maxRetries = 3, initialDelay = 1000): Promise<T> {
let lastError: Error
for (let i = 0; i < maxRetries; i++) {
try {
return await fn()
} catch (error) {
lastError = error
// Don't retry client errors (4xx)
if (error instanceof ApiError && error.statusCode < 500) {
throw error
}
// Calculate delay with exponential backoff
const delay = initialDelay * Math.pow(2, i)
await new Promise((resolve) => setTimeout(resolve, delay))
}
}
throw lastError
}
// Use it
const result = await executeWithRetry(() => api.functions.execute('my-function', input))Rate Limits
Default Limits
| Plan | Requests/minute | Requests/hour | Requests/day |
|---|---|---|---|
| Free | 60 | 1,000 | 10,000 |
| Pro | 600 | 10,000 | 100,000 |
| Business | 6,000 | 100,000 | 1,000,000 |
| Enterprise | Custom | Custom | Custom |
Rate Limit Headers
The API returns rate limit information in response headers:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1640000000X-RateLimit-Limit- Maximum requests allowed in the current windowX-RateLimit-Remaining- Remaining requests in the current windowX-RateLimit-Reset- Unix timestamp when the limit resets
Handling Rate Limits
async function callApiWithRateLimit<T>(fn: () => Promise<T>): Promise<T> {
try {
return await fn()
} catch (error) {
if (error instanceof ApiError && error.statusCode === 429) {
// Get reset time from error body or default to 60 seconds
const resetTime = error.body?.resetTime || Date.now() + 60000
const delay = resetTime - Date.now()
console.log(`Rate limited. Waiting ${delay}ms...`)
await new Promise((resolve) => setTimeout(resolve, delay))
// Retry after waiting
return fn()
}
throw error
}
}
// Use it
const result = await callApiWithRateLimit(() => api.functions.execute('my-function', input))Best Practices
1. Use Environment Variables
Never hardcode API keys:
// ❌ Bad
const api = createBusinessApi({
apiKey: 'sk-abc123...',
})
// ✅ Good
const api = createBusinessApi({
apiKey: process.env.APIS_DO_KEY,
})2. Implement Error Handling
Always handle errors gracefully:
// ❌ Bad
const result = await api.functions.execute('my-function', input)
// ✅ Good
try {
const result = await api.functions.execute('my-function', input)
} catch (error) {
if (error instanceof ApiError) {
// Log to monitoring service
logError(error)
// Show user-friendly message
notifyUser('Operation failed. Please try again.')
}
}3. Use TypeScript
Leverage TypeScript for type safety:
interface CalculateRevenueInput {
transactions: Transaction[]
period: string
}
interface CalculateRevenueOutput {
total: number
currency: string
breakdown: Record<string, number>
}
const result = await api.functions.execute<
CalculateRevenueInput,
CalculateRevenueOutput
>('calculate-revenue', {
transactions: [...],
period: 'Q4-2024'
})
// result is fully typed
console.log(result.total) // number
console.log(result.breakdown) // Record<string, number>4. Validate Input
Validate input before making API calls:
import { ValidationError } from 'business-as-code'
function validateOrderInput(input: any): void {
if (!input.customer) {
throw new ValidationError('customer', 'Customer is required')
}
if (!Array.isArray(input.items) || input.items.length === 0) {
throw new ValidationError('items', 'At least one item is required')
}
if (typeof input.total !== 'number' || input.total <= 0) {
throw new ValidationError('total', 'Total must be a positive number')
}
}
try {
validateOrderInput(orderData)
const order = await api.resources.create(orderData)
} catch (error) {
if (error instanceof ValidationError) {
console.error(`Invalid ${error.field}: ${error.message}`)
}
}5. Use Pagination
For list operations, implement pagination:
async function getAllFunctions() {
const allFunctions = []
let page = 1
let hasMore = true
while (hasMore) {
const functions = await api.functions.list()
allFunctions.push(...functions)
// Implement your pagination logic
hasMore = functions.length === 100 // Assuming 100 is page size
page++
}
return allFunctions
}6. Monitor and Log
Implement proper logging and monitoring:
import { createBusinessApi } from 'business-as-code'
const api = createBusinessApi({
apiKey: process.env.APIS_DO_KEY,
})
// Wrap API calls with logging
async function loggedExecute<TInput, TOutput>(functionId: string, input: TInput): Promise<TOutput> {
const startTime = Date.now()
try {
console.log(`Executing function: ${functionId}`)
const result = await api.functions.execute<TInput, TOutput>(functionId, input)
const duration = Date.now() - startTime
console.log(`Function ${functionId} completed in ${duration}ms`)
return result
} catch (error) {
const duration = Date.now() - startTime
console.error(`Function ${functionId} failed after ${duration}ms:`, error)
throw error
}
}7. Cache When Appropriate
Cache responses for frequently accessed data:
class CachedApi {
private cache = new Map<string, { data: any; timestamp: number }>()
private cacheTTL = 5 * 60 * 1000 // 5 minutes
constructor(private api: BusinessApi) {}
async getFunction(id: string) {
const cached = this.cache.get(id)
if (cached && Date.now() - cached.timestamp < this.cacheTTL) {
return cached.data
}
const data = await this.api.functions.get(id)
this.cache.set(id, { data, timestamp: Date.now() })
return data
}
}
const cachedApi = new CachedApi(api)
const fn = await cachedApi.getFunction('my-function')Configuration
API Client Configuration
import { createBusinessApi, ApiConfig } from 'business-as-code'
const config: ApiConfig = {
// Base URL (default: https://apis.do)
baseUrl: 'https://apis.do',
// API key for authentication
apiKey: process.env.APIS_DO_KEY,
// Custom headers
headers: {
'X-Custom-Header': 'value',
'User-Agent': 'my-app/1.0.0',
},
}
const api = createBusinessApi(config)Custom Headers
Add custom headers to all requests:
const api = createBusinessApi({
apiKey: process.env.APIS_DO_KEY,
headers: {
'X-Request-ID': crypto.randomUUID(),
'X-App-Version': '1.0.0',
'X-User-ID': 'user-123',
},
})API Resources
The Business-as-Code API is organized into the following resources:
- Functions - Execute business logic with type-safe inputs/outputs
- Workflows - Orchestrate multi-step business processes
- Agents - Deploy autonomous agents for automated operations
- Resources - Manage business entities (nouns) with CRUD operations
- Actions - Execute business actions (verbs) with semantic patterns
- Events - Publish and consume business events
- Searches - Search semantically with text and vector queries
- Metrics - Track KPIs, OKRs, and business metrics
Next Steps
- Functions API - Learn about executing business functions
- Workflows API - Orchestrate complex business processes
- Agents API - Deploy autonomous agents
- Resources API - Manage business entities
- Quick Start Guide - Build your first Business-as-Code application
- Semantic Patterns - Understand the $.Subject.predicate.Object pattern
Support
- Documentation: docs.do
- Community: community.do
- Discord: discord.gg/dotdo
- GitHub: github.com/dot-do
- Email: [email protected]
SDK Reference
- TypeScript/JavaScript: business-as-code
- Python: Coming soon
- Go: Coming soon
- Rust: Coming soon