.do
API Reference

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-here

Getting an API Key

  1. Sign up at platform.do
  2. Navigate to Settings > API Keys
  3. Click Create API Key
  4. 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-code
pnpm add business-as-code
yarn add business-as-code

Basic 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 CodeMeaningSolution
400Bad RequestCheck request parameters and body
401UnauthorizedVerify API key is valid
403ForbiddenCheck API key permissions
404Not FoundVerify resource ID exists
422Unprocessable EntityFix validation errors in request
429Too Many RequestsImplement rate limiting/backoff
500Internal Server ErrorContact support if persists
503Service UnavailableRetry 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

PlanRequests/minuteRequests/hourRequests/day
Free601,00010,000
Pro60010,000100,000
Business6,000100,0001,000,000
EnterpriseCustomCustomCustom

Rate Limit Headers

The API returns rate limit information in response headers:

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1640000000
  • X-RateLimit-Limit - Maximum requests allowed in the current window
  • X-RateLimit-Remaining - Remaining requests in the current window
  • X-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

Support

SDK Reference

  • TypeScript/JavaScript: business-as-code
  • Python: Coming soon
  • Go: Coming soon
  • Rust: Coming soon